总结Bean的三种自定义初始化和销毁方法

目录
  • Bean三种自定义初始化和销毁
    • 一. 三种方法概述
    • 二. 方法详述
  • spring初始化后获取自定义注解Bean
    • 一.新建注解类
    • 二.新建接口类
    • 三.实现接口ApplicationListener

Bean三种自定义初始化和销毁

一. 三种方法概述

在配置类中指定 @Bean(initMethod = “init”,destroyMethod = “destory”)注解

实现InitializingBean接口并重写其afterPropertiesSet方法,实现DisposableBean接口并重写destroy方法

利用java的JSR250规范中的@PostConstruct标注在init方法上,@PreDestroy标注在destroy方法上

二. 方法详述

1. 方法1:配置类中指定

示例代码

public class CarA {
    public CarA() {
        System.out.println("CarA。。。构造函数");
    }
    public void initCarA(){
        System.out.println("CarA的init()方法");
    }
    public void destroyCarA(){
        System.out.println("CarA的destroy()方法");
    }
}
@Configuration
public class ConfigTest {
    @Bean(initMethod = "initCarA",destroyMethod = "destroyCarA")
    public CarA carA(){
        return new CarA();
    }
}

执行结果

CarA。。。构造函数
CarA的init()方法

服务启动

CarA的destroy()方法

2. 方法2:实现接口并重写方法

2.1 示例代码

public class CarB implements InitializingBean, DisposableBean {
    public CarB() {
        System.out.println("CarB。。。构造函数");
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("CarB。。。afterPropertiesSet()方法执行");
    }
    @Override
    public void destroy() throws Exception {
        System.out.println("CarB。。。destroy()方法执行");
    }
}
@Configuration
public class ConfigTest {
    @Bean
    public CarB carB(){
        return new CarB();
    }
}

执行结果

CarB。。。构造函数
CarB。。。afterPropertiesSet()方法执行

服务启动

CarB。。。destroy()方法执行

2.2 概述

Spring 开放了扩展接口,允许我们自定义 bean 的初始化和销毁方法。即当 Spring 容器在 bean 进行到相应的生命周期阶段时,会自动调用我们自定义的初始化和销毁方法。这两个扩展接口是 InitializingBean 和 DisposableBean 。

InitializingBean 接口说明:该接口为 bean 提供了 bean 属性初始化后的处理方法,它只有 afterPropertiesSet 一个方法,凡是实现此接口的类,在 bean 的属性初始化后都会执行该方法。
package org.springframework.beans.factory;

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

DisposableBean 接口说明:该接口为单例 bean 提供了在容器销毁 bean 时的处理方法,它只有 destroy 一个方法,凡是实现此接口的类,在 bean 被销毁时都会执行该方法。

package org.springframework.beans.factory;
public interface DisposableBean {
    void destroy() throws Exception;
}

2.3 方法1 && 方法2

  • 相同点:都是在 bean 属性初始化之后需要执行的初始化方法。
  • 不同点

方法1:代码不与Spring耦合;执行效率较低(通过反射来执行initMethod 方法)

方法2:代码与Spring紧耦合;速度更快(将 bean 强制转换成 InitializingBean 接口类型,然后直接调用 afterPropertiesSet 方法)

  • 说明:afterPropertiesSet 和 initMethod 可以同时存在,但是 afterPropertiesSet 方法是在 initMethod 方法之前执行的。
  • 一个 bean 从创建到初始化的过程总结

通过构造器创建 bean

属性注入

执行 afterPropertiesSet 方法

执行 initMethod 方法

3. 方法3:利用java的JSR250规范

代码示例

public class CarC {
    public CarC() {
        System.out.println("CarC。。。构造函数");
    }
    @PostConstruct
    public void initCarC(){
        System.out.println("CarC。。。初始化方法initCarC()");
    }
    @PreDestroy
    public void destroyCarC(){
        System.out.println("CarC。。。销毁方法destroyCarC");
    }
}
@Configuration
public class ConfigTest {
    @Bean
    public CarC carC(){
        return new CarC();
    }
}

执行结果

CarC。。。构造函数
CarC。。。初始化方法initCarC()

服务启动

CarC。。。销毁方法destroyCarC

spring初始化后获取自定义注解Bean

目的是通过注解将特定类的信息(如接口编号)与类关联,之后可通过接口编号获取对应bean来执行对应逻辑。

一.新建注解类

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Service
public @interface ServiceCode {
    String code() default ""; 
    String className() default "";
}

