适配器模式
适配器模式是一种结构型设计模式, 它能使接口不兼容的对象能够相互合作。
适配器模式在 spring 源码中的应用:DisposableBeanAdapter
当 spring 容器启动时,会将所有 “DisposableBean” 添加到 disposableBeans 集合,可能有各种类,比如:
- 通过 @Bean 注入的实现了 close 方法的 UserService、
- 实现了 DisposableBean 接口,重写了 destory() 方法的类、
- 实现了 AutoCloseable 接口的类
- ……
关闭容器销毁单例 Bean 时,Spring 会找出实现了 “DisposableBean”,并执行对应的方法,进行 Bean 的销毁。这就需要进行很多判断:
- 如果是实现了 close() 方法的 DisposableBean,就调用 close() 方法销毁
- 如果是实现了 DisposableBean 的类,就调用 destory() 方法销毁
- 如果是… 就…
所以对外提供了一个适配器:DisposableBeanAdapter,将这些判断封装起来,外部使用者直接调用 DisposableBeanAdapter 的 destory() 方法即可,在里面会判断到底去调用 close 方法,还是 destroy 方法,或者其他。这就是适配器模式。
DisposableBeanAdapter#destroy
以下 spring 代码版本为 spring-framework-5.2.4
org.springframework.beans.factory.support.DisposableBeanAdapter#destroy
@Override
public void destroy() {
// bean
if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
// 执行 @PreDestroy 注解指定的销毁方法
for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
processor.postProcessBeforeDestruction(this.bean, this.beanName);
}
}
// 如果当前类实现了 DisposableBean
if (this.invokeDisposableBean) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking destroy() on bean with name '" + this.beanName + "'");
}
try {
if (System.getSecurityManager() != null) {
// 执行 DisposableBean 的 destroy 方法
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((DisposableBean) this.bean).destroy();
return null;
}, this.acc);
}
else {
((DisposableBean) this.bean).destroy();
}
}
catch (Throwable ex) {
String msg = "Invocation of destroy method failed on bean with name '" + this.beanName + "'";
if (logger.isDebugEnabled()) {
logger.warn(msg, ex);
}
else {
logger.warn(msg + ": " + ex);
}
}
}
// 如果指定了 destroyMethod,则执行
if (this.destroyMethod != null) {
invokeCustomDestroyMethod(this.destroyMethod);
}
else if (this.destroyMethodName != null) {
Method methodToInvoke = determineDestroyMethod(this.destroyMethodName);
if (methodToInvoke != null) {
invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke));
}
}
}
Bean 的生命周期
- 加载类
- 实例化前
- 实例化
- BeanDefinition 后置处理
- CommonAnnotationBeanPostProcessor:找 @PostConstruct 和 @PreDestroy 修饰的方法
- 实例化后
- 填充属性
- 初始化前—BeanPostProcessor.postProcessBeforeInitialization
- (执行 @PostConstruct 定义的方法)
- 初始化:创建 Bean
- 初始化后—BeanPostProcessor
- 判断 Bean 是否是 DisposableBean,如果是则加入到 disposableBeans<beanName, new
DisposableBeanAdapter(bean)> 中- 是否实现了 DisposableBean 接口
- 实现了AutoCloseable 接口
- BeanDefinition 中定义了 destroyMethodName
- 如果 destroy-method 为默认值则看是否定义了 close 和 shutdown 方法
- 类中是否存在@PreDestroy 注解的方法
- 判断 Bean 是否是 DisposableBean,如果是则加入到 disposableBeans<beanName, new
- Bean 的销毁
- 当调用 applicationContext.close() 时,执行 disposableBeans
中所有的 DisposableBeanAdapter 对应的销毁方法 destroy。(DisposableBeanAdapter
实现了 DisposableBean 接口,重写了 destroy 方法逻辑如下)- 执行 @PreDestroy 修饰的方法。
- 当前类实现了 DisposableBean 接口,则强转为 DisposableBean 类型,然后执行 destroy 方法。
- 如果指定了 destroy-method,则执行。(destroy-method 有优先级如下)
- 实现了 AutoCloseable 接口,就把它的 close 方法作为 destroy-method。
- 如果指定了 destroyMethodName,把指定的作为 destroy-method。
- 如果指定的 destroyMethodName 为默认值,如果定义了 close 方法,把 close 方法作为 destroy-method。
- 如果没有 close,看是否有 shutdown 方法,如果有,把它作为 destroy-method。
- 当调用 applicationContext.close() 时,执行 disposableBeans
适配器模式在 springmvc 源码中的应用:HeandlerAdapter
springmvc 支持多种类型的处理器
处理器指的是:接收用户请求,并进行处理的类或方法。
- 自定义类加上 @Controller 注解,自定义方法加上 @RequestMapping 注解。
- 自定义类实现 Servlet 接口(一般都直接实现 HttpServlet 接口)。
- 自定义类实现 Controller 接口,重写 handleRequest 方法。
- 自定义类实现 HttpRequestHandler 接口,重写 handleRequest 方法。
针对以上四种不同类型的处理器,需要调用不同的方法进行请求的处理:
- 执行 @RequestMapping(url) 修饰的方法。
- 调用 service() 方法。
- 强转为 Controller 类型,然后调用 handleRequest 方法。
- 强转为 HttpRequestHandler 类型,然后调用 handleRequest 方法。
所以提供了对应的适配器:
- RequestMappingHandlerAdapter:适配注解处理器
- SimpleServletHandlerAdapter:适配 Servlet 处理器
- SimpleControllerHandlerAdapter:适配 Controller 处理器
- HttpRerquestHandlerAdapter:适配 HttpRequestHandler 处理器
外部使用者遍历所有适配器,看当前是配置是否支持处理器,如果支持,则直接调用适配器的 handle 方法进行请求的处理。
当用户在浏览器地址栏输入一个请求后,会由 DispatcherServlet 的 service 方法进行处理,最终会调用到 doDispatch 方法:
以下 springmvc 代码版本为 spring-webmvc-5.2.7.RELEASE
org.springframework.web.servlet.DispatcherServlet#doDispatch
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
try {
ModelAndView mv = null;
Exception dispatchException = null;
try {
processedRequest = checkMultipart(request);
multipartRequestParsed = (processedRequest != request);
// Determine handler for the current request.
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null) {
noHandlerFound(processedRequest, response);
return;
}
// 获取处理器对应的适配器
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// Process last-modified header, if supported by the handler.
String method = request.getMethod();
boolean isGet = "GET".equals(method);
if (isGet || "HEAD".equals(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
return;
}
}
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
// 执行适配器的 handle 方法
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
// 省略部分代码......
org.springframework.web.servlet.DispatcherServlet#getHandlerAdapter
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
if (this.handlerAdapters != null) {
// 遍历所有适配器,找到支持该处理器的适配器
for (HandlerAdapter adapter : this.handlerAdapters) {
if (adapter.supports(handler)) {
return adapter;
}
}
}
throw new ServletException("No adapter for handler [" + handler +
"]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
}
适配器 SimpleControllerHandlerAdapter 代码示例
// 适配 Controller 处理器
public class SimpleControllerHandlerAdapter implements HandlerAdapter {
@Override
public boolean supports(Object handler) {
// 如果处理器是 Controller 类型,则支持该处理器
return (handler instanceof Controller);
}
@Override
@Nullable
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// 强转为 Controller,然后执行 handleRequest 方法
return ((Controller) handler).handleRequest(request, response);
}
@Override
public long getLastModified(HttpServletRequest request, Object handler) {
if (handler instanceof LastModified) {
return ((LastModified) handler).getLastModified(request);
}
return -1L;
}
}