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 分钟前
掘友们,你们现在下班了都玩啥游戏?| 沸点周刊 8.13
前端·人工智能·后端
JAVA面经实录91722 分钟前
集合框架 (六)
java·开发语言
骇客野人26 分钟前
Linux 查看 Java 进程常用命令
java·linux·运维
shengjk128 分钟前
从 StarRocks Stream Load 400 报错,彻底搞懂 HTTP 100-continue
后端
程序员cxuan1 小时前
Anthropic:session 之间可以相互通信了
人工智能·后端·程序员
周GZ1 小时前
简单讲解Java中静态方法与 实例方法
java·开发语言
卷无止境1 小时前
FastAPI 前端托管全攻略:从静态文件到大型全栈项目架构
后端·python
疯狂打码的少年1 小时前
【数据结构】树的基本概念与二叉树定义
java·数据结构·笔记·算法
webmote331 小时前
用 NVIDIA Nemotron 3 Super + .NET 构建有记忆的多轮对话
后端·算法
神奇小汤圆1 小时前
JUC三大常用工具类CountDownLatch、CyclicBarrier、Semaphore
后端