应用场景
在实际项目中,某些时候我们需要在程序stop,对象销毁的的时候做一些销毁工作。例如在我的项目中,有大量的使用redis分布式锁的场景。集群情况下,某一个锁的过期时间会很长。如果在一个实例获取到锁之后还没有释放锁就重启或者停止了。就会导致在这个实例重启之后和其他实例在锁没有过期之前无法获取这个锁。
所以我需要在程序停止之后释放掉哪些还没有释放的redis锁。
实现
方法一
使用@Bean的自定义销毁方法
@Bean中有一个destroyMethod()实现可以在spring销毁对象的时候调用。
public class MyDisposableBean{public Map<String, String> map = new HashMap<>();private void init(){System.out.println("MyDisposableBean自定义初始化方法");}private void destroyMethod(){System.out.println("自定义销毁方法,MyDisposableBean对象销毁");}
}
@Configuration
public class BeanConfigurer {@Bean(name = "MyDisposableBean", initMethod = "init", destroyMethod = "destroyMethod")public MyDisposableBean getMyDisposableBean(){System.out.println("MyDisposableBean构造方法");return new MyDisposableBean();}
}
这样我们在从spring ioc获取的对象并使用之后,在程序停止前就会调用destroyMethod 指定的方法。
测试启动后停止项目,日志如下:
MyDisposableBean构造方法
MyDisposableBean自定义初始化方法
Disconnected from the target VM, address: '127.0.0.1:60130', transport: 'socket'
自定义销毁方法,MyDisposableBean对象销毁
方法二
实现 DisposableBean 接口,实现其 destroy方法。
public interface DisposableBean {/*** Invoked by the containing {@code BeanFactory} on destruction of a bean.* @throws Exception in case of shutdown errors. Exceptions will get logged* but not rethrown to allow other beans to release their resources as well.*/void destroy() throws Exception;}
public class MyDisposableBean implements DisposableBean {public Map<String, String> map = new HashMap<>();int i = 0;@Overridepublic void destroy() throws Exception {System.out.println("MyDisposableBean对象销毁");}}
可以使用@Component自动装配的spring ioc,也可以使用@Bean方式手动加载到spring ioc容器。
启动和停止测试结果如下:
Disconnected from the target VM, address: '127.0.0.1:60681', transport: 'socket'
MyDisposableBean对象销毁
利用以上两个方法就能实现在对象销毁之前做一些操作