06.Aware接口

  1. Aware接口提供了一种内置的注入手段,可以注入向Bean中注入BeanFactory、ApplicationContext等对象
  2. InitializingBean是一个接口,提供了一个Bean初始化之前执行的方法
  3. Aware接口提供的方法属于Spring内置的方法,内置的注入和和初始化方法不受扩展功能(BeanPostProcessr、BeanFactoryPostProcessor)的影响,一定会被执行;因此Spring内部的类经常会用他们
  4. 配置类中@Autowire注入失效分析

一 常见的Aware接口

  1. InitializingBean:Bean的初始化之前执行该接口的afterPropertiesSet()方法
  2. DisposableBean:Bean的销毁时执行该接口的destroy()方法
  3. BeanNameAware:注入Bean的名字
  4. BeanFactoryAware:注入BeanFactory
  5. ApplicationAware:注入Application
  6. EmbeddedValueResolverAware:用于解析EL表达式,具体可参考百度

二 InitializingBean和DisposableBean

这两个接口是相对应的,前者提供了初始化方法,后者提供了销毁方法

三 Autowire注入失效分析

如下例:

@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");
        };
    }
}

可以发现,当这个配置类初始化的时候,并没有注入applicationContext,且初始化方法也没有执行。

解决方法:

  1. 用内置(Aware)依赖注入和初始化取代扩展依赖注入和初始化
  2. 用静态工厂方法(使用static修饰)代替实例工厂方法,避免工厂对象提前被创建

正常情况下,spring的启动流程(即context.refresh())是这样子:

  1. 扫描并执行所有的BeanFactoryPostProcessor
  2. 注册BeanPostProcessor
  3. 创建和初始化所有的Bean
    1. 依赖注入扩展(如@Value和@Autowired)
    2. 初始化扩展(如@PostConstruct)
    3. 执行Aware
  4. 创建成功
ApplicationContext BeanFactoryPostProcessor BeanPostProcessor Java配置类 1. 执行 BeanFactoryPostProcessor 2. 注册 BeanPostProcessor 3. 创建和初始化 3.1 依赖注入扩展(如 @Value 和 @Autowired) 3.2 初始化扩展(如 @PostConstruct) 3.3 执行 Aware 及 InitializingBean 3.4 创建成功 ApplicationContext BeanFactoryPostProcessor BeanPostProcessor Java配置类

但是,当配置类中有一个Bean是BeanFactoryPostProcessor类型的时候,spring需要先创建这个工厂后处理器,那么将会直接初始化该配置类,将工厂后处理器创建出来;而创建的时候,Bean后处理器还没有注册,因此Autowired和PostConstruct不会生效

配置类中有工厂后处理器时的流程

  1. 创建和初始化该配置类
    1. 执行Aware
    2. 创建成功
  2. 执行工厂后处理器
  3. 注册Bean后处理器
ApplicationContext BeanFactoryPostProcessor BeanPostProcessor Java配置类 3. 创建和初始化 3.1 执行 Aware 及 InitializingBean 3.2 创建成功 1. 执行 BeanFactoryPostProcessor 2. 注册 BeanPostProcessor ApplicationContext BeanFactoryPostProcessor BeanPostProcessor Java配置类

以下为相关代码

public class A06 {
    private static final Logger log = LoggerFactory.getLogger(A06.class);

    public static void main(String[] args) {
        GenericApplicationContext context = new GenericApplicationContext();
//        context.registerBean("myBean", MyBean.class);
        context.registerBean("myConfig1", MyConfig1.class);
//        context.registerBean("myConfig2", MyConfig2.class);
        context.registerBean(AutowiredAnnotationBeanPostProcessor.class);
        context.registerBean(CommonAnnotationBeanPostProcessor.class);
        context.registerBean(ConfigurationClassPostProcessor.class);

        context.refresh(); // 1. beanFactory 后处理器,  2. 添加 bean 后处理器, 3. 初始化单例
        context.close();
    }
}
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 + " 初始化");
    }

    @Autowired
    public void aaa(ApplicationContext applicationContext) {
        log.debug("当前bean " + this + " 使用@Autowired 容器是:" + applicationContext);
    }

    @PostConstruct
    public void init() {
        log.debug("当前bean " + this + " 使用@PostConstruct 初始化");
    }

}
@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");
        };
    }
}
@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 static BeanFactoryPostProcessor processor2() {
        return beanFactory -> {
            log.debug("执行 processor2");
        };
    }
}

你可能感兴趣的:(spring,java,spring,spring,boot)