一、概要
org.springframework.beans.factory.BeanFactory
Bean factory implementations should support the standard bean lifecycle interfacesas far as possible. The full set of initialization methods and their standard order is: 1. BeanNameAware's setBeanName 2. BeanClassLoaderAware's setBeanClassLoader 3. BeanFactoryAware's setBeanFactory 4. ResourceLoaderAware's setResourceLoader(only applicable when running in an application context) 5. ApplicationEventPublisherAware's setApplicationEventPublisher(only applicable when running in an application context) 6. MessageSourceAware's setMessageSource(only applicable when running in an application context) 7. ApplicationContextAware's setApplicationContext(only applicable when running in an application context) 8. ServletContextAware's setServletContext(only applicable when running in a web application context) 9. postProcessBeforeInitialization methods of BeanPostProcessors 10. InitializingBean's afterPropertiesSet 11. a custom init-method definition 12. postProcessAfterInitialization methods of BeanPostProcessors On shutdown of a bean factory, the following lifecycle methods apply: 1. DisposableBean's destroy 2. a custom destroy-method definition
二、实测结果
1. 提前抛出结果
BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry#1 BeanFactoryPostProcessor#postProcessBeanFactory#2 InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation#3 InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation#4 InstantiationAwareBeanPostProcessor#postProcessPropertyValues#5 Foo#setName#6 BeanNameAware#setBeanName#7 BeanClassLoaderAware#setBeanClassLoader#8 BeanFactoryAware#setBeanFactory#9 ResourceLoaderAware#setResourceLoader#10 ApplicationEventPublisherAware#setApplicationEventPublisher#11 MessageSourceAware#setMessageSource#12 ApplicationContextAware#setApplicationContext#13 BeanPostProcessor#postProcessBeforeInitialization#14 InitializingBean#afterPropertiesSet#15 Foo#customInit#16 BeanPostProcessor#postProcessBeforeInitialization#17 Foo#getName#19 FooTest#test#18It is a foo ! DisposableBean#destroy#20 Foo#customDestroy#21
2. 顺序由谁决定的
org.springframework.context.support.AbstractApplicationContext#refresh()
三、具体示例
pom.xml
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>4.1.9.RELEASE</version> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>4.1.9.RELEASE</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.3</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> </plugins> </build>
bean configuration:
<bean class="cn.zno.bean.OneBeanDefinitionRegistryPostProcessor"></bean> <bean class="cn.zno.bean.OneInstantiationAwareBeanPostProcessor"></bean> <bean id="foo" class="cn.zno.bean.Foo" init-method="customInit" destroy-method="customDestroy"> <property name="name" value="It is a foo !"></property> </bean>
java bean:
package cn.zno.bean; import java.util.concurrent.atomic.AtomicInteger; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.context.MessageSource; import org.springframework.context.MessageSourceAware; import org.springframework.context.ResourceLoaderAware; import org.springframework.core.io.ResourceLoader; public class Foo implements BeanNameAware, // 获取<bean id=.. /> 其中id对应的值,如果不存在id,取name属性值,均不存在 cn.zno.bean.Foo#0 BeanClassLoaderAware, // 获取该bean 的 ClassLoader BeanFactoryAware, // 获取 BeanFactory ResourceLoaderAware, // 获取 ResourceLoader ApplicationEventPublisherAware, // 获取 ApplicationEventPublisher MessageSourceAware, // 获取 MessageSource ApplicationContextAware, // 获取 ApplicationContext InitializingBean, // setter 执行完毕后执行 DisposableBean // 工厂销毁时执行 { public static AtomicInteger loadOrder = new AtomicInteger(); private String name; public String getName() { System.out.println("Foo#getName#" + Foo.loadOrder.incrementAndGet()); return name; } public void setName(String name) { System.out.println("Foo#setName#" + Foo.loadOrder.incrementAndGet()); this.name = name; } public void customInit() { System.out.println("Foo#customInit#" + Foo.loadOrder.incrementAndGet()); } public void customDestroy() { System.out.println("Foo#customDestroy#" + Foo.loadOrder.incrementAndGet()); } @Override public void setBeanName(String name) { System.out.println("BeanNameAware#setBeanName#" + Foo.loadOrder.incrementAndGet()); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { System.out.println("ApplicationContextAware#setApplicationContext#" + Foo.loadOrder.incrementAndGet()); } @Override public void setMessageSource(MessageSource messageSource) { System.out.println("MessageSourceAware#setMessageSource#" + Foo.loadOrder.incrementAndGet()); } @Override public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { System.out.println("ApplicationEventPublisherAware#setApplicationEventPublisher#" + Foo.loadOrder.incrementAndGet()); } @Override public void setResourceLoader(ResourceLoader resourceLoader) { System.out.println("ResourceLoaderAware#setResourceLoader#" + Foo.loadOrder.incrementAndGet()); } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("BeanFactoryAware#setBeanFactory#" + Foo.loadOrder.incrementAndGet()); } @Override public void setBeanClassLoader(ClassLoader classLoader) { System.out.println("BeanClassLoaderAware#setBeanClassLoader#" + Foo.loadOrder.incrementAndGet()); } @Override public void afterPropertiesSet() throws Exception { System.out.println("InitializingBean#afterPropertiesSet#" + Foo.loadOrder.incrementAndGet()); } @Override public void destroy() throws Exception { System.out.println("DisposableBean#destroy#" + Foo.loadOrder.incrementAndGet()); } }
package cn.zno.bean; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; public class OneBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { System.out.println("BeanFactoryPostProcessor#postProcessBeanFactory#" + Foo.loadOrder.incrementAndGet()); } @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { System.out.println("BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry#" + Foo.loadOrder.incrementAndGet()); } }
package cn.zno.bean; import java.beans.PropertyDescriptor; import org.springframework.beans.BeansException; import org.springframework.beans.PropertyValues; import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor; public class OneInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if(beanName.equals("foo")) System.out.println("BeanPostProcessor#postProcessBeforeInitialization#" + Foo.loadOrder.incrementAndGet()); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if(beanName.equals("foo")) System.out.println("BeanPostProcessor#postProcessBeforeInitialization#" + Foo.loadOrder.incrementAndGet()); return bean; } @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { if(beanName.equals("foo")) System.out.println("InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation#" + Foo.loadOrder.incrementAndGet()); return null; } @Override public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { if(beanName.equals("foo")) System.out.println("InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation#" + Foo.loadOrder.incrementAndGet()); return true; } @Override public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { if(beanName.equals("foo")) System.out.println("InstantiationAwareBeanPostProcessor#postProcessPropertyValues#" + Foo.loadOrder.incrementAndGet()); return pvs; } }
package cn.zno.bean; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:spring/root/private-root.xml" }) public class FooTest { @Autowired private Foo foo; @Test public void test() { System.out.println("FooTest#test#" + Foo.loadOrder.incrementAndGet() + foo.getName()); } }
aware
/ə'weə/ having or showing knowledge or understanding or realization or perception
你需要啥,只需要实现对应的接口,你就可以使用了
post
/pəʊst/ any particular collection of letters or packages that is delivered
为什么叫postProcess ,就是参数中的引用对象交给该方法来修改
你想改啥,通过啥做啥,只需要实现对应的接口就可以了
四、实际应用
1. mabatis 自动配置所有 mapper 的 BeanDefinition
public class MapperScannerConfigurer implements BeanDefinitionRegistryPostProcessor, InitializingBean, ApplicationContextAware, BeanNameAware { ...
这个Processor的威力有多大,获取不到env ,需要使用字符串而非引用指定sqlSessionFactory ,描述如下
mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactory");
弃用了一个方法
@Deprecated public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) { this.sqlSessionFactory = sqlSessionFactory; }
Specifies which SqlSessionFactory to use in the case that there is more than one in the spring context. Usually this is only needed when you have more than one datasource. Note bean names are used, not bean references. This is because the scanner loads early during the start process and it is too early to build mybatis object instances.
2.
五、FactoryBean
稍作修改
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean class="cn.zno.bean.OneBeanDefinitionRegistryPostProcessor"></bean> <bean class="cn.zno.bean.OneBeanPostProcessor"></bean> <bean id="foo" class="cn.zno.bean.FooFactoryBean" > <property name="attr1" value="It is a foo !"></property> </bean> </beans>
package cn.zno.bean; import org.springframework.beans.factory.FactoryBean; public class FooFactoryBean implements FactoryBean<Foo>{ private String attr1; public String getAttr1() { return attr1; } public void setAttr1(String attr1) { this.attr1 = attr1; } @Override public Foo getObject() throws Exception { System.out.println("FooFactoryBean#getObject#" + Foo.loadOrder.incrementAndGet()); Foo foo = new Foo(); foo.setName(attr1); return foo; } @Override public Class<?> getObjectType() { System.out.println("FooFactoryBean#getObjectType#" + Foo.loadOrder.incrementAndGet()); return Foo.class; } @Override public boolean isSingleton() { System.out.println("FooFactoryBean#isSingleton#" + Foo.loadOrder.incrementAndGet()); return true; } }
其余文件保持原样,包括测试类
@Autowired private Foo foo; @Test public void test() { System.out.println("FooTest#test#" + Foo.loadOrder.incrementAndGet() + foo.getName()); }
结果:
Foo 实现的接口全部失效!
不过可以让FooFactoryBean 实现其需要的接口
结论:
FactoryBean 是对普通bean的构造函数做了抽象,可以传入特殊参数,比如资源文件等(在工厂中解析加工等复杂操作),最终得到目标对象
补充:
import javax.annotation.PostConstruct; import javax.annotation.PreDestroy;
@PostConstruct public void postConstruct() { System.out.println("Foo#postConstruct#" + Foo.loadOrder.incrementAndGet()); } @PreDestroy public void preDestroy() { System.out.println("Foo#preDestroy#" + Foo.loadOrder.incrementAndGet()); }
BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry#1 BeanFactoryPostProcessor#postProcessBeanFactory#2 InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation#3 InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation#4 InstantiationAwareBeanPostProcessor#postProcessPropertyValues#5 Foo#setName#6 BeanNameAware#setBeanName#7 BeanClassLoaderAware#setBeanClassLoader#8 BeanFactoryAware#setBeanFactory#9 ResourceLoaderAware#setResourceLoader#10 ApplicationEventPublisherAware#setApplicationEventPublisher#11 MessageSourceAware#setMessageSource#12 ApplicationContextAware#setApplicationContext#13 BeanPostProcessor#postProcessBeforeInitialization#14 Foo#postConstruct#15 InitializingBean#afterPropertiesSet#16 Foo#customInit#17 BeanPostProcessor#postProcessBeforeInitialization#18 Foo#getName#20 FooTest#test#19It is a foo ! Foo#preDestroy#21 DisposableBean#destroy#22 Foo#customDestroy#23
标签:life,Spring,springframework,bean,loadOrder,import,org,Foo,public From: https://www.cnblogs.com/zno2/p/10341983.html