0
点赞
收藏
分享

微信扫一扫

Mr. Cappuccino的第62杯咖啡——Spring之Bean的生命周期

醉倾城1 2023-08-19 阅读 19
mrspringjava

Spring之Bean的生命周期

Aware接口

实现Aware接口是为了bean能获取某些信息、感知某些信息。Aware自身是一个空的接口,Spring提供了很多它的实现接口,开发者实现这些已有的接口就能获取特定的一些信息。

项目结构

在这里插入图片描述

项目代码

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com</groupId>
    <artifactId>spring-bean-life-cycle</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>5.2.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>5.2.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.1.RELEASE</version>
        </dependency>
    </dependencies>

</project>

AwareBean.java

package com.spring.bean;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

/**
 * @author honey
 * @date 2023-08-13 16:08:02
 */
public class AwareBean implements BeanNameAware, BeanClassLoaderAware, ApplicationContextAware {

    private String beanName;
    private ClassLoader classLoader;
    private ApplicationContext applicationContext;

    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {
        this.classLoader = classLoader;
    }

    @Override
    public void setBeanName(String beanName) {
        this.beanName = beanName;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    public String getBeanName() {
        return beanName;
    }

    public ClassLoader getClassLoader() {
        return classLoader;
    }

    public ApplicationContext getApplicationContext() {
        return applicationContext;
    }
}

SpringTest01.java

package com.spring.test;

import com.spring.bean.AwareBean;
import org.springframework.context.support.GenericApplicationContext;

/**
 * @author honey
 * @date 2023-08-13 16:43:37
 */
public class SpringTest01 {

    public static void main(String[] args) {
        GenericApplicationContext applicationContext = new GenericApplicationContext();
        applicationContext.registerBean("awareBean", AwareBean.class);
        applicationContext.refresh();
        AwareBean awareBean = applicationContext.getBean("awareBean", AwareBean.class);
        System.out.println("beanName:" + awareBean.getBeanName());
        System.out.println("classLoader:" + awareBean.getClassLoader());
        System.out.println("applicationContext:" + awareBean.getApplicationContext());
        applicationContext.close();
    }
}

运行结果

在这里插入图片描述

源代码


AbstractApplicationContext.java

在这里插入图片描述

在这里插入图片描述

DefaultListableBeanFactory.java

在这里插入图片描述

AbstractBeanFactory.java

在这里插入图片描述

在这里插入图片描述

AbstractAutowireCapableBeanFactory.java

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


AbstractApplicationContext.java

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

从AbstractApplicationContext类的finishBeanFactoryInitialization方法一直进入到AbstractAutowireCapableBeanFactory类的initializeBean方法,具体跳转步骤此处省略,可参照上面的跳转步骤

AbstractAutowireCapableBeanFactory.java

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

ApplicationContextAwareProcessor.java

在这里插入图片描述

在这里插入图片描述


使用场景

SpringContextUtils.java

package com.bubble.core.util;

import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;
import org.springframework.stereotype.Component;

/**
 * Spring上下文工具类
 *
 * @author honey
 * @date 2021-09-21 18:27:54
 */
@Component
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class SpringContextUtils implements ApplicationContextAware {

    private static ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context = applicationContext;
    }

    public static ApplicationContext getApplicationContext() {
        return context;
    }

    public static <T> T getBean(String s, Class<T> clazz) {
        return context.getBean(s, clazz);
    }

    public static Boolean containsBean(String s) {
        return context.containsBean(s);
    }

    public static Boolean containsBean(Class<?> clazz) {
        String first = clazz.getSimpleName().substring(0, 1).toLowerCase();
        String after = clazz.getSimpleName().substring(1);
        return context.containsBean(first + after);
    }

    public static <T> T getBean(Class<T> clazz) {
        return context.getBean(clazz);
    }

    public static void publishEvent(ApplicationEvent event) {
        context.publishEvent(event);
    }
}

InitializingBean接口

InitializingBean接口为bean对象提供了初始化方法,它只包括afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候都会执行该方法。

实现InitializingBean接口是直接调用afterPropertiesSet方法,比通过反射调用init-method指定的方法效率要高一点,但是init-method方式消除了对spring的依赖。如果调用afterPropertiesSet方法时出错,则不调用init-method指定的方法。

@PostConstruct通过Bean对象后置处理器(CommonAnnotationBeanPostProcessor)实现,InitializingBean和@Bean通过IOC工厂(BeanFactory)实现。

项目结构

在这里插入图片描述

项目代码

InitBean.java

package com.spring.bean;

import org.springframework.beans.factory.InitializingBean;

import javax.annotation.PostConstruct;

/**
 * @author honey
 * @date 2023-08-13 18:41:58
 */
public class InitBean implements InitializingBean {

    @Override
    public void afterPropertiesSet() {
        System.out.println("InitBean 调用afterPropertiesSet()");
    }

    @PostConstruct
    public void init(){
        System.out.println("InitBean 调用init()");
    }

    public void initMethod(){
        System.out.println("InitBean 调用initMethod()");
    }
}

