spring有关bean的加载问题
2017-03-17 本文已影响125人
吴世浩
一、好言
掏心掏肺的对一个人好,要么得到一生的知己,要么换来一生的教训。
二、背景
最近离职在交接,所以有时间来在看看spring的一些加载及周期问题,自己写代码测试,看看源码之类的,最近用了ApplicationContextAware,BeanPostProcessor,慢慢熟悉用法,然后在跟源码看了。下面是一些示例。
三、代码示例
3.1 bean加载顺序
- 实例化;
- 设置属性值;
- 如果实现了BeanNameAware接口,调用setBeanName设置Bean的ID或者Name;
- 如果实现BeanFactoryAware接口,调用setBeanFactory 设置BeanFactory;
- 如果实现ApplicationContextAware,调用setApplicationContext设置ApplicationContext
- 调用BeanPostProcessor的预先初始化方法;
- 调用InitializingBean的afterPropertiesSet()方法;
- 调用定制init-method方法;
- 调用BeanPostProcessor的后初始化方法;
摘自网上
3.2 bean的初始化
package com.mouse.moon.spring.bean;
import org.springframework.beans.factory.InitializingBean;
/**
* Created by Mahone Wu on 2017/3/17.
*/
public class Man implements InitializingBean {
private WoMan woMan;
public Man(){
System.out.println("初始化 man");
}
public void setWoMan(WoMan woMan){
System.out.println("setWoMan");
this.woMan = woMan;
}
public void init(){
System.out.println("init");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("afterPropertiesSet");
}
}
package com.mouse.moon.spring.bean;
/**
* Created by Mahone Wu on 2017/3/17.
*/
public class WoMan {
public WoMan(){
System.out.println("init... woman类");
}
/**说点啥了*/
public String say(String str){
return str;
}
}
package com.mouse.moon.spring.bean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
/**
* Created by Mahone Wu on 2017/3/17.
*/
public class Main {
public static void main(String[] args) {
ApplicationContext context = new FileSystemXmlApplicationContext("classpath:/test/spring.xml");
Man man = (Man)context.getBean("man");
}
}
打印日志如下:
初始化 man
.17:42:12.463 DEBUG [main] org.springframework.beans.factory.support.DefaultListableBeanFactory[529] - Eagerly caching bean 'man' to allow for resolving potential circular references
.17:42:12.465 DEBUG [main] org.springframework.beans.factory.support.DefaultListableBeanFactory[221] - Creating shared instance of singleton bean 'woMan'
.17:42:12.465 DEBUG [main] org.springframework.beans.factory.support.DefaultListableBeanFactory[448] - Creating instance of bean 'woMan'
init... woman类
.17:42:12.465 DEBUG [main] org.springframework.beans.factory.support.DefaultListableBeanFactory[529] - Eagerly caching bean 'woMan' to allow for resolving potential circular references
.17:42:12.466 DEBUG [main] org.springframework.beans.factory.support.DefaultListableBeanFactory[484] - Finished creating instance of bean 'woMan'
setWoMan
.17:42:12.521 DEBUG [main] org.springframework.beans.factory.support.DefaultListableBeanFactory[1620] - Invoking afterPropertiesSet() on bean with name 'man'
afterPropertiesSet
.17:42:12.522 DEBUG [main] org.springframework.beans.factory.support.DefaultListableBeanFactory[1678] - Invoking init method 'init' on bean with name 'man'
init
执行的顺序:
构造方法
set方法
afterPropertiesSet
init-method方法配置
如果加上@PostConstruct,则需要在xml里面加上如下配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
<bean id="man" class="com.mouse.moon.spring.bean.Man" init-method="init">
<property name="woMan" ref="woMan"></property>
</bean>
<bean id="woMan" class="com.mouse.moon.spring.bean.WoMan"></bean>
</beans>
<context:annotationconfig />将隐式地向Spring容器注册AutowiredAnnotationBeanPostProcessor、 CommonAnnotationBeanPostProcessor、 PersistenceAnnotationBeanPostProcessor以及 RequiredAnnotationBeanPostProcessor这4个BeanPostProcessor。