赞
踩
网上大部分把Bean
的生命周期概括为 4 个阶段
Instantiation
):第 1 步,实例化一个 bean
对象Populate
):第 2 步,为 bean
设置相关属性和依赖;Initialization
):第 3~7 步,步骤较多,其中第 5、6 步为初始化操作,第 3、4 步为在初始化前执行,第 7 步在初始化后执行,该阶段结束,才能被用户使用;Destruction
):第 8~10步,第8步不是真正意义上的销毁(还没使用呢),而是先在使用前注册了销毁的相关调用接口,为了后面第9、10步真正销毁 bean
时再执行相应的方法Spring Bean
的完整生命周期看作从创建Spring
容器开始,直到最终Spring
容器销毁Bean
,还涉及到一些其他扩展点钩子方法的使用Spring
有很强的扩展性,主要体现在它为外界提供了许多钩子方法, 比如Aware
、BeanPostProcessor
、InitializingBean
、init-method
等都是 Spring
提供的扩展点
BeanFactoryPostProcessor
接口public interface BeanFactoryPostProcessor {
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
Spring
允许BeanFactoryPostProcessor
在容器实例化任何其它bean
之前读取配置元数据,并可以根据需要进行修改,例如可以把bean
的scope
从singleton
改为prototype
,也可以把property
的值给修改掉;它是在spring
容器加载了bean
的定义文件之后,在bean
实例化之前执行的;
Spring
允许可以同时配置多个BeanFactoryPostProcessor
,并通过设置order
属性来控制各个BeanFactoryPostProcessor
的执行次序,具体看下面的例子
User
public class User{ private String name; private int age; public User() { System.out.println("实例化"); } public String getName() { return name; } public void setName(String name) { System.out.println("初始化 注入name属性"); this.name = name; } public int getAge() { return age; } public void setAge(int age) { System.out.println("初始化 注入age属性"); this.age = age; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
UserBeanFactoryPostProcessor
public class UserBeanFactoryPostProcessor implements BeanFactoryPostProcessor { /** * * @param beanFactory 从工厂中可以获取到相关bean的定义信息 * @throws BeansException */ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { System.out.println("调用UserBeanFactoryPostProcessor的postProcessBeanFactory"); BeanDefinition user = beanFactory.getBeanDefinition("user"); //value MutablePropertyValues propertyValues = user.getPropertyValues(); System.out.println("user.age:"+propertyValues.get("age")); System.out.println("将年龄更改为22"); propertyValues.addPropertyValue("age",22); System.out.println("UserBeanFactoryPostProcessor的postProcessBeanFactory调用结束"); } }
applicationContext.xml
<bean id="user" class="com.minifull.pojo.User" scope="singleton">
<property name="name" value="minifull"></property>
<property name="age" value="21"></property>
</bean>
<bean id="userBeanFactoryPostProcessor" class="com.minifull.postprocessorpag.UserBeanFactoryPostProcessor"></bean>
@Test
public void beanFactoryPostProcessortest(){
ApplicationContext applicationContext = new FileSystemXmlApplicationContext("classpath:applicationContext.xml");
User user = (User)applicationContext.getBean("user");
System.out.println(user);
}
InstantationAwareBeanPostProcessor
接口Spring源码解析(十一)Spring扩展接口InstantiationAwareBeanPostProcessor解析
InstantiationAwareBeanPostProcessor
接口继承BeanPostProcessor
接口,它内部提供了3个方法,再加上BeanPostProcessor
接口内部的2个方法,所以实现这个接口需要实现5个方法。InstantiationAwareBeanPostProcessor
接口的主要作用在于目标对象的实例化过程中需要处理的事情,包括实例化对象的前后过程以及实例的属性设置
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor { //在对象实例化之前调用,直接返回一个对象(如代理对象)来代替通过内置的实例化流程创建对象 @Nullable default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { return null; } //在对象实例化完成后,执行populateBean之前,判断是否继续进行对属性赋值的流程 default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { return true; } //在Spring处理完默认的成员属性,应用到指定的bean之前进回调,可以用来检查和修改属性 @Nullable default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException { return null; } }
从源码分析一下,InstantiationAwareBeanPostProcessor
继承了BeanPostProcessor
接口,所以他有BeanPostProcessor
的特性;
在容器初始化的refresh
方法中首先实例化 BeanPostProcessors
类型的bean
,然后才会实例化剩余 单例并且非懒加载的bean
@Override
public void refresh() throws BeansException, IllegalStateException {
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
}
单例bean
的实例化最终是发生在doCreateBean
方法中的,而在执行doCreateBean
之前有resolveBeforeInstantiation
方法
//AbstractAutowireCapableBeanFactory
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
//省略....
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
}
在resolveBeforeInstantiation
中判断执行InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { Object bean = null; //如果beforeInstantiationResolved还没有设置或者是false(说明还没有需要在实例化前执行的操作) if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) { // 判断是否有注册过InstantiationAwareBeanPostProcessor类型的bean if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { Class<?> targetType = determineTargetType(beanName, mbd); if (targetType != null) { //执行 bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); if (bean != null) { bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } } mbd.beforeInstantiationResolved = (bean != null); } return bean; } protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName); //只要有一个result不为null;后面的所有 后置处理器的方法就不执行了,直接返回(所以执行顺序很重要) if (result != null) { return result; } } } return null; } @Override public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { result = beanProcessor.postProcessAfterInitialization(result, beanName); //如果返回null;后面的所有 后置处理器的方法就不执行,直接返回(所以执行顺序很重要) if (result == null) { return result; } } return result; }
从上面代码可以看出:
1. 如果postProcessBeforeInstantiation方法返回了Object是null;那么就直接返回,调用doCreateBean方法();
2. 如果postProcessBeforeInstantiation返回不为null;说明修改了bean对象;然后这个时候就立马执行postProcessAfterInitialization方法(注意这个是初始化之后的方法,也就是通过这个方法实例化了之后,直接执行初始化之后的方法;中间的实例化之后 和 初始化之前都不执行);
3. 在调用postProcessAfterInitialization方法时候如果返回null;那么就直接返回,调用doCreateBean方法();(初始化之后的方法返回了null,那就需要调用doCreateBean生成对象了)
4. 在调用postProcessAfterInitialization时返回不为null;那这个bean就直接返回给ioc容器了 初始化之后的操作 是这里面最后一个方法了;
可以看到我们在postProcessBeforeInstantiation
和postProcessAfterInitialization
返回了对象,就不再执行Spring内部接下来的doCreateBean方法了,而是直接返回我们定义的对象,通过这一点我们可以生成一个代理类
Aware
接口spring源码:Aware接口
若 Spring
检测到 bean
实现了 Aware
接口,则会为其注入相应的依赖。所以通过让bean
实现 Aware
接口,则能在 bean
中获得相应的 Spring
容器资源。
Spring
中提供的 Aware
接口有:
BeanNameAware
:注入当前 bean
对应 beanName
;
BeanClassLoaderAware
:注入加载当前 bean
的 ClassLoader
;
BeanFactoryAware
:注入 当前BeanFactory
容器 的引用
ApplicationContextAware
如我们想得到当前的BeanFactory
,我们可以让我们的实现类继承BeanFactoryAware
接口,然后通过接口注入的方式得到当前容器中的BeanFactory
:
public class User implements BeanFactoryAware {
private BeanFactory beanFactory;
private String name;
private int age;
//get set...
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("BeanFactoryAware: 为UserBean注入beanFactory属性");
this.beanFactory = beanFactory;
}
}
BeanPostProcessor
接口BeanPostProcessor
,可以在spring
容器实例化bean
之后,在执行bean
的初始化方法前后,添加一些自己的处理逻辑。这里说的初始化方法,指的是下面两种:
① bean
实现了InitializingBean
接口,对应的方法为afterPropertiesSet
② 在bean
定义的时候,通过init-method
设置的方法
public interface BeanPostProcessor {
// 初始化前置处理
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
// 初始化后置处理
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
BeanPostProcessor
的常用场景有:
Spring AOP
功能,生成对象的代理类,然后返回使用如下:
/** * bean的后置处理器 * 分别在bean的初始化前后对bean对象提供自己的实例化逻辑 * postProcessAfterInitialization:初始化之后对bean进行增强处理 * postProcessBeforeInitialization:初始化之前对bean进行增强处理 * */ public class MyBeanPostProcessor implements BeanPostProcessor { //对初始化之后的Bean进行处理 //参数:bean:即将初始化的bean //参数:beanname:bean的名称 //返回值:返回给用户的那个bean,可以修改bean也可以返回一个新的bean public Object postProcessAfterInitialization(Object bean, String beanname) throws BeansException { User user = null; System.out.println("调用BeanPostProcessor的postProcessAfterInitialization方法:对初始化之后的Bean进行处理,将user的name改为Jack"); if("name".equals(beanname) || bean instanceof User) { user = (User) bean; user.setName("Jack"); } return user; } //对初始化之前的Bean进行处理 //参数:bean:即将初始化的bean //参数:beanname:bean的名称 //返回值:返回给用户的那个bean,可以修改bean也可以返回一个新的bean public Object postProcessBeforeInitialization(Object bean, String beanname) throws BeansException { System.out.println("调用BeanPostProcessor的postProcessBeforeInitialization方法: 对初始化之前的Bean进行处理,此时我的名字"+bean); return bean; } }
<bean id="user" class="com.minifull.pojo.User" scope="singleton">
<property name="name" value="minifull"></property>
<property name="age" value="21"></property>
</bean>
<bean id="userBeanFactoryPostProcessor" class="com.minifull.postprocessorpag.UserBeanFactoryPostProcessor"></bean>
<!-- 配置bean的后置处理器,不需要id,IoC容器自动识别是一个BeanPostProcessor -->
<bean class="com.minifull.postprocessorpag.MyBeanPostProcessor"></bean>
InitializingBean
和 DisposableBean
接口InitializingBean
是 Spring
为 bean
初始化提供的扩展点,可以添加自定义的初始化方法或者做一些资源初始化操作,当BeanFactory
设置完所有的Bean
属性之后才会调用afterPropertiesSet
方法
InitializingBean
接口 的定义如下
public interface InitializingBean {
void afterPropertiesSet() throws Exception;
}
DisposableBean
接口只有一个方法destroy
,作用是:当一个单例Bean
实现DisposableBean
,destroy
可以添加自定义的一些销毁方法或者资源释放操作
init-method
指定 init-method
方法,指定初始化方法:
public class User implements BeanFactoryAware { private BeanFactory beanFactory; private String name; private int age; public User() { System.out.println("实例化"); } public String getName() { return name; } public void setName(String name) { System.out.println("初始化 注入name属性"); this.name = name; } public int getAge() { return age; } public void setAge(int age) { System.out.println("初始化 注入age属性"); this.age = age; } //Bean的初始化方法 public void initUser() { System.out.println("Bean:init Method"); } //Bean的销毁方法 public void destroyUser() { System.out.println("Bean:destroy Method"); } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", age=" + age + '}'; } public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("BeanFactoryAware: 为UserBean注入beanFactory属性"); this.beanFactory = beanFactory; } }
<bean id="user" class="com.minifull.pojo.User" scope="singleton" init-method="initUser" destroy-method="destroyUser">
<property name="name" value="minifull"></property>
<property name="age" value="21"></property>
</bean>
<bean id="userBeanFactoryPostProcessor" class="com.minifull.postprocessorpag.UserBeanFactoryPostProcessor"></bean>
<!-- 配置bean的后置处理器,不需要id,IoC容器自动识别是一个BeanPostProcessor -->
<bean class="com.minifull.postprocessorpag.MyBeanPostProcessor"></bean>
@Test
public void test1(){
FileSystemXmlApplicationContext applicationContext = new FileSystemXmlApplicationContext("classpath:applicationContext.xml");
User user = (User)applicationContext.getBean("user");
System.out.println(user);
applicationContext.close();
}
针对上面的初始化,销毁等操作在 doCreateBean()
方法中能看到依次执行了这 4 个阶段:
// AbstractAutowireCapableBeanFactory.java protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // 1. 实例化 BeanWrapper instanceWrapper = null; if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } Object exposedObject = bean; try { // 2. 属性赋值 populateBean(beanName, mbd, instanceWrapper); // 3. 初始化 exposedObject = initializeBean(beanName, exposedObject, mbd); } // 4. 销毁-注册回调接口 try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } return exposedObject; }
关注一下initializeBean()
初始化的过程,这部分比较复杂
// AbstractAutowireCapableBeanFactory.java protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { // 3. 检查 Aware 相关接口并设置相关依赖 if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { invokeAwareMethods(beanName, bean); } // 4. BeanPostProcessor 前置处理 Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } // 5. 若实现 InitializingBean 接口,调用 afterPropertiesSet() 方法 // 6. 若配置自定义的 init-method方法,则执行 try { invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } // 7. BeanPostProceesor 后置处理 if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
在 invokInitMethods()
方法中会检查 InitializingBean
接口和 init-method
方法,销毁的过程也与其类似:
// DisposableBeanAdapter.java public void destroy() { // 9. 若实现 DisposableBean 接口,则执行 destory()方法 if (this.invokeDisposableBean) { try { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> { ((DisposableBean) this.bean).destroy(); return null; }, this.acc); } else { ((DisposableBean) this.bean).destroy(); } } } // 10. 若配置自定义的 detory-method 方法,则执行 if (this.destroyMethod != null) { invokeCustomDestroyMethod(this.destroyMethod); } else if (this.destroyMethodName != null) { Method methodToInvoke = determineDestroyMethod(this.destroyMethodName); if (methodToInvoke != null) { invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke)); } } }
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。