SpringBean的生命周期
- 容器启动后,对scope为singleton且非懒加载的Bean进行实例化,按照Bean定义来配置信息,注入所有的属性
- 如果Bean实现了BeanNameAware接口,则回调该接口的setBeanName()方法
- 如果Bean实现了BeanFactoryAware接口,则回调该接口的setBeanFactory()方法
- 如果Bean实现了ApplicationContextAware接口,则回调该接口的setApplicationContext()方法
- 如果有Bean实现了BeanPostProcessor接口,则会回调该接口的postProcessBeforeInitialzation()方法
- 如果Bean实现了InitializingBean接口,则会回调该接口的afterPropertiesSet()方法
- 如果Bean配置了init-method方法,则会执行init-method配置的方法
- 如果Bean实现了BeanPostProcessor接口,则会回调该接口的postProcessAfterInitialization()方法
- 对于scope为singleton的Bean,Spring的IOC容器中会缓存该Bean的实例;对于scope为prototype的Bean,每次调用都会new新的对象,其生命周期就交给调用方管理
- 容器关闭后,如果Bean实现了DisposableBean接口,则会回调该接口的destroy()方法,
- 如果Bean配置了destroy-method方法,则会执行destroy-method配置的方法
常用扩展点
@Component
public class CustomInitialize extends CommonLoggerDefine
implements ApplicationContextAware, InitializingBean, DisposableBean, InstantiationAwareBeanPostProcessor,
BeanNameAware, BeanFactoryAware, BeanFactoryPostProcessor, BeanPostProcessor {
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
logger.info("===Custom ApplicationContext===");
}
@Override
public void afterPropertiesSet() throws Exception {
logger.info("===Custom InitializingBean===");
}
@Override
public void destroy() throws Exception {
logger.info("===Custom DisposableBean===");
}
@Override
public void setBeanFactory(BeanFactory paramBeanFactory) throws BeansException {
logger.info("===Custom BeanFactoryAware===");
}
@Override
public void setBeanName(String paramString) {
logger.info("===Custom BeanNameAware===");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory paramConfigurableListableBeanFactory)
throws BeansException {
BeanDefinition bd = paramConfigurableListableBeanFactory.getBeanDefinition("userBean");
MutablePropertyValues pv = bd.getPropertyValues();
bd.setScope("singleton");
logger.info("===Custom BeanFactoryPostProcessor===" + pv.getPropertyValues());
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
logger.info("===Custom BeanPostProcessor Before===");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
logger.info("===Custom BeanPostProcessor After===");
return bean;
}
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
logger.info("===Custom InstantiationAwareBeanPostProcessor Before===");
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
logger.info("===Custom InstantiationAwareBeanPostProcessor After===");
return true;
}
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
throws BeansException {
logger.info("===Custom InstantiationAwareBeanPostProcessor postProcessProperties===");
return null;
}
@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean,
String beanName) throws BeansException {
logger.info("===Custom InstantiationAwareBeanPostProcessor postProcessPropertyValues===");
return pvs;
}
}
public class UserBean extends CommonLoggerDefine {
@PostConstruct
public void postConstruct() {
logger.info("===Custom PostConstruct===");
}
@PreDestroy
public void preDestroy() {
logger.info("===Custom PreDestroy===");
}
}
public class CustomBean extends CommonLoggerDefine {
public void start() {
logger.info("===Custom CustomBean Starter===");
}
public void destroy() {
logger.info("===Custom CustomBean Destroy===");
}
}
/**
* 通常用来创建复杂的Bean,其默认方法设置是单例,注入需要添加&符号:@Resource(name = "&customFactoryBean")
*
* @author LEric
*/
public class CustomFactoryBean extends CommonLoggerDefine implements FactoryBean<UserBean> {
@Override
public UserBean getObject() throws Exception {
logger.info("===Custom FactoryBean Object===");
return new UserBean();
}
@Override
public Class<?> getObjectType() {
logger.info("===Custom FactoryBean Class===");
return UserBean.class;
}
}
public class CommonLoggerDefine {
public Logger logger = LoggerFactory.getLogger(getClass());
}
启动类
@SpringBootApplication(scanBasePackages = "com.xpt.extension.advance")
public class AdvanceApplication {
public static void main(String[] args) {
SpringApplication.run(AdvanceApplication.class, args);
System.exit(0);
}
@Bean(initMethod = "start", destroyMethod = "destroy")
public CustomBean customBean() {
return new CustomBean();
}
@Bean(name = "customFactoryBean")
public CustomFactoryBean toolFactory() {
return new CustomFactoryBean();
}
@Bean(name = "userBean")
public UserBean userBean() {
return new UserBean();
}
}
备注
自定义Spring-Boot-Starter实现与自定义标签解析的实现
/**
* 用来处理XML中的自定义的标签
*
* @author LEric
*/
public class CustomHandler extends NamespaceHandlerSupport {
@Override
public void init() {
registerBeanDefinitionParser("label", new BeanParser());
}
}
/**
* 通过继承AbstractSingleBeanDefinitionParser或者实现BeanDefinitionParser都可达到目的
*
* @author LEric
*
*/
public class BeanParser implements BeanDefinitionParser {
@Override
public BeanDefinition parse(Element element, ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();
return builder.getBeanDefinition();
}
}
/**
* 自定义Spring-Boot-Starter实现的时候使用,同@Import注解共同使用
*
* @author LEric
*
*/
public class CustomImport implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// 实现逻辑的处理
}
}
总结
Spring常用的技术扩展点都可以在AbstractApplicationContext中的refresh()方法中找到;
BeanDefinition:描述Bean的信息,比如:class信息,属性信息,是否是单例,是否延迟加载等;
常见的接口有:
- FactoryBean,AOP的基础bean
- BeanPostProcessor,每个bean初始化前后的操作
- InstantiationAwareBeanPostProcessor,每个Bean实例化前后的操作
- BeanNameAware,获取当前Bean的Id
- ApplicationContextAware,获取上下文
- BeanFactoryAware,针对Bean工厂的处理
- BeanFactoryPostProcessor,在Bean创建之前来读取Bean的元属性,并对元属性进行修改,例如将Bean的scope属性从singleton改变为prototype
- InitializingBean,在属性设置完毕后的操作
- DisposableBean,关闭容器前的操作
备注
- BeanPostProcessor:每个Bean初始化前后都会回调其中的方法,如:init-method,InitializingBean等
- 不推荐使用InitializingBean,因为它和Spring耦合太紧密,推荐使用@PostConstruct注解
- Spring容器最常用的两个扩展点:BeanFactoryPostProcessor和BeanPostProcessor,其对应方法会被Spring在容器初始化过程中调用,此时所有Bean的定义信息都已经初始化好,但是这些Bean还没有实例化
- postProcessBeforeInitialization:会在每个Bean实例化之后、初始化之前被调用
- postProcessAfterInitialization:会在每个bean初始化之后被调用
-
ApplicationContext利用ApplicationContextAwareProcessor完成ApplicationContext中特有的某些Aware的调用,发生的时机在Bean初始化之前:
(6.1)EnvironmentAware:将上下文中Enviroment注入进去,通常获取配置属性时使用
(6.2)EmbeddedValueResolverAware:将上下文中EmbeddedValueResolver注入进去,用于参数解析
(6.3)ResourceLoaderAware:将上下文设置进去
(6.4)ApplicationEventPublisherAware:实现ApplicationEventPublisher接口,将自己注入进去
(6.5)MessageSourceAware:将自身注入
(6.6)ApplicationContextAware:将自身注入
- BeanClassLoaderAware:会将加载当前Bean的ClassLoader注入进去。