深入Spring专题(31)

134 阅读2分钟

这是我参与2022首次更文挑战的第38天,活动详情查看2022首次更文挑战

Spring首选调用初始化回调,并且使用DestructiveBean实例创建并存储了File实例,在调用destroy()方法期间时,Spring遍历它所管理的一组单例,并调用指定的销毁回调。在回调中,使用DestructiveBean实例删除所创建的文件并将消息记录到控制态中显示,指示文件是否存在。

实现DisposableBean接口

bean可实现Disposable接口,作为接收销毁回调的机制,DisposableBean接口定义了一个方法destroy(),该方法在bean被销毁之前被调用。使用该机制与使用InitializingBean接口初始化回调是正交的,实现了DisposableBean接口的DestructiveBean类如下:

public class DestructiveBean implements InitializingBean,DisposableBean{
    private File file;
    private String filePath;
    
    public void afterPropertiesSet() throws Exception{
        System.out.println("Initializing Bean");
        if(filePath == null){
            throw new IllegalArgumentException("你必须定义文件目录属性的值:"+DestructiveBean.class);
        }
        this.file=new File(filePath);
        this.file.createNewFile();
        System.out.println("文件存在:"+file.exists());
    }
    @Override
    public void destroy(){
        System.out.println("Destroying Bean");
        if(!file.delete()){
            System.out.println("删除文件失败!");
        }
        System.out.println("文件存在:"+file.exists());
    }
    
    public void setFilePath(String filePath){
        this.filePath=filePath;
    }
    public static void main(String... args) throws Exception{
        GenericXmlApplicationContext ctx=new GenericXmlApplicationContext();
        ctx.load("classpath:spring/app-context.xml");
        ctx.refresh();
        
        DestructiveBean bean=(DestructiveBean)ctx.getBean("destructiveBean");
        System.out.println("调用bean销毁方法开始");
        ctx.destroy();
        System.out.println("调用bean销毁方法结束");
    }
   
}

使用回调方法机制的代码与使用回调接口机制的代码是没什么差别,可使用相同的方法名称。

使用JSR-250 @PreDestroy注解

定义在bean销毁之前所调用方法的第三种方式是使用JSR-250 生命周期注解@PreDestroy,它与@PreConstruct注解相反。

在同一类中同时使用@PostConstruct和@PreDestroy来执行程序的初始化和销毁操作:

public class DestructiveBean{
    private File file;
    private String filePath;
    @PostConstruct
    public void afterPropertiesSet() throws Exception{
        System.out.println("Initializing Bean");
        if(filePath == null){
            throw new IllegalArgumentException("你必须定义文件目录属性的值:"+DestructiveBean.class);
        }
        this.file=new File(filePath);
        this.file.createNewFile();
        System.out.println("文件存在:"+file.exists());
    }
    @PreDestroy
    public void destroy(){
        System.out.println("Destroying Bean");
        if(!file.delete()){
            System.out.println("删除文件失败!");
        }
        System.out.println("文件存在:"+file.exists());
    }
    
    public void setFilePath(String filePath){
        this.filePath=filePath;
    }
    public static void main(String... args) throws Exception{
        GenericXmlApplicationContext ctx=new GenericXmlApplicationContext();
        ctx.load("classpath:spring/app-context.xml");
        ctx.refresh();
        
        DestructiveBean bean=(DestructiveBean)ctx.getBean("destructiveBean");
        System.out.println("调用bean销毁方法开始");
        ctx.destroy();
        System.out.println("调用bean销毁方法结束");
    }
   
}