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");
        };
    }
}
相关推荐
掘金者阿豪8 分钟前
Seedance 2.0/2.5 虚拟素材能跨 Key 共用吗?一次讲清 Asset ID、账号隔离与 SaaS 素材架构
前端·后端
程序员黎剑17 分钟前
Spring-Bean生命周期-构造器访问Autowired字段为null
java·后端·spring
泡海椒35 分钟前
JQuick-Curl 拦截器实战:统一 Token、日志、请求预处理,让第三方接口调用真正工程化
后端
古法安卓37 分钟前
Android-重启流程源码解析
android·java·android studio
东方小月38 分钟前
一篇文章带你深入拆解Skill的本质与工程实现,让你不再滥用Skill
前端·人工智能·后端
清水白石0081 小时前
Python 类型设计深度解析:TypedDict 能否替代 dataclass?从 JSON 数据边界到 API 设计的最佳实践
java·python·json
晊晌_h1 小时前
嵌入式从0到精通——线程
java·开发语言·jvm
一木 之林1 小时前
五、C++ 新特性、关键字与编译原理(进阶)(二)
java·开发语言·c++
前端小张同学1 小时前
AI全栈开发最佳实践💐
前端·后端·架构