spring bean的声明周期

最近忽然想整理一下spring bean的声明周期,由于忽然发现工做了这么久,spring bean的生命周期都忘了,平时不怎么用html

在传统的Java应用中,bean的生命周期很简单,使用Java关键字 new 进行Bean 的实例化,而后该Bean 就可以使用了。一旦bean再也不被使用,则由Java自动进行垃圾回收。java

相比之下,了解spring bean的生命周期,可让咱们在项目中更改spring的底层源码,根据咱们的业务来在spring bean的各个周期实现咱们想要的功能spring

bean 的生命周期
1.Spring启动,查找并加载须要被Spring管理的bean,进行Bean的实例化服务器

2.Bean实例化后对将Bean的引入和值注入到Bean的属性中函数

3.若是Bean实现了BeanNameAware接口的话,Spring将Bean的Id传递给setBeanName()方法post

4.若是Bean实现了BeanFactoryAware接口的话,Spring将调用setBeanFactory()方法,将BeanFactory容器实例传入.net

5.若是Bean实现了ApplicationContextAware接口的话,Spring将调用Bean的setApplicationContext()方法,将bean所在应用上下文引用传入进来。3d

6.若是Bean实现了BeanPostProcessor接口,Spring就将调用他们的postProcessBeforeInitialization()方法。htm

7.若是Bean 实现了InitializingBean接口,Spring将调用他们的afterPropertiesSet()方法。相似的,若是bean使用init-method声明了初始化方法,该方法也会被调用对象

8.若是Bean 实现了BeanPostProcessor接口,Spring就将调用他们的postProcessAfterInitialization()方法。

9.此时,Bean已经准备就绪,能够被应用程序使用了。他们将一直驻留在应用上下文中,直到应用上下文被销毁。

10.若是bean实现了DisposableBean接口,Spring将调用它的destory()接口方法,一样,若是bean使用了destory-method 声明销毁方法,该方法也会被调用。

 

上面是Spring 中Bean的核心接口和生命周期。可是翻阅JavaDoc文档发现除了以上接口外,还有另外的初始化过程涉及的接口。

Bean 完整的生命周期

 

 

BeanNameAware.setBeanName() 在建立此bean的bean工厂中设置bean的名称,在普通属性设置以后调用,在InitializinngBean.afterPropertiesSet()方法以前调用

BeanClassLoaderAware.setBeanClassLoader(): 在普通属性设置以后,InitializingBean.afterPropertiesSet()以前调用

BeanFactoryAware.setBeanFactory() : 回调提供了本身的bean实例工厂,在普通属性设置以后,在InitializingBean.afterPropertiesSet()或者自定义初始化方法以前调用

EnvironmentAware.setEnvironment(): 设置environment在组件使用时调用

EmbeddedValueResolverAware.setEmbeddedValueResolver(): 设置StringValueResolver 用来解决嵌入式的值域问题

ResourceLoaderAware.setResourceLoader(): 在普通bean对象以后调用,在afterPropertiesSet 或者自定义的init-method 以前调用,在 ApplicationContextAware 以前调用。

ApplicationEventPublisherAware.setApplicationEventPublisher(): 在普通bean属性以后调用,在初始化调用afterPropertiesSet 或者自定义初始化方法以前调用。在 ApplicationContextAware 以前调用。

MessageSourceAware.setMessageSource(): 在普通bean属性以后调用,在初始化调用afterPropertiesSet 或者自定义初始化方法以前调用,在 ApplicationContextAware 以前调用。

ApplicationContextAware.setApplicationContext(): 在普通Bean对象生成以后调用,在InitializingBean.afterPropertiesSet以前调用或者用户自定义初始化方法以前。在ResourceLoaderAware.setResourceLoader,ApplicationEventPublisherAware.setApplicationEventPublisher,MessageSourceAware以后调用。

ServletContextAware.setServletContext(): 运行时设置ServletContext,在普通bean初始化后调用,在InitializingBean.afterPropertiesSet以前调用,在 ApplicationContextAware 以后调用注:是在WebApplicationContext 运行时

BeanPostProcessor.postProcessBeforeInitialization() : 将此BeanPostProcessor 应用于给定的新bean实例 在任何bean初始化回调方法(像是InitializingBean.afterPropertiesSet或者自定义的初始化方法)以前调用。这个bean将要准备填充属性的值。返回的bean示例可能被普通对象包装,默认实现返回是一个bean。

BeanPostProcessor.postProcessAfterInitialization() : 将此BeanPostProcessor 应用于给定的新bean实例 在任何bean初始化回调方法(像是InitializingBean.afterPropertiesSet或者自定义的初始化方法)以后调用。这个bean将要准备填充属性的值。返回的bean示例可能被普通对象包装

InitializingBean.afterPropertiesSet(): 被BeanFactory在设置全部bean属性以后调用(而且知足BeanFactory 和 ApplicationContextAware)。

————————————销毁————————————

在BeanFactory 关闭的时候,Bean的生命周期会调用以下方法:

DestructionAwareBeanPostProcessor.postProcessBeforeDestruction(): 在销毁以前将此BeanPostProcessor 应用于给定的bean实例。可以调用自定义回调,像是DisposableBean 的销毁和自定义销毁方法,这个回调仅仅适用于工厂中的单例bean(包括内部bean)

实现了自定义的destory()方法

 

 

通常我平时用的比较多的是@PostConstruct注解,在spring项目中,在一个bean的初始化过程当中,方法执行前后顺序为

静态代码块>代码块>Constructor > @Autowired > @PostConstruct
被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行,而且只会被服务器调用一次,相似于Serclet的inti()方法。被@PostConstruct修饰的方法会在构造函数以后,init()方法以前运行。

@PreConstruct说明
被@PreConstruct修饰的方法会在服务器卸载Servlet的时候运行,而且只会被服务器调用一次,相似于Servlet的destroy()方法。被@PreConstruct修饰的方法会在destroy()方法以后运行,在Servlet被完全卸载以前。

@PostConstruct 修饰的方法只能是无参函数,没有返回类型,不能抛出异常

咱们能够在其中作一些本身想要的事情,例如初始化加载一些配置等

 

package com.aibao.pos.microshop.wxdev.controller;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.springframework.stereotype.Component;

@Component
public class TestAnnotationPreDestroy {
    
    static {
        System.out.println("静态代码块");
    }
    {
        System.out.println("代码块");
    }
    public TestAnnotationPreDestroy(){
        System.out.println("构造函数");
    }
    
    
    @PreDestroy
    public void destory() {
        System.out.println("我被销毁了、、、、、我是用的@PreDestory的方式、、、、、、");
        System.out.println("我被销毁了、、、、、我是用的@PreDestory的方式、、、、、、");
    }
    
    @PostConstruct
    public void init() {
        System.out.println("我被初始化、、、、、我是用的@@PostConstruct的方式、、、、、、");
        System.out.println("我被初始化、、、、、我是用的@@PostConstruct的方式、、、、、、");
    }
    
}

输出:

静态代码块
代码块
构造函数
我被初始化、、、、、我是用的@@PostConstruct的方式、、、、、、
我被初始化、、、、、我是用的@@PostConstruct的方式、、、、、、

 

http://www.javashuo.com/article/p-ypixtkvs-bd.html
https://blog.csdn.net/tengdazhang770960436/article/details/92692614

https://blog.csdn.net/qq_40194399/article/details/90720963

相关文章
相关标签/搜索