Spring Bean的生命周期


Spring Bean的生命周期

Created with Raphaël 2.3.0 实例化Bean Bean属性赋值 检查Bean是否实现了Aware的相关接口,并且设置相关依赖 Bean后处理器before执行 检查Bean是否实现了InitializingBean的相关接口,并且设置相关依赖 初始化Bean Bean后处理器after执行 使用Bean 检查Bean是否实现了DisposableBean的相关接口,并且设置相关依赖 销毁Bean

生命周期扩展接口:

BeanNameAware、BeanClassLoaderAware、BeanFactoryAware、InitializingBean、DisposableBean、BeanPostProcessor

1、BeanNameAware

BeanNameAware 是一个在 Spring 框架中定义的接口。它是一个回调接口,允许被 Spring 容器管理的 Bean 在初始化过程中获取到自己的 Bean 名称。这对于需要基于 Bean 名称来执行某些特定逻辑的应用场景非常有用。

接口定义

public interface BeanNameAware {
  void setBeanName(String name);
}

setBeanName(String name) 方法会在 Spring 容器创建完 Bean 实例后调用,并传入该 Bean 的名称作为参数。

使用场景

  • 当 Bean 需要知道自己在容器中的名称时,可以实现此接口。例如,在日志记录、配置文件读取等方面可能需要使用 Bean 的名称。

示例代码
假设我们有一个名为 MyBean 的类,它实现了 BeanNameAware 接口:

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;

public class MyBean implements BeanNameAware {
    private String beanName;

    @Override
    public void setBeanName(String name) throws BeansException {
        this.beanName = name;
        System.out.println("Bean Name: " + name);
    }
}

2、BeanClassLoaderAware

BeanClassLoaderAware 是 Spring 框架中的一个接口,它允许被 Spring 容器管理的 Bean 获得其ClassLoader(类加载器)。这在某些情况下是非常有用的,特别是当 Bean 需要进行类的动态加载或访问类路径资源时。

接口定义

public interface BeanClassLoaderAware {
  void setBeanClassLoader(ClassLoader classLoader);
}

setBeanClassLoader(ClassLoader classLoader) 方法会在 Spring 容器创建完 Bean 实例后调用,并传入该 Bean 的 ClassLoader 作为参数。
使用场景

  • 当 Bean 需要根据 ClassLoader 加载类或资源时,可以实现此接口。例如,如果你需要在运行时加载一些配置文件或动态生成的类,那么 BeanClassLoader 就会很有用。

示例代码
假设我们有一个名为 MyBean 的类,它实现了 BeanClassLoaderAware 接口:

import org.springframework.beans.factory.BeanClassLoaderAware;

public class MyBean implements BeanClassLoaderAware {
    private ClassLoader classLoader;

    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {
        this.classLoader = classLoader;
        System.out.println("Bean ClassLoader: " + classLoader);
    }