包含接口编号和beanName信息。

二.新建接口类

@ServiceCode(code = "100010", className = "echoService")
@Service("echoService")
public class EchoService { 
}

三.实现接口ApplicationListener

来监听spring容器初始化完成后执行:

@Component
@Order(1)
public class ServiceInitListener implements ApplicationListener<ContextRefreshedEvent> {
    private static final Logger LOGGER = LoggerFactory.getLogger(ServiceInitListener.class); 
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        ApplicationContext applicationContext = event.getApplicationContext();
        //注意 需要时根容器才能通过注解获取到bean,比如event直接获取的容器中只有一些公共注册bean
        if (applicationContext.getParent() != null) {
            applicationContext = applicationContext.getParent();
        }
        Map<String, Object> beansWithAnnotation = applicationContext.getBeansWithAnnotation(ServiceCode.class);
        for (Object bean : beansWithAnnotation.values()) {
            ServiceCode annotation = bean.getClass().getAnnotation(ServiceCode.class);
            String code = annotation.code();
            String className = annotation.className();
            //注册接口编号和beanName
            //在统一入口可通过code获取beanName,然后通过springContext获取对应bean执行自定义逻辑
            //或者完成其他逻辑
        }
    } 
}

注意:

ContextRefreshedEvent获取到的上下文环境不是根spring容器,其中只有部分spring内置bean,无法通过注解获取到自定义bean,需要获取其父容器来完成操作。我第一次获取是beanList总为空,后来发现其容器内部bean没有自定义的service bean,获取父容器后操作一切正常。

