Spring中xxAware接口和InitializingBean接口的作用

question:Aware接口和InitializingBean接口的作用都可以用例如@Autowired @PostConstruct注解来实现,那么其相比较于注解的实现,优势是什么呢?

早期的Spring中并不存在注解开发,注解开发是在后期的Spring中引入,并广泛应用的

注解只是一个标记,其不起任何作用,起作用的是对注解解析的类和方法,在Spring中,对各类注解解析的类主要是xxBeanFactoryPostProcessor,xxBeanPostProcessor类
也就是说,如果对注解解析的扩展功能如果失效了,那么注解自然是起不到作用了

首先,从例1,我们可以直观的看到注解生效的原因
从例2,我们可以看到其扩展功能失效的一个场景
参考视频:bilibili

@Component
public class MyBean implements ApplicationContextAware, InitializingBean {
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("当前bean " + this +  "初始化");
    }

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

    @Autowired
    public void addApplicationContext(ApplicationContext applicationContext){
        System.out.println("当前bean " + this + " 使用@Autowired 容器是:" + applicationContext);
    }

    @PostConstruct
    public void init(){
        System.out.println("当前bean " + this + " 使用@PostConstruct 初始化");
    }
}
public class InvalidAutowiredApplication {
    public static void main(String[] args) {
        // GenericApplicationContext 是一个【干净】的容器,其不会自动添加默认的 BeanPostProcessor
        GenericApplicationContext context = new GenericApplicationContext();
        context.registerBean("myBean", MyBean.class);
        // 你依次尝试注册BeanPostProcessor 和不注册,你会得到什么输出
        context.registerBean(AutowiredAnnotationBeanPostProcessor.class);
        context.registerBean(CommonAnnotationBeanPostProcessor.class);
        context.registerBean(ConfigurationClassPostProcessor.class);
        context.refresh();
        context.close();
    }
}

例2:

@Configuration
public class MyConfig {
    @Autowired
    public void setApplicationContext(ApplicationContext applicationContext){
        System.out.println("当前bean " + this + " 使用@Autowired 容器是:" + applicationContext);
    }

    @PostConstruct
    public void init(){
        System.out.println("当前bean " + this + " 使用@PostConstruct");
    }

    @Bean
    public BeanFactoryPostProcessor processor(){
        return beanFactory ->{
            System.out.println("当前bean " + this + " 使用@Bean BeanFactoryPostProcessor");
        };
    }
}
// 你会观察到,其实你注入了相关的BeanPostProcessor,MyConfig中的@Autowired 和 @PostConstruct也不会生效
public class InvalidAutowiredApplication {
    public static void main(String[] args) {
        // GenericApplicationContext 是一个【干净】的容器,其不会自动添加默认的 BeanPostProcessor
        GenericApplicationContext context = new GenericApplicationContext();
        context.registerBean("myConfig", MyConfig.class);
        context.registerBean(AutowiredAnnotationBeanPostProcessor.class);
        context.registerBean(CommonAnnotationBeanPostProcessor.class);
        context.registerBean(ConfigurationClassPostProcessor.class);
        context.refresh();
        context.close();
    }
}

解析:
对于context.refresh(),其主要按以下顺序执行了三件事
-执行BeanFactory后置处理器
-添加Bean后置处理器
-创建和初始化单例
在这里插入图片描述
当 Java 配置类中定义了 BeanFactoryPostProcessor 时,如果要创建配置类中的 BeanFactoryPostProcessor 就必须 提前 创建和初始化 Java 配置类。

在创建和初始化 Java 配置类时,由于 BeanPostProcessor 还未准备好,无法解析配置类中的 @Autowired 等注解,导致 @Autowired 等注解失效:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值