Aware接口和InitializaingBean接口

67 阅读3分钟

Aware接口用于注入一些与容器相关的信息,比如BeanNameAware接口,设置Bean的名字。BeanFactoryAware接口,注入BeanFactory容器。ApplicationContextAware接口,注入ApplicationContext容器。

我们接下来测试BeanNameAware,ApplicationContextAware,InitializaingBean这三个接口。

讲讲我们这里用的并不是BeanFactory的实现类,可以看到我们以往注册bean是非常麻烦的,注册bean之前还要创建BeanDefinition。然后再对其进行注册。我们这里用ApplicationContext,适用registerBean后调用refresh方法,Application就可以自动帮我们把bean注册到容器中,并进行一些初始化,并且已经实例化好了。

结果也看出来,确实也都输出了。该注入的注入成功,该调用的初始化方法也成功调用。

这时有人会问了,这个和注入和@Autowired注解有什么区别吗,都是依赖注入。还有初始化方法和@PostConstruct这个标志的初始化方法有什么区别吗。 首先不可否认,他们的确实都可以完成注入,你可以不用实现这些接口,使用上面说的注解依旧可以进行注入,以及初始化方法的执行。但是这些注解的使用都需要依赖bean后置处理器,这些后置处理器属于扩展方法。要想使用注解,就必须还要为容器添加bean后置处理器并绑定。而我们刚刚实现的一些Aware接口和Initializaing接口就是属于内置功能,不需要增加任何后置处理器,就可以执行的。

我们现在把@Autowired和@PostConstruct注解加上,发现顺序如下。

@Autowired -> Aware接口

@PostConstruct -> Initializing接口

我们可以看到 在注入阶段是@Autowired注解先执行,在初始化阶段也是@PostConstruct注解的先执行。

规律很明显了,当内置的功能和扩展的同时执行时,扩展功能先执行。

还有个注意点就是@Autowired等一些注解可能会失效,上面的情况不会。我们来手动制造一个失效的情况

首先我们会在Config中使用@Bean注解向容器中注入一个自定义的BeanFactroyPostProcessor。此时就会发现我们的@Autowired注解和@PostConstruct注解失效。那问题来了,为什么呢。回答这个问题,我们要稍微对refresh方法有点了解,具体的流程不讲,我们讲大致的流程

首先会找到所有的BeanFactoryPostProcessor后置处理器并开启,然后会找到所有BeanPostProcessor后置处理器也开启。在这两步完成之后,才会进行单例对象的创建。在创建单例对象的时候,由于前面两步已经开启了后置处理器,所以此时在创建对象时,所用的注解就会被后置处理器解析。也就是生效。 以上说的是正常的流程。

但是我们在用@Bean注解向容器中添加BeanFactoryPostProcessor处理器的时候,就会破坏正常顺序,我们知道容器会首先找到所有BeanFactoryPostProcessor,但是找到我们自定义的BeanFactoryPostProcessor,他就要首先把这个对象创建出来,才能调用该方法。所以就先创建了该单例对象。因此在创建单例对象时,并没有后置处理器被开启,所以对象中的注解都将失效。

为什么内置功能不失效,相比也清楚了。内置功能不需要依赖后置处理器,所以不会失效。

本文使用 文章同步助手 同步