SpringConfig.java

package com.spring.config;

import com.spring.bean.InitBean;
import org.springframework.context.annotation.Bean;

/**
 * @author honey
 * @date 2023-08-13 18:52:09
 */
public class SpringConfig {

    @Bean(initMethod = "initMethod")
    public InitBean initBean() {
        return new InitBean();
    }
}

SpringTest02.java

package com.spring.test;

import com.spring.bean.InitBean;
import com.spring.config.SpringConfig;
import org.springframework.context.annotation.CommonAnnotationBeanPostProcessor;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.context.support.GenericApplicationContext;

/**
 * @author honey
 * @date 2023-08-13 18:48:22
 */
public class SpringTest02 {

    public static void main(String[] args) {
        GenericApplicationContext applicationContext = new GenericApplicationContext();
        applicationContext.registerBean("springConfig", SpringConfig.class);
        applicationContext.registerBean(CommonAnnotationBeanPostProcessor.class);
        applicationContext.registerBean(ConfigurationClassPostProcessor.class);
        applicationContext.refresh();
        InitBean initBean = applicationContext.getBean("initBean", InitBean.class);
        System.out.println("InitBean " + initBean);
        applicationContext.close();
    }
}

运行结果

在这里插入图片描述

源代码


AbstractAutowireCapableBeanFactory.java

在这里插入图片描述

CommonAnnotationBeanPostProcessor.java

在这里插入图片描述

InitDestroyAnnotationBeanPostProcessor.java

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


AbstractAutowireCapableBeanFactory.java

在这里插入图片描述

在这里插入图片描述


AbstractAutowireCapableBeanFactory.java

在这里插入图片描述

在这里插入图片描述


BeanFactoryPostProcessor接口

实现BeanFactoryPostProcessor接口,可以在Spring的bean创建之前,修改bean的定义属性。也就是说,Spring允许BeanFactoryPostProcessor在容器实例化任何其它bean之前读取配置元数据,并可以根据需要进行修改,例如可以把bean的scope从singleton改为prototype,也可以把property的值给修改掉。可以同时配置多个BeanFactoryPostProcessor,并通过设置’order’属性来控制各个BeanFactoryPostProcessor的执行次序。
注意:BeanFactoryPostProcessor是在Spring容器加载了bean的定义文件之后,在bean实例化之前执行的。接口方法的入参是ConfigurrableListableBeanFactory。

ConfigurationClassPostProcessor:主要用于处理配置类,使@Bean、@Import、@ComponentScan等注解生效。

项目结构

在这里插入图片描述

项目代码

UserBean.java

package com.spring.bean;

/**
 * @author honey
 * @date 2023-08-14 01:02:08
 */
public class UserBean {

    private String name = "Faker";

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

MyBeanFactoryPostProcessor.java

package com.spring.processor;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

/**
 * @author honey
 * @date 2023-08-14 01:00:25
 */
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        // 修改bean对象的属性值
        BeanDefinition userBean = beanFactory.getBeanDefinition("userBean");
        userBean.getPropertyValues().addPropertyValue("name", "Honey");
    }
}

SpringTest03.java

package com.spring.test;

import com.spring.bean.UserBean;
import com.spring.processor.MyBeanFactoryPostProcessor;
import org.springframework.context.support.GenericApplicationContext;

/**
 * @author honey
 * @date 2023-08-14 01:04:16
 */
public class SpringTest03 {

    public static void main(String[] args) {
        GenericApplicationContext applicationContext = new GenericApplicationContext();
        applicationContext.registerBean("userBean", UserBean.class);
        applicationContext.registerBean(MyBeanFactoryPostProcessor.class);
        applicationContext.refresh();
        UserBean userBean = applicationContext.getBean("userBean", UserBean.class);
        System.out.println("userBean name:" + userBean.getName());
        applicationContext.close();
    }
}

运行结果

在这里插入图片描述

源代码


AbstractApplicationContext.java

在这里插入图片描述

在这里插入图片描述

PostProcessorRegistrationDelegate.java

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


AbstractApplicationContext.java

在这里插入图片描述

具体跳转步骤此处省略

AbstractAutowireCapableBeanFactory.java

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


Bean的生命周期

Spring bean的生命周期主要包含四个阶段:实例化 Instantiation --> 属性赋值 Populate --> 初始化 Initialization --> 销毁 Destruction

Spring bean的生命周期核心代码:AbstractBeanFactory#getBean()

  1. 实例化Bean对象,执行构造方法;
  2. 属性赋值,对Bean对象中的属性进行赋值,如在Bean对象中使用@Autowired注解实现依赖注入以及通过BeanFactoryPostProcessor修改Bean对象中的属性值;
  3. 初始化阶段,执行Bean对象中Aware相关接口的实现方法;
  4. 初始化阶段,执行BeanPostProcessor#postProcessBeforeInitialization(),在初始化方法之前执行;
  5. 初始化阶段,执行初始化方法;
  6. 初始化阶段,执行BeanPostProcessor#postProcessAfterInitialization(),在初始化方法之后执行;
  7. 销毁Bean对象;