通过@Order注解来定制执行顺序,越小越优先执行。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • SpringBoot中的Bean的初始化与销毁顺序解析

    我今天学习到SpringBoot里面自定义Bean的初始化与销毁方法 我先总结一下我学到的四种方法: 方法一: 指定init-method 和 destory-method 方法二: 通过让 Bean 实现 InitializingBean 接口,定义初始化逻辑 DisposableBean 接口,定义销毁逻辑 方法三: 用 @PostConstruct,在 Bean 创建完成并且赋值完成后,执行该注解标注的方法 @PreDestroy,在容器销毁 Bean 之前,执行该注解标注的方法 方法四:

  • Spring Bean初始化及销毁多种实现方式

    这篇文章主要介绍了Spring Bean初始化及销毁多种实现方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一.前言 日常开发过程有时需要在应用启动之后加载某些资源,或者在应用关闭之前释放资源.Spring 框架提供相关功能,围绕 Spring Bean 生命周期,可以在 Bean 创建过程初始化资源,以及销毁 Bean 过程释放资源.Spring 提供多种不同的方式初始化/销毁 Bean,如果同时使用这几种方式,Spring 如何处理这几

  • Spring Bean的初始化和销毁实例详解

    本文实例讲述了Spring Bean的初始化和销毁.分享给大家供大家参考,具体如下: 一 点睛 在开发过程中,经常遇到在Bean使用之前或者之后做一些必要的操作,Spring对Bean的生命周期的操作提供了支持. 1 Java配置方式:使用@Bean的initMethod和destroyMethod. 2 注解方式:利用JSR-250的@PostConstruct和@PreDestroy. 二 实战 1 增加JSR250支持 <dependency> <groupId>javax.

  • Spring中bean的初始化和销毁几种实现方式详解

    Bean的生命周期 : 创建bean对象 – 属性赋值 – 初始化方法调用前的操作 – 初始化方法 – 初始化方法调用后的操作 – --- 销毁前操作 – 销毁方法的调用. [1]init-method和destroy-method 自定义初始化方法和销毁方法两种方式:xml配置和注解. ① xml配置 <bean id="person" class="com.core.Person" scope="singleton" init-meth

  • 总结Bean的三种自定义初始化和销毁方法

    目录 Bean三种自定义初始化和销毁 一. 三种方法概述 二. 方法详述 spring初始化后获取自定义注解Bean 一.新建注解类 二.新建接口类 三.实现接口ApplicationListener Bean三种自定义初始化和销毁 一. 三种方法概述 在配置类中指定 @Bean(initMethod = “init”,destroyMethod = “destory”)注解 实现InitializingBean接口并重写其afterPropertiesSet方法,实现DisposableBea

  • 详解SpringBoot静态方法获取bean的三种方式

    目录 方式一  注解@PostConstruct 方式二  启动类ApplicationContext 方式三 手动注入ApplicationContext 方式一  注解@PostConstruct import com.example.javautilsproject.service.AutoMethodDemoService; import org.springframework.beans.factory.annotation.Autowired; import org.springfr

  • Spring框架通过工厂创建Bean的三种方式实现

    工厂模式 Spring中bean的创建,默认是框架利用反射new出来的bean实例.有时候也会有一些复杂的情况. 假设有一个飞机,属性如下,现在需要造很多同型号的飞机,那么唯一需要改变的属性只有DriverName(机长姓名),此时可以使用工厂模式帮我们创建对象,有一个专门帮我们创建对象的类帮我们创建对象,这个类就叫工厂. public class AirPlane { private String DriverName;// 机长姓名 private String AirPlaneName;/

  • Spring中Bean的三种实例化方式详解

    目录 一.环境准备 二.构造方法实例化 三.分析Spring的错误信息 四.静态工厂实例化 4.1 工厂方式创建bean 4.2 静态工厂实例化 五.实例工厂与FactoryBean 5.1 环境准备 5.2 实例工厂实例化 5.3 FactoryBean的使用 六.bean实例化小结 一.环境准备 准备开发环境 创建一个Maven项目 pom.xml添加依赖 resources下添加spring的配置文件applicationContext.xml 最终项目的结构如下: 二.构造方法实例化 在

  • pytorch自定义初始化权重的方法

    在常见的pytorch代码中,我们见到的初始化方式都是调用init类对每层所有参数进行初始化.但是,有时我们有些特殊需求,比如用某一层的权重取优化其它层,或者手动指定某些权重的初始值. 核心思想就是构造和该层权重同一尺寸的矩阵去对该层权重赋值.但是,值得注意的是,pytorch中各层权重的数据类型是nn.Parameter,而不是Tensor或者Variable. import torch import torch.nn as nn import torch.optim as optim imp

  • SpringBoot定制三种错误页面及错误数据方法示例

    目录 定制错误页面 自定义 error.html 自定义动态错误页面 自定义静态错误页面 定制错误数据 1. 自定义异常处理类 2. 自定义错误属性处理工具 我们知道 Spring Boot 已经提供了一套默认的异常处理机制,但是 Spring Boot 提供的默认异常处理机制却并不一定适合我们实际的业务场景,因此,我们通常会根据自身的需要对 Spring Boot 全局异常进行统一定制,例如定制错误页面,定制错误数据等. 定制错误页面 我们可以通过以下 3 种方式定制 Spring Boot

  • Python中列表(List) 的三种遍历(序号和值)方法小结

    目录 列表(List) 的三种遍历(序号和值)方法 Python遍历整个列表 1.深入地研究循环 2.在for循环中执行更多的操作 3.在for循环结束后执行一些操作 列表(List) 的三种遍历(序号和值)方法 if __name__ == '__main__': list = ['html', 'js', 'css', 'python'] for i in list: print(list.index(i), i) # 方法1 print( '遍历列表方法1:') for i in list

  • Android 三种延迟操作的实现方法

    Android 三种延迟操作的实现方法 实现方法: 一.线程 new Thread(new Runnable(){ public void run(){ Thread.sleep(XXXX); handler.sendMessage();----告诉主线程执行任务 } }).start 二.延时器 TimerTask task = new TimerTask(){ public void run(){ //execute the task } }; Timer timer = new Timer

  • sql下三种批量插入数据的方法

    本文将介绍三种批量插入数据的方法.第一种方法是使用循环语句逐个将数据项插入到数据库中:第二种方法使用的是SqlBulkCopy,使您可以用其他源的数据有效批量加载 SQL Server 表:第三种使用的方法是sql server中的表值参数方法,表值参数是 SQL Server 2008 中的新参数类型.表值参数是使用用户定义的表类型来声明的.使用表值参数,可以不必创建临时表或许多参数,即可向 Transact-SQL 语句或例程(如存储过程或函数)发送多行数据. 代码示例: 此例子为控制台输出

  • 三种禁用FileSystemObject组件的方法

    我整理了一下,本来只找到两种方法,后来被某人一刺激,硬是想到第三种不为人所知的方法,呵呵,也不知道是不是这样的.第一种:用RegSrv32 /u C:\WINDOWS\SYSTEM\scrrun.dll(win98路径)来注销该组 件.此方法过于狠毒,属于同归于尽的方法,大家都没得用,是下招 第二种:修改Progid的值,在ASP里调用组件的方式通常是 Set 对象名=Server. CreateObject("Progid"),这时候我们就可以通过修改注册表中的Progid值从达 到

随机推荐