    // 使用 classLoader 加载资源的方法
    public void loadResource() {
        try {
            Class<?> clazz = classLoader.loadClass("com.example.MyDynamicClass");
            // ... 进一步处理 ...
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

3、BeanFactoryAware

BeanFactoryAware 是 Spring 框架中的一个接口,它允许被 Spring 容器管理的 Bean 获得 BeanFactory 的引用。这对于需要直接与 Spring 容器交互的 Bean 来说非常有用。

接口定义

public interface BeanFactoryAware {
  void setBeanFactory(BeanFactory beanFactory) throws BeansException;
}

setBeanFactory(BeanFactory beanFactory) 方法会在 Spring 容器创建完 Bean 实例后调用,并传入该 Bean 的 BeanFactory 作为参数。

使用场景

  • 当 Bean 需要直接从 Spring 容器中获取其他 Bean 的实例时,可以实现此接口。例如,如果一个 Bean 需要根据条件来决定是否注入另一个 Bean,或者需要在运行时动态地获取其他 Bean 的实例,那么BeanFactory 就会很有用。

示例代码
假设我们有一个名为 MyBean 的类,它实现了 BeanFactoryAware 接口:

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;

public class MyBean implements BeanFactoryAware {
    private BeanFactory beanFactory;

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
        System.out.println("BeanFactory: " + beanFactory);
    }

    // 使用 beanFactory 获取其他 Bean 的方法
    public Object getAnotherBean(String beanName) {
        return beanFactory.getBean(beanName);
    }
}

4、InitializingBean

InitializingBean 是 Spring 框架中的一个接口,它提供了一种机制让 Bean 在初始化完成后执行一些额外的操作。实现这个接口的 Bean 可以定义一个 afterPropertiesSet() 方法,该方法将在所有的属性被设置之后调用。

接口定义

public interface InitializingBean {
  void afterPropertiesSet() throws Exception;
}

afterPropertiesSet() 方法用于执行初始化操作。如果方法抛出异常,Spring 容器会捕获这些异常并适当地处理它们。

使用场景

  • 当 Bean 需要在所有属性被注入后执行一些初始化操作时,可以实现此接口。例如,验证配置、预加载数据、连接数据库等。

示例代码
假设我们有一个名为 MyBean 的类,它实现了 InitializingBean 接口:

import org.springframework.beans.factory.InitializingBean;

public class MyBean implements InitializingBean {
    private String someProperty;

    public void setSomeProperty(String someProperty) {
        this.someProperty = someProperty;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        // 初始化操作
        System.out.println("Initializing MyBean with property: " + someProperty);
        // ... 更多初始化操作 ...
    }
}

注意事项:

  1. 如果 Bean 同时实现了 InitializingBean 和定义了一个带有 @PostConstruct 注解的方法,那么
    @PostConstruct 标记的方法将优先于 afterPropertiesSet() 方法执行。
  2. 如果 Bean 定义了 init-method 属性,那么该方法将优先于 afterPropertiesSet() 方法执行。
  3. 如果 Bean 既实现了 InitializingBean 接口又定义了 init-method,那么 init-method 将在 afterPropertiesSet() 方法之后执行。

5、DisposableBean

DisposableBean 是 Spring 框架中的一个接口,它允许被 Spring 容器管理的 Bean 在容器销毁时执行一些清理工作。这对于释放资源(如关闭数据库连接、网络连接或其他需要显式关闭的资源)非常重要。

接口定义

public interface DisposableBean {
  void destroy() throws Exception;
}

destroy() 方法会在 Spring 容器销毁 Bean 之前调用。如果方法抛出异常,Spring 容器会捕获这些异常并适当地处理它们。

使用场景

  • 当 Bean 需要在容器销毁时执行一些清理操作时,可以实现此接口。例如,关闭数据库连接、释放文件句柄、断开网络连接等。

示例代码
假设我们有一个名为 MyBean 的类,它实现了 DisposableBean 接口:

import org.springframework.beans.factory.DisposableBean;

public class MyBean implements DisposableBean {
    private Connection connection;

    public void setConnection(Connection connection) {
        this.connection = connection;
    }

    @Override
    public void destroy() throws Exception {
        if (connection != null) {
            connection.close();
            System.out.println("Connection closed.");
        }
    }
}

注意事项:

  1. 如果 Bean 同时实现了 DisposableBean 接口和定义了一个带有 @PreDestroy 注解的方法,那么
    @PreDestroy 标记的方法将优先于 destroy() 方法执行。
  2. 如果 Bean 定义了 destroy-method 属性,那么该方法将优先于 destroy() 方法执行。
  3. 如果 Bean 既实现了 DisposableBean 接口又定义了 destroy-method,那么 destroy-method 将在 destroy() 方法之后执行。

6、BeanPostProcessor

BeanPostProcessor 是 Spring 框架中的一个核心接口,它提供了在 Bean 初始化前后进行自定义处理的能力。实现 BeanPostProcessor 接口可以让开发者在 Spring 容器中添加自定义的逻辑,例如进行 AOP(面向切面编程)的织入、Bean 的属性修改等。

主要特点:

  1. 接口定义

    public interface BeanPostProcessor {
      Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
      Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
    }
    
    • postProcessBeforeInitialization(Object bean, String beanName):在 Bean 的初始化方法(如 afterPropertiesSet() 或任何由 init-method 指定的方法)被调用之前调用。
    • postProcessAfterInitialization(Object bean, String beanName):在 Bean 的初始化方法被调用之后调用。
  2. 使用场景

    • 自动装配切点和通知(AOP)。
    • 修改 Bean 的属性或替换整个 Bean。
    • 执行通用的初始化或清理操作。
  3. 示例代码
    假设我们有一个名为 MyBeanPostProcessor 的类,它实现了 BeanPostProcessor 接口:

    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanPostProcessor;
    
    public class MyBeanPostProcessor implements BeanPostProcessor {
    
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            System.out.println("Bean '" + beanName + "' is about to be initialized.");
            return bean;
        }
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            System.out.println("Bean '" + beanName + "' has been initialized.");
            return bean;
        }
    }
    

注意事项:

  • Spring 容器会在内部维护一个 BeanPostProcessor 列表,并按照声明顺序调用它们。
  • 如果多个 BeanPostProcessor 被定义,它们会按声明顺序依次调用。
  • BeanPostProcessor 的实现类可能会改变传递给它的 Bean 对象。这意味着返回的对象可以是不同的类型或不同的实例。

执行顺序:

在这里插入图片描述

  • 28
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring生命周期包括实例化、配置和销毁三个阶段。首先,实例化阶段是指创建一个Bean的实例。在Spring中,Bean的实例化可以通过使用BeanFactory或ApplicationContext来获取。其次,配置阶段是指对实例化的Bean进行配置,也就是进行IOC注入。在这个阶段,Spring会根据配置文件中的Bean的id值进行相应的配置。如果Bean实现了BeanNameAware接口,Spring还会调用它实现的setBeanName(String)方法,传递的参数就是Bean的id值。最后,销毁阶段是指当Bean不再使用时进行垃圾回收。对于Singleton模式的BeanSpring会负责管理整个生命周期;而对于Prototype模式的BeanSpring在创建好并交给使用者后就不再管理后续的生命周期。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [关于Spring Bean生命周期](https://blog.csdn.net/Apeopl/article/details/82964799)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [Springbean生命周期详解](https://blog.csdn.net/qq_64169170/article/details/123052663)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值