Bean的生命周期
Bean的完整生命周期
- 如果使用的是new关键字,则他的生命周期很简单,直接实例化,就可以使用,当使用完毕,就会被垃圾回收器回收。
- 如果是Spring管理的Bean,则比较麻烦
先了解一个接口BeanPosrProcessor
/*
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.beans.factory.config;
import org.springframework.beans.BeansException;
import org.springframework.lang.Nullable;
/**
* Factory hook that allows for custom modification of new bean instances —
* for example, checking for marker interfaces or wrapping beans with proxies.
*
* <p>Typically, post-processors that populate beans via marker interfaces
* or the like will implement {@link #postProcessBeforeInitialization},
* while post-processors that wrap beans with proxies will normally
* implement {@link #postProcessAfterInitialization}.
*
* <h3>Registration</h3>
* <p>An {@code ApplicationContext} can autodetect {@code BeanPostProcessor} beans
* in its bean definitions and apply those post-processors to any beans subsequently
* created. A plain {@code BeanFactory} allows for programmatic registration of
* post-processors, applying them to all beans created through the bean factory.
*
* <h3>Ordering</h3>
* <p>{@code BeanPostProcessor} beans that are autodetected in an
* {@code ApplicationContext} will be ordered according to
* {@link org.springframework.core.PriorityOrdered} and
* {@link org.springframework.core.Ordered} semantics. In contrast,
* {@code BeanPostProcessor} beans that are registered programmatically with a
* {@code BeanFactory} will be applied in the order of registration; any ordering
* semantics expressed through implementing the
* {@code PriorityOrdered} or {@code Ordered} interface will be ignored for
* programmatically registered post-processors. Furthermore, the
* {@link org.springframework.core.annotation.Order @Order} annotation is not
* taken into account for {@code BeanPostProcessor} beans.
*
* @author Juergen Hoeller
* @author Sam Brannen
* @since 10.10.2003
* @see InstantiationAwareBeanPostProcessor
* @see DestructionAwareBeanPostProcessor
* @see ConfigurableBeanFactory#addBeanPostProcessor
* @see BeanFactoryPostProcessor
*/
public interface BeanPostProcessor {
// 在Bean的 init方法之前触发
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
// 在Bean的 init方法之后触发
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
这个类上面的注解完整的解释了Bean的生命周期
如上图所示,Bean 的生命周期还是比较复杂的,下面来对上图每一个步骤做文字描述:
-
Spring启动,查找并加载需要被Spring管理的bean,进行Bean的实例化
-
Bean实例化后对将Bean的引入和值注入到Bean的属性中
-
如果Bean实现了BeanNameAware接口的话,Spring将Bean的Id传递给setBeanName()方法
-
如果Bean实现了BeanFactoryAware接口的话,Spring将调用setBeanFactory()方法,将BeanFactory容器实例传入
-
如果Bean实现了ApplicationContextAware接口的话,Spring将调用Bean的setApplicationContext()方法,将bean所在应用上下文引用传入进来。
-
如果Bean实现了BeanPostProcessor接口,Spring就将调用他们的postProcessBeforeInitialization()方法。
-
如果Bean 实现了InitializingBean接口,Spring将调用他们的afterPropertiesSet()方法。类似的,如果bean使用init-method声明了初始化方法,该方法也会被调用
-
如果Bean 实现了BeanPostProcessor接口,Spring就将调用他们的postProcessAfterInitialization()方法。
-
此时,Bean已经准备就绪,可以被应用程序使用了。他们将一直驻留在应用上下文中,直到应用上下文被销毁。
-
如果bean实现了DisposableBean接口,Spring将调用它的destory()接口方法,同样,如果bean使用了destory-method 声明销毁方法,该方法也会被调用
测试代码
11. 在resource目录下新建一个xml配置文件
<?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 id="a" class="com.zh.source.A" init-method="init"></bean>
<bean id="b" class="com.zh.source.B"></bean>
<bean id="aPostProcess" class="com.zh.source.APostProcess"></bean>
</beans>
- 在src目录下新建A,B,APostProcess类
public class A {
public void init(){
System.out.println("=====A===init===");
}
}
public class B {
}
public class APostProcess implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("=====APostProcess->before->"+beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("=====APostProcess->after->"+beanName);
return bean;
}
}
注意:自定义PostProcess类需要实现BeanPostProcessor接口,然后需要在类的什么阶段做处理,就实现该接口before或after,并且自定义的PostProcess类也需要交给Spring容器管理
- 测试
public class TestSpring {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("test.xml");
System.out.println(context.getBean("a"));
}
}
/**
打印结果:
=====APostProcess->before->a
=====A===init===
=====APostProcess->after->a
17:46:38.542 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'b'
=====APostProcess->before->b
=====APostProcess->after->b
com.zh.source.A@be35cd9
Disconnected from the target VM, address: '127.0.0.1:0', transport: 'socket'
Process finished with exit code 0
*/