1、Bean实例生命周期
![](https://img.haomeiwen.com/i13194828/7d1d5a6bee8a758b.png)
![](https://img.haomeiwen.com/i13194828/40eddd8b61cede81.png)
![](https://img.haomeiwen.com/i13194828/f5e5857da624559c.png)
Bean实例生命周期的执行过程如下:
1、Spring对bean进行实例化(调用构造函数),默认bean是单例;
2、通过set方法设置对象属性;
3、检查Aware相关接口,并设置相关依赖
-
3.1 如果bean实现了BeanNameAware接口,spring将bean的id传给setBeanName()方法;
-
3.2 如果bean实现了BeanFactoryAware接口,spring将调用setBeanFactory方法,将BeanFactory实例传进来;
-
3.3 如果bean实现了ApplicationContextAware接口,它的setApplicationContext()方法将被调用,将应用上下文的引用传入到bean中;
——我们在项目中通常需要一个Bean上下文工具类SpringUtil.class,用来通过名称获取bean,这时我们就可以通过SpringUtil implements ApplicationContextAware来获取ApplicationContext上下文,然后通过ApplicationContext来获取bean,例子见后面代码
4、BeanPostProcessor前置处理
如果bean实现了BeanPostProcessor接口,它的postProcessBeforeInitialization方法将被调用;
5、如果bean实现了InitializingBean接口,spring将调用它的afterPropertiesSet接口方法;
6、如果bean使用了init-method属性声明了初始化方法,该方法也会被调用;
7、BeanPostProcessor后置处理
如果bean实现了BeanPostProcessor接口,它的postProcessAfterInitialization接口方法将被调用;
BeanPostProcessor 称之为bean的加工器,主要是在bean完成初始化之后,准备执行默认方法的前后对bean进行包装,即允许我们对bean实例进行自定义的修改,比如注入属性和完善配置,例子见后面代码
8、如果该Bean是单例singleton的,则将Bean放到Spring 缓冲池中;如果该Bean是多例prototype,则将准备好的Bean提交给调用者,后续不再管理该Bean的生命周期。
执行到这里时,bean已经准备就绪,可以被应用程序使用了,他们将一直驻留在应用上下文中(spring 缓存池),直到该应用上下文被销毁;
9、销毁
当bean的应用上下文springApplicationContent(spring 缓存池)销毁时,bean销毁,
这时如果有bean实现了DisposableBean接口,spring将调用它的distroy()接口方法。同样的,如果bean使用了destroy-method属性声明了销毁方法,则该方法被调用;
2、spring bean 注册到 IOC容器的过程
![](https://img.haomeiwen.com/i13194828/a298970b89032e30.png)
- 1、读取bean配置信息(通过xml中<bean> ,或者通过注解@Autowrite @Configuration),根据配置信息,在容器内部建立Bean定义注册表
- 2、根据bean注册表实例化bean
- 3、将bean实例放到spring容器中(spring容器中有一个Bean缓存池)
- 4、使用bean
3、SpringUtil工具类
package com.xxx.web.util;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public final class SpringUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;; // Spring应用上下文环境
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
applicationContext = applicationContext;
}
/**
* 获取对象
*
* @param name
* @return Object 一个以所给名字注册的bean的实例
* @throws BeansException
*
*/
@SuppressWarnings("unchecked")
public static <T> T getBean(String name) throws BeansException {
return (T) applicationContext.getBean(name);
}
/**
* 获取类型为requiredType的对象
*
* @param clz
* @return
* @throws BeansException
*
*/
public static <T> T getBean(Class<T> clz) throws BeansException {
@SuppressWarnings("unchecked")
T result = (T) applicationContext.getBean(clz);
return result;
}
/**
* 如果applicationContext包含一个与所给名称匹配的bean定义,则返回true
*
* @param name
* @return boolean
*/
public static boolean containsBean(String name) {
return applicationContext.containsBean(name);
}
/**
* 判断以给定名字注册的bean定义是一个singleton还是一个prototype。 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException)
*
* @param name
* @return boolean
* @throws NoSuchBeanDefinitionException
*
*/
public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
return applicationContext.isSingleton(name);
}
/**
* @param name
* @return Class 注册对象的类型
* @throws NoSuchBeanDefinitionException
*
*/
public static Class<?> getType(String name) throws NoSuchBeanDefinitionException {
return applicationContext.getType(name);
}
/**
* 如果给定的bean名字在bean定义中有别名,则返回这些别名
*
* @param name
* @return
* @throws NoSuchBeanDefinitionException
*
*/
public static String[] getAliases(String name) throws NoSuchBeanDefinitionException {
return applicationContext.getAliases(name);
}
}
4、BeanPostProcessor使用
注入属性,如果bean属于ServiceBean,则把其属性dynamic设置为true
package com.xxx.processor;
import org.apache.dubbo.config.spring.ServiceBean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
/**
* Description:修复dubbo2.7.1 zk 注册服务为 持久化节点问题
* Date:2019/5/7
*/
@Component
public class ServiceBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if(ServiceBean.class.isInstance(bean)){
((ServiceBean)bean).setDynamic(Boolean.TRUE);
}
return bean;
}
}
网友评论