spring源码阅段笔记

来源:互联网 发布:华为云计算认证 编辑:程序博客网 时间:2024/06/06 01:15

一:IOC容器创建和注入依赖,通过反射。

二.IOC容器在web应用中的启动流程

先了解web应用在tomcat中的启动流程


spring mvc只需在应用启动的过程中执行初始化操作,创建好容器并通过spring ioc根据配置文件创建好对象


1.在web.xml中配置ContextLoaderListener事件监听器

  1. //这里对根上下文进行初始化。  
  2. public void contextInitialized(ServletContextEvent event) {  
  3.     //这里创建需要的ContextLoader  
  4.     this.contextLoader = createContextLoader();  
  5.     //这里使用ContextLoader对根上下文进行载入和初始化  
  6.     this.contextLoader.initWebApplicationContext(event.getServletContext());  
  7. }  
在监听器的contextInitialized方法中的initWebApplicationContext完成根上下文WebApplicationContext的创建,并将其注册到ServeletContext中wac.setServletContext(servletContext),这个根上下文会被以后的DispatcherServlet初始化自己的时候作为自己ApplicationContext的父上下文。

2.完成对ContextLoaderListener的初始化以后, Tomcat开始初始化DispatchServlet,在servlet生命周期中的init阶段,新建一个ApplicationContext并以根上下文为父,注册到ServletCintext中.初始化后:

  1. protected void initFrameworkServlet() throws ServletException, BeansException {  
  2.     initMultipartResolver();  
  3.     initLocaleResolver();  
  4.     initThemeResolver();  
  5.     initHandlerMappings();  
  6.     initHandlerAdapters();  
  7.     initHandlerExceptionResolvers();  
  8.     initRequestToViewNameTranslator();  
  9.     initViewResolvers();  
  10. }  

完成springmvc各个元素的建立

三:spring mvc框架的实现:

DispatcherServlet工作流程:


以springmvc中DispatchServlet中的init方法入手,以initHandlerMappings()举例

  1. private void initHandlerMappings() throws BeansException {  
  2.     if (this.detectAllHandlerMappings) {  
  3.          // 这里找到所有在上下文中定义的HandlerMapping,同时把他们排序  
  4.          // 因为在同一个上下文中可以有不止一个handlerMapping,所以我们把他们都载入到一个链里进行维护和管理  
  5.         Map matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(  
  6.                 getWebApplicationContext(), HandlerMapping.classtruefalse);  
  7.         if (!matchingBeans.isEmpty()) {  
  8.             this.handlerMappings = new ArrayList(matchingBeans.values());  
  9.             // 这里通过order属性来对handlerMapping来在list中排序  
  10.             Collections.sort(this.handlerMappings, new OrderComparator());  
  11.         }  
  12.     }  
  13.     else {  
  14.         try {  
  15.             Object hm = getWebApplicationContext().getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class);  
  16.             this.handlerMappings = Collections.singletonList(hm);  
  17.         }  
  18.         catch (NoSuchBeanDefinitionException ex) {  
  19.             // Ignore, we'll add a default HandlerMapping later.  
  20.         }  
  21.     }  
  22.   
  23.     //如果在上下文中没有定义的话,那么我们使用默认的BeanNameUrlHandlerMapping  
  24.     if (this.handlerMappings == null) {  
  25.         this.handlerMappings = getDefaultStrategies(HandlerMapping.class);  
  26.     ........  
  27.     }  
  28. }  
