从北京回成都被隔离7天,今天是第二天,我是一个比较自由的人,如果让我宅在屋子里面,我真的会疯掉,我总是盯着窗外看,不由自主地想到钱钟书在《围城》里面说:"婚姻是一座围城,城外的人想进去,城里的人想出来,虽然我没有婚姻",不过以我目前被隔离的状态,我是能理解那种感受的,我看到身边不少的男性女性朋友步入婚姻后,有的幸福,有的是无比的痛苦,不过,
你在选择的时候,就要想清楚你是否能承担这个选择给你带来的后果
,任何事物都是这样,不论婚姻,学业,事业,爱情等,美好的事物可能会伴随不好的结果,同样,不好的开端同样可能会收获完美的结局,这一切都取决于我们怎么抉择,如果你喜欢城外,那么就呆在城外,你喜欢城里,那么就呆在城里!
今天我们来分享一下Spring Bean的生命周期,Spring Bean的生命周期对于我们掌握Spring来说是很关键的,理解了Spring的生命周期,那么我们在开发的时候才能更好的利用Spring的功能,从而达到我们的目的!
此阶段主要配置bean的信息,bean的配置有xml,注解,properties,API BeanDefinition
方式,我们主要用的是xml和注解,不过随着 springboot的发展,现在xml也不怎么用了,一般都是使用注解,不过这些方式最终都会通过解析,然后配置到BeanDefinition
中,所以我们可以直接 通过原生API BeanDefinition
来创建Bean,下面我们主要通过xml和注解来配置简单的Bean。
定义一个Bean
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private String username;
private String idCard;
}
<bean id="user" class="com.steak.spring.beanbuild.User">
<constructor-arg index="0" name="username" value="steak"/>
<constructor-arg index="1" name="idCard" value="522425199812290589"/>
</bean>
<bean id="user" class="com.steak.spring.beanbuild.User">
<property name="username" value="steak"/>
<property name="idCard" value="522425199812290589"/>
</bean>
@Configuration
和@Bean
@Configuration
public class UserConfig {
@Bean
public User user(){
return new User("steak","123456");
}
}
@Component
,@Service
,@Controller
等注解申明一个Bean@Component
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private String username;
private String idCard;
}
使用BeanDefinitionBuilder
建造者来构建一个Bean,并设置属性和其他一些信息,如作用域scope,懒加载lazyInit等,使用addPropertyValue
来填充属性,构建完成之后使用DefaultListableBeanFactory
的registerBeanDefinition
注册到Spring工厂。
public class BeanBuildTest {
public static void main(String[] args) {
//构建BeanDefinition
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(User.class.getName());
beanDefinitionBuilder.addPropertyValue("username","steak");
beanDefinitionBuilder.addPropertyValue("idCard","522425199812290045");
AbstractBeanDefinition userBeanDefinition = beanDefinitionBuilder.getBeanDefinition();
System.out.println(userBeanDefinition);
//注册Bean
DefaultListableBeanFactory defaultListableBeanFactory = new DefaultListableBeanFactory();
defaultListableBeanFactory.registerBeanDefinition("user",userBeanDefinition);
//获取Bean
User user = defaultListableBeanFactory.getBean("user", User.class);
System.out.println(user);
}
}
第二阶段主要是解析Bean的元信息,这里我们主要来演示解析XML
和注解
方式的Bean,
使用XmlBeanDefinitionReader
来对xml文件进行解析,loadBeanDefinitions
加载spring配置文件,这个方法返回参数是一个整数, 代表Bean的个数,然后使用DefaultListableBeanFactory
的getBeanDefinitionNames
获取所有Bean,返回一个数组,我们再对其解析。
public class XmlBeanReaderTest {
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
xmlBeanDefinitionReader.loadBeanDefinitions("spring.xml");
String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
for (String definitionName : beanDefinitionNames) {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(definitionName);
System.out.println(beanDefinition.getPropertyValues());
System.out.println(definitionName);
}
}
}
注解使用AnnotatedBeanDefinitionReader对Bean进行解析
public class AnnotationBeanReaderTest {
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
AnnotatedBeanDefinitionReader reader = new AnnotatedBeanDefinitionReader(beanFactory);
reader.register(UserService.class);
BeanDefinition beanDefinition = beanFactory.getBeanDefinition("userService");
System.out.println(beanDefinition);
}
}
解析完Bean以后,需要将Bean注册到Spring容器中,注册Bean有一个接口BeanDefinitionRegistry
,它继承了AliasRegistry
接口,可以看出它提供了设置别名 的一些操作,BeanDefinitionRegistry
是一个接口,我们不能直接进行实例化,所以我们一般使用的是它的实现类DefaultListableBeanFactory
。
public interface BeanDefinitionRegistry extends AliasRegistry {
void registerBeanDefinition(String var1, BeanDefinition var2) throws BeanDefinitionStoreException;
void removeBeanDefinition(String var1) throws NoSuchBeanDefinitionException;
BeanDefinition getBeanDefinition(String var1) throws NoSuchBeanDefinitionException;
boolean containsBeanDefinition(String var1);
String[] getBeanDefinitionNames();
int getBeanDefinitionCount();
boolean isBeanNameInUse(String var1);
}
public interface AliasRegistry {
//设置别名
void registerAlias(String name, String alias);
//移除别名
void removeAlias(String alias);
//是否是别名
boolean isAlias(String name);
//获取别名
String[] getAliases(String name);
}
注册Bean需要使用一个BeanDefinitionBuilder建造者来建造一个BeanDefinition,上面已经说过,这里不赘述。建造完成以后再使用BeanDefinitionRegistry
来注册Bean,使用registerBeanDefinition
进行注册。
的
public class BeanRegister {
public static void main(String[] args) {
//构建BeanDefinition
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(User.class.getName());
beanDefinitionBuilder.addPropertyValue("username","steak");
beanDefinitionBuilder.addPropertyValue("idCard","522425199812290045");
AbstractBeanDefinition userBeanDefinition = beanDefinitionBuilder.getBeanDefinition();
System.out.println(userBeanDefinition);
//注册Bean到Spring
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
beanFactory.registerBeanDefinition("user",userBeanDefinition);
//获取Bean
User user = beanFactory.getBean("user", User.class);
System.out.println(user);
}
}
BeanDefinitionRegistry
继承了AliasRegistry
,AliasRegistry
提供了一些操作别名的方法,下面演示一些方法。beanFactory.registerBeanDefinition("user",userBeanDefinition);
beanFactory.registerAlias("user","user-1");
beanFactory.registerAlias("user","user-2");
//获取Bean
User user = beanFactory.getBean("user", User.class);
for (String alias : beanFactory.getAliases("user")) {
System.out.println(alias);
}
到这里Spring的Bean就注册完了,注册完Bean以后再继续做其他的操作。
Bean实例化分为实例化前和实例化,实例化前会调用applyBeanPostProcessorsBeforeInitialization
, 实例化会调用determineConstructorsFromBeanPostProcessors
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
看出对getBeanPostProcessors()
进行遍历操作,getBeanPostProcessors()
是一个集合,泛型是BeanPostProcessor
,BeanPostProcessor
可以使我们 在对Bean进行实例化的时候做一些干扰,
private final List<BeanPostProcessor> beanPostProcessors = new BeanPostProcessorCacheAwareList();
public class BeanInstanceBeforeTest{
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
beanFactory.addBeanPostProcessor(new BeanPostProcessor() {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if ("user".equals(beanName)){
return new User("liupai","123456");
}
return null;
}
});
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class)
.addPropertyValue("idCard", "111111")
.addPropertyValue("username", "steak")
.getBeanDefinition();
beanFactory.registerBeanDefinition("user",beanDefinition);
User user = beanFactory.getBean("user", User.class);
System.out.println(user);
}
}
在实例化前我们对Bean进行干扰,如果Bean为"user",那么对其重新赋值,我们从输出可以看出输出的并不是我们使用BeanDefinitionBuilder.addPropertyValue() 构造的值,而是在BeanPostProcessor
构造的值,由此可以看出实例化过程已经被我们干扰,不过这样的操作一般不会用。
通过Bean的构造函数实例化Bean
@Nullable
protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)
throws BeansException {
if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {
Constructor<?>[] ctors = bp.determineCandidateConstructors(beanClass, beanName);
if (ctors != null) {
return ctors;
}
}
}
return null;
}
Bean实例化完成后会调用applyBeanPostProcessorsAfterInitialization
方法
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
我们也可以对实例化后的Bean进行干扰,下面我们将实例化后的Bean设置为空
public class BeanInstanceAfterTest{
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
beanFactory.addBeanPostProcessor(new BeanPostProcessor() {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("user")){
return new User(null,null);
}
return null;
}
});
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class)
.addPropertyValue("idCard", "111111")
.addPropertyValue("username", "steak")
.getBeanDefinition();
beanFactory.registerBeanDefinition("user",beanDefinition);
User user = beanFactory.getBean("user", User.class);
System.out.println(user);
}
}
从输出结果可以看出我们在实例化Bean以后可以对其进行干扰,只不过这样的操作很少会去用。
对Bean进行实例化后就到了属性赋值阶段,属性赋值阶段会调用InstantiationAwareBeanPostProcessor
的postProcessProperties
,下面我们手动进行属性赋值, 我们在构建 BeanDefinition时并没有设置属性,而是在进行实例化的时候再进行属性赋值,
public class BeanPropertiesTest {
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
beanFactory.addBeanPostProcessor(new InstantiationAwareBeanPostProcessor() {
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
if (beanName.equals("user")){
MutablePropertyValues propertyValues = (MutablePropertyValues) pvs;
propertyValues.add("username","steak");
propertyValues.add("idCard","111111");
}
return null;
}
});
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class)
.getBeanDefinition();
beanFactory.registerBeanDefinition("user",beanDefinition);
User user = beanFactory.getBean("user", User.class);
System.out.println(user);
}
}
从输出可以看出属性设置成功。
如果在构建BeanDefinition的时候已经有属性值了,那么PropertyValues
就会有相应的属性值(这些属性值是我们在XML或者注解中设置的值)
public class BeanPropertiesTest {
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
beanFactory.addBeanPostProcessor(new InstantiationAwareBeanPostProcessor() {
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
return null;
}
});
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class)
.addPropertyValue("idCard", "222222")
.addPropertyValue("username", "steak")
.getBeanDefinition();
beanFactory.registerBeanDefinition("user",beanDefinition);
User user = beanFactory.getBean("user", User.class);
System.out.println(user);
}
}
Bean属性赋值成功以后会回调invokeAwareMethods
,实现BeanNameAware , BeanClassLoaderAware , BeanFactoryAware接口的Bean,在Bean 初始化的时候会依次执行,如下。
public class UserAware implements BeanNameAware , BeanClassLoaderAware , BeanFactoryAware {
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
System.out.println("classLoader "+classLoader);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("beanFactory "+beanFactory);
}
@Override
public void setBeanName(String name) {
System.out.println("name "+name);
}
}
public class UserAwareTest {
public static void main(String[] args) {
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(UserAware.class.getName());
AbstractBeanDefinition userBeanDefinition = beanDefinitionBuilder.getBeanDefinition();
//注册Bean
DefaultListableBeanFactory defaultListableBeanFactory = new DefaultListableBeanFactory();
defaultListableBeanFactory.registerBeanDefinition("userAware",userBeanDefinition);
//获取Bean
UserAware userAware = defaultListableBeanFactory.getBean("userAware", UserAware.class);
System.out.println(userAware);
}
}
由此看出,执行顺序是按照回调函数invokeAwareMethods
的Bean判断顺序来执行的,顺序为BeanNameAware->BeanClassLoaderAware->BeanFactoryAware
Bean初始化前会调用BeanPostProcessor
接口的postProcessBeforeInitialization
作初始化操作,BeanPostProcessor
, 看下BeanPostProcessor
的两个实现类 CommonAnnotationBeanPostProcessor
和ApplicationContextAwareProcessor
ApplicationContextAwareProcessor
的invokeAwareInterfaces
中有7个判断,如果我们的Bean实现了这7个Aware接口,那么将会依次执行这 7个接口的方法,CommonAnnotationBeanPostProcessor
是处理@PostConstruct
的处理器
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
if (bean instanceof ApplicationStartupAware) {
((ApplicationStartupAware) bean).setApplicationStartup(this.applicationContext.getApplicationStartup());
}
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
public CommonAnnotationBeanPostProcessor(){
setOrder(Ordered.LOWEST_PRECEDENCE-3);
setInitAnnotationType(PostConstruct.class);
setDestroyAnnotationType(PreDestroy.class);
ignoreResourceType("javax.xml.ws.WebServiceContext");
// java.naming module present on JDK 9+?
if(jndiPresent){
this.jndiFactory=new SimpleJndiBeanFactory();
}
}
@PostConstruct
注解的方法public class UserApplicationContextAware implements EnvironmentAware , EmbeddedValueResolverAware , ResourceLoaderAware,
ApplicationEventPublisherAware, MessageSourceAware,ApplicationStartupAware,ApplicationContextAware {
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("applicationContext "+applicationContext);
}
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
System.out.println("applicationEventPublisher "+applicationEventPublisher);
}
@Override
public void setApplicationStartup(ApplicationStartup applicationStartup) {
System.out.println("applicationStartup "+applicationStartup);
}
@Override
public void setEmbeddedValueResolver(StringValueResolver resolver) {
System.out.println("resolver "+resolver);
}
@Override
public void setEnvironment(Environment environment) {
System.out.println("environment "+environment);
}
@Override
public void setMessageSource(MessageSource messageSource) {
System.out.println("messageSource "+messageSource);
}
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
System.out.println("resourceLoader "+resourceLoader);
}
@PostConstruct
public void PostConstructTest(){
System.out.println("PostConstruct SimpleTest");
}
}
public class UserApplicationContextAwareTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(UserApplicationContextAware.class);
context.refresh();
}
}
可以看出实现了EnvironmentAware , EmbeddedValueResolverAware , ResourceLoaderAware, ApplicationEventPublisherAware, MessageSourceAware,ApplicationStartupAware,ApplicationContextAware这七个接口,将会按照ApplicationContextAwareProcessor
的invokeAwareInterfaces
顺序执行
Bean在初始化的时候会调用InitializingBean
接口的afterPropertiesSet()
方法。
public interface InitializingBean {
void afterPropertiesSet() throws Exception;
}
如果我们指定了Bean的初始化方法,那么在调用完afterPropertiesSet()
方法后会调用我们自定义的初始化方法
InitializingBean
public class BusinessService implements InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("after ");
}
/**
* 初始化方法
*/
public void init(){
System.out.println("init");
}
}
可以通过@Bean(initMethod = "init")
这种方式来设置Bean的初始化方法,这个方法就是BusinessService
Bean中的 init()方法,
@Configuration
public class BeanConfig{
@Bean(initMethod = "init")
public BusinessService businessService(){
return new BusinessService();
}
}
public class ConfigBeanTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class);
}
}
从输出看出先执行afterPropertiesSet()
在执行我们自定义的初始化方法。
Bean初始化完成后会调用BeanPostProcessor
接口的postProcessAfterInitialization()
方法。
所有单例Bean初始化完成之后会调用SmartInitializingSingleton
接口的afterSingletonsInstantiated()
方法,逻辑如下
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
.tag("beanName", beanName);
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
smartInitialize.end();
}
}
public class Bean1 {
public Bean1(){
System.out.println("bean1 ");
}
}
public class Bean2 {
public Bean2(){
System.out.println("bean2");
}
}
SmartInitializingSingleton
@Configuration
public class BeanInitOverConfig implements SmartInitializingSingleton {
@Override
public void afterSingletonsInstantiated() {
System.out.println("所有单例bean初始化完成之后调用");
}
@Bean
public Bean1 bean1(){
return new Bean1();
}
@Bean
public Bean2 bean2(){
return new Bean2();
}
}
public class BeanInitOverTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanInitOverConfig.class);
}
}
从输出可以看出Bean1和Bean2输出后afterSingletonsInstantiated()
再输出,由此证明所有单例Bean初始化完成后会调用SmartInitializingSingleton
的afterSingletonsInstantiated()
方法。
初始化完成Bean后就可以使用Bean,使用Bean使用getBean方法便可,
public class BeanInitOverTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanInitOverConfig.class);
Bean1 bean1 = context.getBean("bean1", Bean1.class);
}
}
Bean的销毁可以使用@PreDestroy
注解,自定义销毁方法,实现DisposableBean
接口。
public class Bean1 implements DisposableBean {
public Bean1(){
System.out.println("bean1 ");
}
/**
* 自定义销毁方法
*/
public void bean1Destroy(){
System.out.println("销毁bean1");
}
/**
* 实现DisposableBean
* @throws Exception
*/
@Override
public void destroy() throws Exception {
System.out.println("继承DisposableBean销毁bean");
}
/**
* 使用@PreDestroy
*/
@PreDestroy
public void preDestroy(){
System.out.println("@PreDestroy销毁bean");
}
}
@Configuration
public class BeanDestroyConfig{
@Bean(destroyMethod = "bean1Destroy")
public Bean1 bean1(){
return new Bean1();
}
}
AnnotationConfigApplicationContext
的close
触发销毁beanpublic class BeanDestroyTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanDestroyConfig.class);
context.close();
}
}
可以看出使用销毁顺序优先级为@PreDestroy
> 实现DisposableBean > 自定义方法
使用@PreDestroy
销毁Bean,它会调用DestructionAwareBeanPostProcessor
的postProcessBeforeDestruction
,postProcessBeforeDestruction
在它的实现类InitDestroyAnnotationBeanPostProcessor
中进行销毁
@Override
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
try {
metadata.invokeDestroyMethods(bean, beanName);
}
catch (InvocationTargetException ex) {
String msg = "Destroy method on bean with name '" + beanName + "' threw an exception";
if (logger.isDebugEnabled()) {
logger.warn(msg, ex.getTargetException());
}
else {
logger.warn(msg + ": " + ex.getTargetException());
}
}
catch (Throwable ex) {
logger.warn("Failed to invoke destroy method on bean with name '" + beanName + "'", ex);
}
}
CommonAnnotationBeanPostProcessor
对@PreDestroy
进行管理,它继承了InitDestroyAnnotationBeanPostProcessor
,
到这里,Bean的生命周期就说完了。
今天的分享就到这里,感谢你的观看,我们下期见