项目结构

在这里插入图片描述

项目代码

AutowireBean.java

package com.spring.bean;

/**
 * @author honey
 * @date 2023-08-14 01:48:12
 */
public class AutowireBean {
}

LifeCycleBean.java

package com.spring.bean;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

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

/**
 * @author honey
 * @date 2023-08-14 01:47:44
 */
public class LifeCycleBean implements BeanNameAware, BeanClassLoaderAware, ApplicationContextAware, InitializingBean, DisposableBean {

    private String name;

    public LifeCycleBean() {
        System.out.println("1.执行无参构造方法");
        System.out.println("LifeCycleBean 执行LifeCycleBean()");
    }

    @Autowired
    public void setAutowireBean(AutowireBean autowireBean) {
        System.out.println("2.设置对象属性");
        System.out.println("LifeCycleBean 执行setAutowireBean() autowireBean = " + autowireBean);
    }

    public void setName(String name) {
        System.out.println("2.设置对象属性");
        System.out.println("LifeCycleBean 执行setName() name = " + name);
        this.name = name;
    }

    @Override
    public void setBeanName(String name) {
        System.out.println("3.执行Aware接口中的方法");
        System.out.println("LifeCycleBean 执行setBeanName()");
    }

    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {
        System.out.println("3.执行Aware接口中的方法");
        System.out.println("LifeCycleBean 执行setBeanClassLoader()");
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("3.执行Aware接口中的方法");
        System.out.println("LifeCycleBean 执行setApplicationContext()");
    }

    @Override
    public void afterPropertiesSet() {
        System.out.println("5.执行初始化方法");
        System.out.println("LifeCycleBean 执行afterPropertiesSet()");
    }

    @PostConstruct
    public void postConstruct() {
        System.out.println("5.执行初始化方法");
        System.out.println("LifeCycleBean 执行postConstruct()");
    }

    public void initMethod() {
        System.out.println("5.执行初始化方法");
        System.out.println("LifeCycleBean 执行initMethod()");
    }

    @Override
    public void destroy() {
        System.out.println("7.执行销毁方法");
        System.out.println("LifeCycleBean 执行destroy()");
    }

    @PreDestroy
    public void preDestroy() {
        System.out.println("7.执行销毁方法");
        System.out.println("LifeCycleBean 执行preDestroy()");
    }

    public String getName() {
        return name;
    }
}

LifeCycleBeanFactoryPostProcessor.java

package com.spring.processor;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

/**
 * @author honey
 * @date 2023-08-14 02:13:45
 */
public class LifeCycleBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        // 修改bean对象的属性值
        BeanDefinition userBean = beanFactory.getBeanDefinition("lifeCycleBean");
        userBean.getPropertyValues().addPropertyValue("name", "Honey");
    }
}

LifeCycleBeanPostProcessor.java

package com.spring.processor;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

/**
 * @author honey
 * @date 2023-08-14 02:01:57
 */
public class LifeCycleBeanPostProcessor implements BeanPostProcessor {

    private final String beanName = "lifeCycleBean";

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (this.beanName.equals(beanName)) {
            System.out.println("4.bean对象后置处理器初始化方法之前执行");
            System.out.println("LifeCycleBean 执行postProcessBeforeInitialization()");
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (this.beanName.equals(beanName)) {
            System.out.println("6.bean对象后置处理器初始化方法之后执行");
            System.out.println("LifeCycleBean 执行postProcessAfterInitialization()");
        }
        return bean;
    }
}

SpringConfig02.java

package com.spring.config;

import com.spring.bean.AutowireBean;
import com.spring.bean.LifeCycleBean;
import com.spring.processor.LifeCycleBeanFactoryPostProcessor;
import com.spring.processor.LifeCycleBeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;

/**
 * @author honey
 * @date 2023-08-14 02:17:17
 */
@Import({LifeCycleBeanFactoryPostProcessor.class, LifeCycleBeanPostProcessor.class})
public class SpringConfig02 {

    @Bean(initMethod = "initMethod")
    public LifeCycleBean lifeCycleBean() {
        return new LifeCycleBean();
    }

    @Bean
    public AutowireBean autowireBean() {
        return new AutowireBean();
    }
}

SpringTest04.java

package com.spring.test;

import com.spring.bean.LifeCycleBean;
import com.spring.config.SpringConfig02;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * @author honey
 * @date 2023-08-14 02:15:22
 */
public class SpringTest04 {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig02.class);
        LifeCycleBean lifeCycleBean = applicationContext.getBean("lifeCycleBean", LifeCycleBean.class);
        System.out.println("-----------------------------------");
        System.out.println("LifeCycleBean " + lifeCycleBean);
        System.out.println("-----------------------------------");
        applicationContext.close();
    }
}

运行结果

在这里插入图片描述

源代码

AbstractBeanFactory.java

在这里插入图片描述
在这里插入图片描述

AbstractAutowireCapableBeanFactory.java

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述


举报

相关推荐

0 条评论