这里要注意handlerMappings是一系列handlerMapping的集合,比如就包括SimpleUrlHandlerMaaping,从handlerMappings中就可以根据请求获得相应的HandlerExecutionChain

  1. public interface HandlerMapping {  
  2.   public static final String PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE =  
  3.                     Conventions.getQualifiedAttributeName(HandlerMapping.class"pathWithinHandlerMapping");  
  4.       //实际上维护一个HandlerExecutionChain,这是典型的Command的模式的使用,这个执行链里面维护handler和拦截器  
  5.     HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;  
  6. }  
  1. public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {  
  2.     //这里根据request中的参数得到其对应的handler,具体处理在AbstractUrlHandlerMapping中  
  3.     Object handler = getHandlerInternal(request);  
  4.     //如果找不到对应的,就使用缺省的handler  
  5.     if (handler == null) {  
  6.         handler = this.defaultHandler;  
  7.     }  
  8.     //如果缺省的也没有,那就没办法了  
  9.     if (handler == null) {  
  10.         return null;  
  11.     }  
  12.     // 如果handler不是一个具体的handler,那我们还要到上下文中取  
  13.     if (handler instanceof String) {  
  14.         String handlerName = (String) handler;  
  15.         handler = getApplicationContext().getBean(handlerName);  
  16.     }  
  17.     //生成一个HandlerExecutionChain,其中放了我们匹配上的handler和定义好的拦截器,就像我们在HandlerExecutionChain中看到的那样,它持有一个handler和一个拦截器组。  
  18.     return new HandlerExecutionChain(handler, this.adaptedInterceptors);  
  19. }  
  1. protected Object getHandlerInternal(HttpServletRequest request) throws Exception {  
  2.     //这里的HTTP Request传进来的参数进行分析,得到具体的路径信息。  
  3.     String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);  
  4.     .......//下面是根据请求信息的查找  
  5.     return lookupHandler(lookupPath, request);  
  6. }  
  7.   
  8. protected Object lookupHandler(String urlPath, HttpServletRequest request) {  
  9.     // 如果能够直接能在SimpleUrlHandlerMapping的映射表中找到,那最好。  
  10.     Object handler = this.handlerMap.get(urlPath);  
  11.     if (handler == null) {  
  12.         // 这里使用模式来对map中的所有handler进行匹配,调用了Jre中的Matcher类来完成匹配处理。  
  13.         String bestPathMatch = null;  
  14.         for (Iterator it = this.handlerMap.keySet().iterator(); it.hasNext();) {  
  15.             String registeredPath = (String) it.next();  
  16.             if (this.pathMatcher.match(registeredPath, urlPath) &&  
  17.                             (bestPathMatch == null || bestPathMatch.length() <= registeredPath.length())) {  
  18.                 //这里根据匹配路径找到最象的一个  
  19.                 handler = this.handlerMap.get(registeredPath);  
  20.                 bestPathMatch = registeredPath;  
  21.             }  
  22.         }  
  23.   
  24.         if (handler != null) {  
  25.             exposePathWithinMapping(this.pathMatcher.extractPathWithinPattern(bestPathMatch, urlPath), request);  
  26.         }  
  27.     }  
  28.     else {  
  29.         exposePathWithinMapping(urlPath, request);  
  30.     }  
  31.     //  
  32.     return handler;  
  33. }  

  1. public class HandlerExecutionChain {  
  2.   
  3.     private Object handler;  
  4.   
  5.     private HandlerInterceptor[] interceptors;  
  6.      
  7.     ........  
  8. }  
以上过程可以通过一个HandlerMapping对象找到请求所对应的HandlerExecutionChain,对请求进行处理。

 整个spring mvc的请求会被DispatchServlet拦截,进行分发,由doService调用doDispatch

  1. protected void doDispatch(final HttpServletRequest request, HttpServletResponse response) throws Exception {  
  2.     HttpServletRequest processedRequest = request;  
  3.     //这是从handlerMapping中得到的执行链  
  4.     HandlerExecutionChain mappedHandler = null;  
  5.     int interceptorIndex = -1;  
  6.      
  7.     ........  
  8.     try {  
  9.         //我们熟悉的ModelAndView开始出现了。  
  10.         ModelAndView mv = null;  
  11.         try {  
  12.             processedRequest = checkMultipart(request);  
  13.   
  14.             // 这是我们得到handler的过程  
  15.             mappedHandler = getHandler(processedRequest, false);  
  16.             if (mappedHandler == null || mappedHandler.getHandler() == null) {  
  17.                 noHandlerFound(processedRequest, response);  
  18.                 return;  
  19.             }  
  20.   
  21.             // 这里取出执行链中的Interceptor进行前处理  
  22.             if (mappedHandler.getInterceptors() != null) {  
  23.                 for (int i = 0; i < mappedHandler.getInterceptors().length; i++) {  
  24.                     HandlerInterceptor interceptor = mappedHandler.getInterceptors()[i];  
  25.                     if (!interceptor.preHandle(processedRequest, response, mappedHandler.getHandler())) {  
  26.                         triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);  
  27.                         return;  
  28.                     }  
  29.                     interceptorIndex = i;  
  30.                 }  
  31.             }  
  32.   
  33.             //在执行handler之前,用HandlerAdapter先检查一下handler的合法性:是不是按Spring的要求编写的。  
  34.             HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());  
  35.             mv = ha.handle(processedRequest, response, mappedHandler.getHandler());  
  36.   
  37.             // 这里取出执行链中的Interceptor进行后处理  
  38.             if (mappedHandler.getInterceptors() != null) {  
  39.                 for (int i = mappedHandler.getInterceptors().length - 1; i >= 0; i--) {  
  40.                     HandlerInterceptor interceptor = mappedHandler.getInterceptors()[i];  
  41.                     interceptor.postHandle(processedRequest, response, mappedHandler.getHandler(), mv);  
  42.                 }  
  43.             }  
  44.         }  
  45.          
  46.         ........  
  47.   
  48.         // Did the handler return a view to render?  
  49.         //这里对视图生成进行处理  
  50.         if (mv != null && !mv.wasCleared()) {  
  51.             render(mv, processedRequest, response);  
  52.         }  
  53.         .......  
  54. }  
