最近在看springboot自动配置,看到了@Conditional,@ConditionalOnMissingBean等等。这些注解,一直研究他们是如何实现springboot的条件注解的。由他们回到了@Configuration,回到了ConfigurationClassPostProcessor。ConfigurationClassPostProcessor实现了BeanFactoryPostProcessor,在spring生命周期当中会存在某个地方执行实现了BeanFactoryPostProcessor的postProcessBeanFactory方法。由于以前看spring源码时做了比较,于是这里再次总结一下加深自己的影响。
我会从spring生命周期分析,然后到spring如何实现注解,例如@Configuration,@Import等等,最后到@Conditional相关的注解如何实现。
先来看看spring核心代码:
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
再来看看代码
App.Java
public class App {
public static void main(String[] args) {
System.out.println("====开始初始化容器===");
ApplicationContext ctx = new AnnotationConfigApplicationContext(JavaConfig.class);
System.out.println("====容器初始化成功!====");
System.out.println("==========获取person==============");
Person person = (Person) ctx.getBean("person");
person.say();
System.out.println(person);
System.out.println("==========获取lazyPerson==============");
LazyPerson lazyPerson = (LazyPerson) ctx.getBean("lazyPerson");
System.out.println("===现在关闭容器===");
((ClassPathXmlApplicationContext)ctx).registerShutdownHook();
}
}
JavaConfig
@Configuration
public class JavaConfig {
@Bean
@Lazy
public LazyPerson lazyPerson(){
return new LazyPerson();
}
@Bean
public MyBeanFactoryPostProcessor myBeanFactoryPostProcessor(){
return new MyBeanFactoryPostProcessor();
}
@Bean
public MyBeanPostProcessor myBeanPostProcessor(){
return new MyBeanPostProcessor();
}
@Bean
public MyInstantiationAwareBeanPostProcessor myInstantiationAwareBeanPostProcessor(){
return new MyInstantiationAwareBeanPostProcessor();
}
@Bean
public Person person(){
return new Person();
}
}
LazyPerson
public class LazyPerson {
@PostConstruct
public void init(){
System.out.println("========LazyPerson init====================");
}
public LazyPerson(){
System.out.println("==============LazyPerson()=========");
}
}
MyBeanFactoryPostProcessor
public class MyBeanFactoryPostProcessor implements BeanDefinitionRegistryPostProcessor {
public MyBeanFactoryPostProcessor() {
super();
System.out.println("MyBeanFactoryPostProcessor=====这是BeanFactoryPostProcessor实现类构造器!!");
}
public void postProcessBeanFactory(ConfigurableListableBeanFactory arg0)
throws BeansException {
System.out
.println("MyBeanFactoryPostProcessor=====BeanFactoryPostProcessor调用postProcessBeanFactory方法");
BeanDefinition bd = arg0.getBeanDefinition("person");
bd.getPropertyValues().addPropertyValue("phone", "110");
}
}
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("==MyBeanFactoryPostProcessor==MyBeanFactoryPostProcessor调用=postProcessBeanDefinitionRegistry");
}
MyBeanPostProcessor
public class MyBeanPostProcessor implements BeanPostProcessor {
public MyBeanPostProcessor() {
super();
System.out.println("MyBeanPostProcessor====这是BeanPostProcessor实现类构造器!!");
// TODO Auto-generated constructor stub
}
public Object postProcessAfterInitialization(Object arg0, String arg1)
throws BeansException {
System.out
.println("MyBeanPostProcessor====BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改!");
return arg0;
}
public Object postProcessBeforeInitialization(Object arg0, String arg1)
throws BeansException {
System.out
.println("MyBeanPostProcessor=====BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改!");
return arg0;
}
}
MyInstantiationAwareBeanPostProcessor
public class MyInstantiationAwareBeanPostProcessor extends
InstantiationAwareBeanPostProcessorAdapter {
public MyInstantiationAwareBeanPostProcessor() {
super();
System.out
.println("MyInstantiationAwareBeanPostProcessor=====这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!!");
}
// 接口方法、实例化Bean之前调用
@Override
public Object postProcessBeforeInstantiation(Class beanClass,
String beanName) throws BeansException {
System.out
.println("MyInstantiationAwareBeanPostProcessor=====InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法");
return null;
}
// 接口方法、实例化Bean之后调用
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
System.out
.println("MyInstantiationAwareBeanPostProcessor=====InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法");
return bean;
}
// 接口方法、设置某个属性时调用
@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs,
PropertyDescriptor[] pds, Object bean, String beanName)
throws BeansException {
System.out
.println("MyInstantiationAwareBeanPostProcessor======InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法");
return pvs;
}
}
Person
public class Person implements BeanFactoryAware, BeanNameAware,ApplicationContextAware,
InitializingBean, DisposableBean {
private String name;
private String address;
private int phone;
private BeanFactory beanFactory;
private String beanName;
public Person() {
System.out.println("【构造器】调用Person的构造器实例化");
}
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("【注入属性】注入属性name");
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
System.out.println("【注入属性】注入属性address");
this.address = address;
}
public int getPhone() {
return phone;
}
public void setPhone(int phone) {
System.out.println("【注入属性】注入属性phone");
this.phone = phone;
}
public void say(){
System.out.println("============say===============");
}
@Override
public String toString() {
return "Person [address=" + address + ", name=" + name + ", phone="
+ phone + "]";
}
// 这是BeanFactoryAware接口方法
public void setBeanFactory(BeanFactory arg0) throws BeansException {
System.out
.println("【BeanFactoryAware接口】调用BeanFactoryAware.setBeanFactory()");
this.beanFactory = arg0;
}
// 这是BeanNameAware接口方法
public void setBeanName(String arg0) {
System.out.println("【BeanNameAware接口】调用BeanNameAware.setBeanName()");
this.beanName = arg0;
}
// 这是InitializingBean接口方法
public void afterPropertiesSet() throws Exception {
System.out
.println("【InitializingBean接口】调用InitializingBean.afterPropertiesSet()");
}
// 这是DiposibleBean接口方法
public void destroy() throws Exception {
System.out.println("【DiposibleBean接口】调用DiposibleBean.destory()");
}
// 通过的init-method属性指定的初始化方法
@PostConstruct
public void myInit() {
System.out.println("【init-method】调用的init-method属性指定的初始化方法" );
}
// 通过的destroy-method属性指定的初始化方法
public void myDestory() {
System.out.println("【destroy-method】调用的destroy-method属性指定的初始化方法" );
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("ApplicationContextAware===================applicationContext======================");
}
}
我们运行App的main方法得到结果
====开始初始化容器===
**********invokeBeanFactoryPostProcessors(beanFactory)**********
MyBeanFactoryPostProcessor=====这是BeanFactoryPostProcessor实现类构造器!!
==MyBeanFactoryPostProcessor==MyBeanFactoryPostProcessor调用=postProcessBeanDefinitionRegistry
MyBeanFactoryPostProcessor=====BeanFactoryPostProcessor调用postProcessBeanFactory方法
**********invokeBeanFactoryPostProcessors(beanFactory)**********
*****registerBeanPostProcessors(beanFactory);*****
MyBeanPostProcessor====这是BeanPostProcessor实现类构造器!!
MyInstantiationAwareBeanPostProcessor=====这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!!
*****registerBeanPostProcessors(beanFactory);*****
***finishBeanFactoryInitialization(beanFactory);***
*******下面的一段是因为存在其他的类存在实例化,依赖注入所有你会看到重复的两份*****
MyInstantiationAwareBeanPostProcessor=====InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法
MyInstantiationAwareBeanPostProcessor======InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法
MyBeanPostProcessor=====BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改!
MyBeanPostProcessor====BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改!
MyInstantiationAwareBeanPostProcessor=====InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法
MyInstantiationAwareBeanPostProcessor=====InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法
MyInstantiationAwareBeanPostProcessor======InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法
MyBeanPostProcessor=====BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改!
MyBeanPostProcessor====BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改!
MyInstantiationAwareBeanPostProcessor=====InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法
*******上面的一段是因为存在其他的类存在实例化,依赖注入所有你会看到重复的两份*****
MyInstantiationAwareBeanPostProcessor=====InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法
【构造器】调用Person的构造器实例化
MyInstantiationAwareBeanPostProcessor======InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法
【注入属性】注入属性phone
【BeanNameAware接口】调用BeanNameAware.setBeanName()
【BeanFactoryAware接口】调用BeanFactoryAware.setBeanFactory()
ApplicationContextAware===================applicationContext======================
MyBeanPostProcessor=====BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改!
【init-method】调用的init-method属性指定的初始化方法
【InitializingBean接口】调用InitializingBean.afterPropertiesSet()
MyBeanPostProcessor====BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改!
MyInstantiationAwareBeanPostProcessor=====InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法
***finishBeanFactoryInitialization(beanFactory);****
====容器初始化成功!====
==========获取person==============
============say===============
Person [address=null, name=null, phone=110]
==========获取lazyPerson==============
MyInstantiationAwareBeanPostProcessor=====InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法
==============LazyPerson()=========
MyInstantiationAwareBeanPostProcessor======InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法
MyBeanPostProcessor=====BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改!
========LazyPerson init====================
MyBeanPostProcessor====BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改!
MyInstantiationAwareBeanPostProcessor=====InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法
===现在关闭容器===
上面****标识的内容是我自己打上去方便你们知道refresh()哪个方法执行了什么。我们看下我上面图片中红字的方法。
invokeBeanFactoryPostProcessors:
初始化BeanFactoryPostProcessor,只要是实现该接口的都会在此处初始化,MyBeanFactoryPostProcessor是实现了该接口的所以会在这里实例化并且会调用它的postProcessBeanFactory方法。
registerBeanPostProcessors(beanFactory):
初始化拦截Bean的BeanPostProcessors。只要是BeanPostProcessors的子类,在初始构造函数时,都会调用子类的前后方法
MyBeanPostProcessor和MyInstantiationAwareBeanPostProcessor都实现了该接口,会在这里执行它的初始化方法。
finishBeanFactoryInitialization(beanFactory):
这里bean 如果不是抽象,不是懒加载,不是原型的就会在此处初始化。
bean在这里执行getBean,此时会发生bean的初始化,和相应的依赖注入。
上面的结果中我注释了,因为Spring容器中不止存在我们上面写的那些bean还存在其他的。
这里注入时:
构造器–>自动注入–>PostConstrut–>InitializingBean–>xml中配置init方法
从上面的结果中,我们可以总结出spring的生命周期。
1.初始化BeanFactoryPostProcessor。
2.执行BeanFactoryPostProcessor的postProcessBeanFactory。
3.初始化BeanPostProcessor。
发生getBean操作实现依赖注入:
4.执行InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
5.执行bean的构造函数
6.执行
postProcessBeforeInstantiation.postProcessPropertyValues
7.为bean注入属性
8.执行bean实现的有关Aware接口
9.执行BeanPostProcessor.postProcessBeforeInitialization
10.接下来根据具体情况:
PostConstrut–>InitializingBean–>xml中配置init方法
11.BeanPostProcessor.postProcessAfterInitialization
12.容器执行
13.DisposableBean.destroy
知道了spring生命周期,我们对Spring容器中bean的操作就很得心应手了。很多其他框架在使用spring时也利用了这些特性。
这里我们就对spring的生命周期就非常熟悉了,下一讲就讲解下,具体是哪里的代码执行了这些操作。