spring原始碼分析:spring生命週期
最近在看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()");
}
// 通過<bean>的init-method屬性指定的初始化方法
@PostConstruct
public void myInit() {
System.out.println("【init-method】呼叫<bean>的init-method屬性指定的初始化方法");
}
// 通過<bean>的destroy-method屬性指定的初始化方法
public void myDestory() {
System.out.println("【destroy-method】呼叫<bean>的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】呼叫<bean>的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的生命週期就非常熟悉了,下一講就講解下,具體是哪裡的程式碼執行了這些操作。