这就是整个Spring Web MVC框架的大致流程,整个MVC流程由DispatcherServlet来控制。MVC的关键过程包括: 
配置到handler的映射关系和怎样根据请求参数得到对应的handler,在Spring中,这是由handlerMapping通过执行链来完成的,而具体的映射关系我们在bean定义文件中定义并在HandlerMapping载入上下文的时候就被配置好了。然后 DispatcherServlet调用HandlerMapping来得到对应的执行链,最后通过视图来展现模型数据,但我们要注意的是视图对象是在解析视图名的时候生成配置好的。这些作为核心类的HanderMapping,ViewResolver,View,Handler的紧密协作实现了MVC的功能。 

四:spring aop原理:

概念:

advice表示在连接点的行为,要做什么,包括前置增强,后置增强,环绕增强,抛出增强等;

pointcut切点表示要进行行为增强的目标

advisor:将advice和pointcut连接起来,Advisor的实现有:DefaultPointcutAdvisor他有两个属性advice和 pointcut来让我们配置advice和pointcut。 

代理对象的生成以ProxyFactoryBean为入口

  1. public Object getObject() throws BeansException {  
  2.     //这里初始化通知器链  
  3.     initializeAdvisorChain();  
  4.     if (isSingleton()) {  
  5.     //根据定义需要生成单件的Proxy  
  6.         return getSingletonInstance();  
  7.     }  
  8.     else {  
  9.     .......  
  10.         //这里根据定义需要生成Prototype类型的Proxy  
  11.         return newPrototypeInstance();  
  12.     }  
  13. }  

在getSingletonInstance方法钟调用getProxy()生成代理对象

  1. //使用createAopProxy放回的AopProxy来得到代理对象。  
  2. protected Object getProxy(AopProxy aopProxy) {  
  3.     return aopProxy.getProxy(this.beanClassLoader);  
  4. }  

AopProxy为一个接口,有两种实现,JdkDynamicAopProxy和ObjenesisCglibAopProxy分别以jdk动态代理技术和cglib动态代理技术生成代理对象

final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {@Overridepublic Object getProxy() {return getProxy(ClassUtils.getDefaultClassLoader());}@Overridepublic Object getProxy(@Nullable ClassLoader classLoader) {if (logger.isDebugEnabled()) {logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());}//jdk动态代理的类必须实现接口Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);}@Override@Nullablepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        //根据代理的方法和目标类获得advice增强    List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);// 根据反射进行advice调用和method调用   invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);// Proceed to the joinpoint through the interceptor chain.retVal = invocation.proceed();return retVal;}

五、spring事务

使用Spring管理事务有声明式和编程式两种方式,声明式事务处理通过AOP的实现把事物管理代码作为方面封装来横向插入到业务代码中,使得事务管理代码和业务代码解藕。在这种方式我们结合IoC容器和Spirng已有的FactoryBean来对事务管理进行属性配置,比如传播行为,隔离级别等。其中最简单的方式就是通过配置TransactionProxyFactoryBean来实现声明式事物; 

spring事务的实现最后还是委托给transactionManager来实现,比如在DataSourceTransactionManager:

  1. protected void doCommit(DefaultTransactionStatus status) {  
  2.     //这里得到存在TransactionInfo中已经创建好的事务  
  3.     DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();  
  4.   
  5.     //这里得到和事务绑定的数据库连接  
  6.     Connection con = txObject.getConnectionHolder().getConnection();  
  7.     ........  
  8.     try {  
  9.     //这里通过数据库连接来提交事务  
  10.         con.commit();  
  11.     }  
  12.    .......  
  13. }  
  14.   
  15. protected void doRollback(DefaultTransactionStatus status) {  
  16.     DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();  
  17.     Connection con = txObject.getConnectionHolder().getConnection();  
  18.     if (status.isDebug()) {  
  19.         logger.debug("Rolling back JDBC transaction on Connection [" + con + "]");  
  20.     }  
  21.     try {  
  22.     //这里通过数据库连接来回滚事务  
  23.         con.rollback();  
  24.     }  
  25.     catch (SQLException ex) {  
  26.         throw new TransactionSystemException("Could not roll back JDBC transaction", ex);  
  27.     }  
  28. }  





原创粉丝点击