Spring进阶(Aware接口)

Aware接口提供了一种内置的注入手段

java 复制代码
public class MyBean implements BeanNameAware, ApplicationContextAware, InitializingBean {

    private static final Logger log = LoggerFactory.getLogger(MyBean.class);

    @Override
    public void setBeanName(String name) {
        log.debug("当前bean " + this + " 名字叫:" + name);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        log.debug("当前bean " + this + " 容器是:" + applicationContext);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        log.debug("当前bean " + this + " 初始化");
    }

}

上述的类实现了Aware的两个接口,如果直接将该类注册容器中然后,之后创建Bean,会直接调用上述的方法:

java 复制代码
GenericApplicationContext context = new GenericApplicationContext();
context.registerBean("myBean", MyBean.class);
context.refresh(); // 1. beanFactory 后处理器,  2. 添加 bean 后处理器, 3. 初始化单例
context.close();

结果如下:

DEBUG 17:09:55.174 main com.a06.MyBean - 当前bean com.itheima.a06.MyBean@130161f7 名字叫:myBean

DEBUG 17:09:55.200 main com.a06.MyBean - 当前bean com.itheima.a06.MyBean@130161f7 容器是:org.springframework.context.support.GenericApplicationContext@de3a06f, started on Sun May 17 17:09:55 CST 2026

DEBUG 17:09:55.202 main com.a06.MyBean - 当前bean com.itheima.a06.MyBean@130161f7 初始化

当然上述的功能用 @Autowired 就能实现啊, 为啥还要用 Aware 接口呢 简单地说:

a. @Autowired 的解析需要用到 bean 后处理器, 属于扩展功能

b. 而 Aware 接口属于内置功能, 不加任何扩展, Spring 就能识别

InitializingBean接口提供了一种内置的初始化手段

内置的注入和初始化不受扩展功能的影响

@Autowired失效分析

java 复制代码
@Configuration
public class MyConfig1 {

    private static final Logger log = LoggerFactory.getLogger(MyConfig1.class);

    @Autowired
    public void setApplicationContext(ApplicationContext applicationContext) {
        log.debug("注入 ApplicationContext");
    }

    @PostConstruct
    public void init() {
        log.debug("初始化");
    }

    @Bean //  beanFactory 后处理器
    public BeanFactoryPostProcessor processor1() {
        return beanFactory -> {
            log.debug("执行 processor1");
        };
    }

}

上述的类写完之后,注册执行:

java 复制代码
GenericApplicationContext context = new GenericApplicationContext();
context.registerBean("myConfig1", MyConfig1.class);
context.registerBean(AutowiredAnnotationBeanPostProcessor.class);
context.registerBean(CommonAnnotationBeanPostProcessor.class);
context.registerBean(ConfigurationClassPostProcessor.class);
context.refresh(); // 1. beanFactory 后处理器,  2. 添加 bean 后处理器, 3. 初始化单例
context.close();

打印结果如下:

只输出了一个processor1!!!

那么其他的根本就没有生效

原因如下:

正常的执行顺序:

但是此时BeanFactoryPostProcessor写在了myConfig1中,所以要想执行BeanFactoryPostProcessor先得实例化myConfig1对象,因此顺序变为:

解决方法:

利用Aware提供的接口:

java 复制代码
@Configuration
public class MyConfig2 implements InitializingBean, ApplicationContextAware {

    private static final Logger log = LoggerFactory.getLogger(MyConfig2.class);

    @Override
    public void afterPropertiesSet() throws Exception {
        log.debug("初始化");
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        log.debug("注入 ApplicationContext");
    }

    @Bean //  beanFactory 后处理器
    public BeanFactoryPostProcessor processor2() {
        return beanFactory -> {
            log.debug("执行 processor2");
        };
    }
}
相关推荐
java_cj7 小时前
Elasticsearch索引管理完全指南:从基础API到ILM生命周期管理
大数据·后端·elasticsearch·性能优化
无心水7 小时前
【OpenClaw:赚钱】案例19、内容产量5倍、广告收入翻4倍:播客转多平台内容矩阵全自动化实战(OpenAI Whisper + Claude)
java·人工智能·python·ai编程·openclaw·养龙虾·java.time
geovindu7 小时前
go: Broadcast Pattern
开发语言·后端·设计模式·golang·广播模式
云烟成雨TD7 小时前
Spring AI 1.x 系列【42】MCP 服务端 Spring Boot 启动器
java·人工智能·spring
云烟成雨TD7 小时前
Spring AI 1.x 系列【38】模型上下文协议(MCP)
java·人工智能·spring
Alson_Code7 小时前
Spring AI-1.1.0
java·人工智能·后端·spring·ai编程
小小放舟、7 小时前
@JsonCreator 注解详解——从枚举反序列化说起
spring boot·spring·spring cloud·java-ee·maven·intellij-idea·状态模式
ANnianStriver7 小时前
PetLumina 08 — 通知系统与搜索功能修复(广播机制 + 已读状态 + 参数对齐)
java·ai·ai编程·广播机制
ggaofeng7 小时前
试用zeroclaw
java·开发语言
就叫_这个吧7 小时前
servlet整合tomcat项目启动报错解决,org.apache.tomcat.util.descriptor.web.WebXml.setVersion
java·servlet·tomcat·apache