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");
        };
    }
}
相关推荐
子兮曰3 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
小羊没烦恼!3 天前
微服务化的基石——持续集成
java·大数据·word·powerpoint·.net
子兮曰3 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
俊昭喜喜里3 天前
java中的继承和多态的区别
java
小羊没烦恼!3 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
爱勇宝3 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
譕痕3 天前
JSONObject与JSONArray封装数据格式区别
java·json
胡写代码3 天前
别再前后端各写一套表单校验了
java·后端
小鱼能吃糖3 天前
缺陷修复总览 · mall电商项目:5类缺陷,1个病根,4个业务域
java·电商
此时不提桶,更待何时3 天前
01-06-A-JVM排查实战详解
java·jvm