个人总结spring-bean的声明周期维护有三种:
任何一个事物都有自己的生命周期,生命的开始、生命中、生命结束。大家最熟悉的应该是servlet 的生命周期吧。和 servlet 一样 spring bean 也有自己的生命周期。
Spring提供了一组Aware接口是针对某个实现这些接口的Bean定制初始化的过程,为了让Bean可以获取到框架自身的一些对象。 这些接口均继承于org.springframework.beans.factory.Aware
标记接口,并提供一个将由Bean实现的set*方法,Spring通过基于setter的依赖注入方式使相应的对象可以被Bean使用。
ApplicationContextAware | 获得ApplicationContext对象 |
BeanFactoryAware | 获得BeanFactory对象,可以用来检测Bean的作用域 |
BeanNameAware | 获得Bean在配置文件中定义的名字 |
ResourceLoaderAware | 获得ResourceLoader对象,可以获得classpath中某个文件 |
ServletContextAware | 可以获取ServletContext对象,可以读取context中的参数 |
ServletConfigAware | 可以获取ServletConfig对象,可以读取config中的参数 |
public class GiraffeService implements ApplicationContextAware, ApplicationEventPublisherAware, BeanClassLoaderAware, BeanFactoryAware, BeanNameAware, EnvironmentAware, ImportAware, ResourceLoaderAware{
public void setBeanClassLoader(ClassLoader classLoader) {
System.out.println("执行setBeanClassLoader,ClassLoader Name = " + classLoader.getClass().getName());
}
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("执行setBeanFactory,setBeanFactory:: giraffe bean singleton=" + beanFactory.isSingleton("giraffeService"));
}
public void setBeanName(String s) {
System.out.println("执行setBeanName:: Bean Name defined in context="
+ s);
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("执行setApplicationContext:: Bean Definition Names="
+ Arrays.toString(applicationContext.getBeanDefinitionNames()));
}
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
System.out.println("执行setApplicationEventPublisher");
}
public void setEnvironment(Environment environment) {
System.out.println("执行setEnvironment");
}
public void setResourceLoader(ResourceLoader resourceLoader) {
Resource resource = resourceLoader.getResource("classpath:spring-beans.xml");
System.out.println("执行setResourceLoader:: Resource File Name="
+ resource.getFilename());
}
public void setImportMetadata(AnnotationMetadata annotationMetadata) {
System.out.println("执行setImportMetadata");
}
}
除Aware接口之外,Spring同样可以针对容器中的所有Bean或者某些Bean定制初始化过程,只需提供一个实现BeanPostProcessor接口的类即可(下面会重点讲)。
Bean生命周期是这样的:
init-method
属性,执行指定的方法。destroy-method
属性,执行指定的方法spring注释中经常提到“regular bean” 就是一个未实例化的bean,它就是BeanDefinition(bean metadata 信息),一个类被读取之后就是BeanDefinition,在被注册Ioc容器完毕以后,Spring Bean 工厂就可以随时根据需要进行实例化。对于XmlBeanFactory 来说,实例化默认是延迟进行的,也就是说在 getBean 的时候才会;而对于 ApplicationContext来说,实例化会在容器启动后通过 AbstractApplicationContext 中 reflash 方法自动进行。spring默认beanFactory为DefaultListableBeanFactory,可以从中得到证实。
BeanPostProcessor:bean级别的处理,针对某个具体的bean实例化后,初始化方法执行前(init-method或者实现了InitializingBean的afterPropertiesSet方法)。
BeanFactoryPostProcessor:BeanFactory级别的处理,是针对整个工厂中的bean作出修改或者新注册(包括BeanDefinition)。
BeanDefinitionRegistryPostProcessor,BeanFactory级别的处理,感觉比BeanFactoryPostProcessor 的语义环境更加强调BeanDefinition的个性化调整。
执行顺序:
1. 执行BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
2. 执行BeanFactoryPostProcessor的postProcessBeanFactory方法(与1中排序相同)
BeanDefinitionRegistryPostProcessor执行顺序先与BeanFactoryPostProcessor。
@FunctionalInterface
public interface BeanFactoryPostProcessor {
//可以从factory中获取:BeanDefinition getBeanDefinition(String var1)
void postProcessBeanFactory(ConfigurableListableBeanFactory factory) throws BeansException;
}
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry var1) throws BeansException;
}
public interface BeanPostProcessor {
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
参阅资料