Spring注解驱动开发 第十五节 注入自定义组件是加入spring底层核心组件。
现在有一些需求就是如果我们要把我们自定义的组件注入到spring容器,但是在自定义这个组件的时候需要spring的核心组件,我们应该怎样做呢?废话不多说,我们列出相应的代码。
@Component
public class MyApplicationContextAware implements ApplicationContextAware,BeanNameAware,EmbeddedValueResolverAware {
private ApplicationContext applicationContext;
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("传入的ioc:"+applicationContext);
this.applicationContext = applicationContext;
}
public void setBeanName(String name) {
System.out.println("容器的id是:"+name);
}
public void setEmbeddedValueResolver(StringValueResolver resolver) {
System.out.println("字符串占位符控制是:"+resolver);
}
}
上面代码中,MyApplicationContextAware类实现了三个接口,ApplicationContextAware,BeanNameAware,EmbeddedValueResolverAware 并且重写了相应的方法。首先ApplicationContextAware接口表示获取spring的ioc容器,重写的方法是setApplicationContext,当spring容器启动后会加载这个类,然后自动调用setApplicationContext方法,然后把spring容器中的ApplicationContext(也是spring容器中的组件)作为参数传入到方法中。BeanNameAware接口表示获取spring容器中组件id的名称,EmbeddedValueResolverAware 接口表示获取字符串的占位符。原理都和ApplicationContextAware一样。下面我们查看一下打印结果:
四月 25, 2019 11:25:52 上午 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor <init>
信息: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
容器的id是:myApplicationContextAware
字符串占位符控制是:org.springframework.beans.factory.config.EmbeddedValueResolver@1a38c59b
传入的ioc:org.springframework.context.annotation.AnnotationConfigApplicationContext@2f410acf: startup date [Thu Apr 25 11:25:52 GMT+08:00 2019]; root of context hierarchy
myApplicationContextAware
在启动类获取的容器内存地址:org.springframework.context.annotation.AnnotationConfigApplicationContext@2f410acf: startup date [Thu Apr 25 11:25:52 GMT+08:00 2019]; root of context hierarchy
Process finished with exit code 0
可以看出,无论是在ApplicationContextAware还是我们new的applicationContext其实都是一个对象。同时xxxAware会对应xxxAwareProcessor,xxxAware ⇒ xxxAwareProcessor 所以,它的实现原理是后置处理器。
首先在我们获取核心组件时加入一个断点。
方法调用栈中有一个红色箭头指向的方法,我们点进去查看一下。
可以看到,正是我们刚才说的,xxxAware ==> xxxAwareProcessor 实现了bean的后置处理器。
上面的截图是spring写的后置处理器,在bean初始化调用前做的操作。由于System.getSecurityManager()等于null,所以会直接执行invokeAwareInterfaces(bean)方法。
然后就会执行这个方法,它会根据传入的bean也就是自己,进行一系列判断,这里肯定是ApplicationContextAware类,然后调用我们实现的setApplicationContext方法,将spring ioc容器作为参数传递进去。这就是实现ApplicationContextAware获取spring核心组件的原理。