适配器模式
适配器模式是一种结构型设计模式, 它能使接口不兼容的对象能够相互合作。
适配器模式在 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
org.springframework.beans.factory.support.DisposableBeanAdapter#destroy
@Override
public void destroy() {// beanif (!CollectionUtils.isEmpty(this.beanPostProcessors)) {// 执行 @PreDestroy 注解指定的销毁方法for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {processor.postProcessBeforeDestruction(this.bean, this.beanName);}}// 如果当前类实现了 DisposableBeanif (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 方法:
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 {@Overridepublic boolean supports(Object handler) { // 如果处理器是 Controller 类型,则支持该处理器return (handler instanceof Controller);}@Override@Nullablepublic ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {// 强转为 Controller,然后执行 handleRequest 方法return ((Controller) handler).handleRequest(request, response);}@Overridepublic long getLastModified(HttpServletRequest request, Object handler) {if (handler instanceof LastModified) {return ((LastModified) handler).getLastModified(request);}return -1L;}
}
本文链接:https://my.lmcjl.com/post/1340.html
4 评论