将一个接口转换为客户端期望的另一个接口,适配器允许接口不兼容的类一起工作。
适配器模式允许在适配器中包装一个原本不兼容的对象,以使其与另一个类兼容。
通常用于使现有类在不修改其源代码的情况下与其他类一起使用。
在Spring Bean的生命周期中,有初始化方法和销毁之前执行的方法,销毁方法的注册执行就使用了适配器模式,众所周知,我们可以通过在xml中配置destroy-method
和实现DisposableBean
接口来完成配置,虽然这是两种完全不同的配置方式,但是Spring在设计的时候就将两种方式的配置最终都通过适配器的方式完成了整合,使得在IOC容器调用的时候完全无感,具体的看代码,项目源码:
//在容器中定义了一个Map保存所有实现DisposableBean的Bean
private Map disposableBeanMap = new HashMap<>();
//定义了适配器,显然这种方式是为了把xml配置的方式适配为DisposableBean的形式
//适配器内部定义了执行bean和具体的销毁方法
public class DisposableBeanAdapter implements DisposableBean {
private final Object bean;
private final String beanName;
private String destroyMethodName;
//构造方法中通过将BeanDefinition传入,获取到在xml中定义的destroy-method
//
public DisposableBeanAdapter(Object bean, String beanName, BeanDefinition beanDefinition) {
this.bean = bean;
this.beanName = beanName;
this.destroyMethodName = beanDefinition.getDestroyMethodName();
}
//在真正执行销毁逻辑时,判断持有的bean是否实现了DisposableBean,实现了就直接执行销毁方法
//否则就通过反射获取到destroyMethodName的方法,再执行,这样就实现了对两种方式的适配整合
@Override
public void destroy() throws Exception {
//实现接口(DisposableBean)的方式
if (bean instanceof DisposableBean) {
//执行销毁方法
((DisposableBean)bean).destroy();
}
//xml定义destroy-method方式
// !(bean instanceof DisposableBean) 防止二次执行销毁方法
if(StrUtil.isNotEmpty(destroyMethodName) && !(bean instanceof DisposableBean)){
Method destroyMethod = bean.getClass().getMethod(destroyMethodName);
if(destroyMethod == null){
throw new BeansException("未找到destroy method:" + destroyMethodName + ",beanName:" + beanName);
}
destroyMethod.invoke(bean);
}
}
}
//在使用的时候只需要将
if(bean instanceof DisposableBean || StrUtil.isNotEmpty(beanDefinition.getDestroyMethodName())){
registryDisposableBean(beanName,new DisposableBeanAdapter(bean , beanName , beanDefinition));
}