1. 操作bean的相关接口
1.1 InitializingBean接口和DisposableBean接口
InitializingBean是由需要在BeanFactory设置所有属性后做出反应的 bean 实现的接口:例如,执行自定义初始化,或仅检查是否已设置所有必需属性。其afterPropertiesSet()方法在设置所有 bean 属性并满足BeanFactoryAware , ApplicationContextAware等之后,由包含的BeanFactory调用。
DisposableBean是由想要在销毁时释放资源的 bean 实现的接口。 BeanFactory将在单独销毁作用域 bean 时调用 destroy 方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| @Component public class User implements InitializingBean, DisposableBean { private String id; private String name;
public String getId() { return id; }
public void setId(String id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
@Override public String toString() { return "User{" + "id='" + id + '\'' + ", name='" + name + '\'' + '}'; }
@Override public void afterPropertiesSet() throws Exception { this.id = "123"; this.name = "zhangsan"; }
@Override public void destroy() throws Exception { this.id = null; this.name = null; } }
|
以上代码在Spring的ApplicationContext运行之后容器中的User的bean对象的id和name会被初始化并赋值,销毁时id和name会被置空。
1 2 3 4 5 6 7 8 9 10 11
| @SpringBootApplication public class TestApplication { public static void main(String[] args) { ConfigurableApplicationContext run = SpringApplication.run(TestApplication.class, args); User bean = run.getBean(User.class); System.out.println(bean); ConfigurableListableBeanFactory beanFactory = run.getBeanFactory(); beanFactory.destroyBean(bean); System.out.println(bean); } }
|
主程序运行打印结果:
1 2
| User{id='123', name='zhangsan'} User{id='null', name='null'}
|
1.2 BeanPostProcessor接口
BeanPostProcessor接口提供了两个方法,分别是postProcessBeforeInitialization()和postProcessAfterInitialization(),分别在bean的初始化回调(如 InitializingBean 的afterPropertiesSet或自定义初始化方法)之前和初始化回调(如 InitializingBean 的afterPropertiesSet或自定义初始化方法)之后调用。
ApplicationContext可以在其 bean 定义中自动检测BeanPostProcessor bean,并将这些后处理器应用于随后创建的任何 bean。 普通的BeanFactory允许以编程方式注册后处理器,将它们应用于通过 bean 工厂创建的所有 bean。
现在新建一个类实现BeanPostProcessor接口,并对User类进行处理:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| @Component public class TestPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof User) { ((User) bean).setId("321"); ((User) bean).setName("lisi"); System.out.println("postProcessBeforeInitialization: " + bean); } return bean; }
@Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof User) { ((User) bean).setId("000"); ((User) bean).setName("wangwu"); System.out.println("postProcessAfterInitialization: " + bean); } return bean; } }
|
主程序运行打印结果:
1 2 3 4
| postProcessBeforeInitialization: User{id='321', name='lisi'} postProcessAfterInitialization: User{id='000', name='wangwu'} User{id='000', name='wangwu'} User{id='null', name='null'}
|
可以看出postProcessBeforeInitialization()方法在afterPropertiesSet()之前调用,而postProcessAfterInitialization()在afterPropertiesSet()之后调用,最终bean的name的值变成了wangwu
。
1.3 Aware接口
实现Aware接口,能获取增强方法,而处理Aware接口方法的就是上面的BeanPostProcessor接口。
下面以BeanNameAware接口为例,让User实现BeanNameAware接口:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| @Component public class User implements InitializingBean, DisposableBean, BeanNameAware { private String id; private String name;
public String getId() { return id; }
public void setId(String id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
@Override public String toString() { return "User{" + "id='" + id + '\'' + ", name='" + name + '\'' + '}'; }
@Override public void afterPropertiesSet() throws Exception { this.id = "123"; this.name = "zhangsan"; }
@Override public void destroy() throws Exception { this.id = null; this.name = null; }
@Override public void setBeanName(String name) { this.name = name; System.out.println("setBeanName: " + this); } }
|
主程序运行打印结果:
1 2 3 4 5
| setBeanName: User{id='null', name='user'} postProcessBeforeInitialization: User{id='321', name='lisi'} postProcessAfterInitialization: User{id='000', name='wangwu'} User{id='000', name='wangwu'} User{id='null', name='null'}
|
2. SpringMVC的相关接口
SpringMVC的核心组件是DispatcherServlet,DispatcherServlet下还驱动着9大策略组件,分别是:
1 2 3 4 5 6 7 8 9
| MultipartResolver //文件解析器 LocaleResolver //当前环境解析器 ThemeResolver //主题解析器 HandlerMapping //处理器的映射器 HandlerAdapter //处理器的适配器 HandlerExceptionResolver //处理器的异常解析器 RequestToViewNameTranslator //当前环境处理器 ViewResolver //视图解析器 FlashMapManager //参数传递管理器
|
最重要的两个接口是HandlerMapping和HandlerAdapter,一个用于扫描web请求的处理器,一个用于对DispatcherServlet接收到的请求进行处理,DispatcherServlet的获取到的参数仅仅是HttpServletRequest和HttpServletResponse
2.1 HandlerMapping接口
HandlerMapping的主要职责是根据HttpServletRequest请求找到适合的Handler,其中getHandler方法返回的是HandlerExecutionChain,该类包装了Handler处理器和HandlerInterceptor处理器拦截器。
HandlerMapping底下的抽象类AbstractHandlerMapping实现类分支有两个,一个是AbstractUrlHandlerMapping,最终映射到一个实例对象上;另一个是AbstractHandlerMethodMapping,最终映射到一个方法上。
getHandlerInternal()方法由子类实现。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| @Override @Nullable public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { Object handler = getHandlerInternal(request); if (handler == null) { handler = getDefaultHandler(); } if (handler == null) { return null; } if (handler instanceof String) { String handlerName = (String) handler; handler = obtainApplicationContext().getBean(handlerName); }
if (!ServletRequestPathUtils.hasCachedPath(request)) { initLookupPath(request); }
HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);
if (logger.isTraceEnabled()) { logger.trace("Mapped to " + handler); } else if (logger.isDebugEnabled() && !DispatcherType.ASYNC.equals(request.getDispatcherType())) { logger.debug("Mapped to " + executionChain.getHandler()); }
if (hasCorsConfigurationSource(handler) || CorsUtils.isPreFlightRequest(request)) { CorsConfiguration config = getCorsConfiguration(handler, request); if (getCorsConfigurationSource() != null) { CorsConfiguration globalConfig = getCorsConfigurationSource().getCorsConfiguration(request); config = (globalConfig != null ? globalConfig.combine(config) : config); } if (config != null) { config.validateAllowCredentials(); } executionChain = getCorsHandlerExecutionChain(request, executionChain, config); }
return executionChain; }
|
2.2 HandlerAdapter接口
HandlerAdapter的主要职责是根据匹配到的Handler处理具体的业务请求,返回模型视图。其核心实现类RequestMappingHandlerAdapter的handleInternal方法实现了改功能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
| @Override protected ModelAndView handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
ModelAndView mav; checkRequest(request);
if (this.synchronizeOnSession) { HttpSession session = request.getSession(false); if (session != null) { Object mutex = WebUtils.getSessionMutex(session); synchronized (mutex) { mav = invokeHandlerMethod(request, response, handlerMethod); } } else { mav = invokeHandlerMethod(request, response, handlerMethod); } } else { mav = invokeHandlerMethod(request, response, handlerMethod); }
if (!response.containsHeader(HEADER_CACHE_CONTROL)) { if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) { applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers); } else { prepareResponse(response); } }
return mav; }
@Nullable protected ModelAndView invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
ServletWebRequest webRequest = new ServletWebRequest(request, response); try { WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod); ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);
ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod); if (this.argumentResolvers != null) { invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers); } if (this.returnValueHandlers != null) { invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers); } invocableMethod.setDataBinderFactory(binderFactory); invocableMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer);
ModelAndViewContainer mavContainer = new ModelAndViewContainer(); mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request)); modelFactory.initModel(webRequest, mavContainer, invocableMethod); mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect);
AsyncWebRequest asyncWebRequest = WebAsyncUtils.createAsyncWebRequest(request, response); asyncWebRequest.setTimeout(this.asyncRequestTimeout);
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); asyncManager.setTaskExecutor(this.taskExecutor); asyncManager.setAsyncWebRequest(asyncWebRequest); asyncManager.registerCallableInterceptors(this.callableInterceptors); asyncManager.registerDeferredResultInterceptors(this.deferredResultInterceptors);
if (asyncManager.hasConcurrentResult()) { Object result = asyncManager.getConcurrentResult(); mavContainer = (ModelAndViewContainer) asyncManager.getConcurrentResultContext()[0]; asyncManager.clearConcurrentResult(); LogFormatUtils.traceDebug(logger, traceOn -> { String formatted = LogFormatUtils.formatValue(result, !traceOn); return "Resume with async result [" + formatted + "]"; }); invocableMethod = invocableMethod.wrapConcurrentResult(result); }
invocableMethod.invokeAndHandle(webRequest, mavContainer); if (asyncManager.isConcurrentHandlingStarted()) { return null; }
return getModelAndView(mavContainer, modelFactory, webRequest); } finally { webRequest.requestCompleted(); } }
|