体育资讯网

您现在的位置是:首页 > 分类10 > 正文

分类10

spring源码分析(spring源码分析和总结简书)

hacker2023-02-24 23:30:22分类10142
本文目录一览:1、Spring源码解析之BeanPostProcessor2、

本文目录一览:

Spring源码解析之BeanPostProcessor

源码版本4.3.10-RELEASE

我们都知道,实现BeanPostProcessor接口,在bean初始化前后,spring会分别回调postProcessBeforeInitialization和postProcessAfterInitialization。目的是保留扩展接口修改bean的属性,甚至可以替换bean :

那spring究竟是如何做到的呢?我们一起来看看吧。

从spring容器启动开始看起:new ClassPathXmlApplicationContext("classpath:application.xml");

看AbstractApplicationContext.refresh();方法。

1、在 obtainFreshBeanFactory 里会解析xml配置,把所有bean注册到beanDefinitionNames,包含我们自定义的BeanPostProcessor。

2、先看 prepareBeanFactory:

这里添加了三个spring默认的BeanPostProcessor。

3、再看 postProcessBeanFactory:

这个是AbstractRefreshableWebApplicationContext(AbstractApplicationContext的子类)的方法,它同样也添加了一个默认的BeanPostProcessor。

4、接着看 invokeBeanFactoryPostProcessors:

这里设置一下TempClassLoader,并重新添加LoadTimeWeaverAwareProcessor,后面会单独开个文章分析内建的这些类的作用。

5、继续看 registerBeanPostProcessors:

registerBeanPostProcessors 会继续添加一个内建Processor:

然后从容器取出所有Processor(包括我们自定义的)进行排序,再添加回beanFactory(先移除后添加),最后重新把ApplicationListenerDetector添加到末尾:

6、最后看一下调用过程吧, finishBeanFactoryInitialization:

在这里beanFactory.preInstantiateSingletons();(在子类DefaultListableBeanFactory里实现)

再到其父类的AbstractBeanFactory.doGetBean-AbstractAutowireCapableBeanFactory. createBean -resolveBeforeInstantiation

就是在这里回调接口的2个方法,其实这里允许直接返回bean了。继续看resolveBeforeInstantiation后面的 doCreateBean ,同样会在applyMergedBeanDefinitionPostProcessors里回调,不过只是针对某一类型的Processor:

doCreateBean 的另一个方法initializeBean里也会做回调:

执行完 createBean 后,再回到其父类的AbstractBeanFactory. getObjectForBeanInstance (该方法就是处理FactoryBean类型的bean)

调到其父类FactoryBeanRegistrySupport.getObjectFromFactoryBean

到AbstractAutowireCapableBeanFactory.postProcessObjectFromFactoryBean(在doGetObjectFromFactoryBean后执行,该方法正是初始化bean的过程)-applyBeanPostProcessorsAfterInitialization

至此,完.

Spring Tx源码解析(二)

   上一篇 我们介绍了 spring-tx 中的底层抽象,本篇我们一起来看看围绕这些抽象概念 spring-tx 是如何打造出声明式事务的吧。笼统的说, spring-tx-5.2.6.RELEASE 的实现主要分为两个部分:

这两部分彼此独立又相互成就,并且每个部分都有着大量的源码支撑,本篇我们先来分析 spring-tx 中的AOP部分吧。

   EnableTransactionManagement 注解想必大家都很熟悉了,它是启用 Spring 中注释驱动的事务管理功能的关键。

EnableTransactionManagement 注解的主要作用是向容器中导入 TransactionManagementConfigurationSelector ,至于注解中定义的几个属性在 Spring AOP源码解析 中有过详细分析,这里就不再赘述了。

由于我们并没有使用 AspectJ ,因此导入容器的自然是 ProxyTransactionManagementConfiguration 这个配置类。

  这个配置类的核心是向容器中导入一个类型为 BeanFactoryTransactionAttributeSourceAdvisor 的Bean。这是一个 PointcutAdvisor ,它的 Pointcut 是 TransactionAttributeSourcePointcut , Advice 是 TransactionInterceptor 。

   TransactionAttributeSourcePointcut 利用 TransactionAttributeSource 解析 @Transactional 注解的能力来选取标注了 @Transactional 注解的方法,而 TransactionInterceptor 则根据应用提出的需求(来自对 @Transactional 注解的解析)将方法增强为事务方法,因此 BeanFactoryTransactionAttributeSourceAdvisor 可以识别出那些标注了 @Transactional 注解的方法,为它们应用上事务相关功能。

   TransactionInterceptor 能对方法进行增强,但是它却不知道该如何增强,比如是为方法新开一个独立事务还是沿用已有的事务?什么情况下需要回滚,什么情况下不需要?必须有一个『人』告诉它该如何增强,这个『人』便是 TransactionAttributeSource 。

   @Transactional 注解定义了事务的基础信息,它表达了应用程序期望的事务形态。 TransactionAttributeSource 的主要作用就是解析 @Transactional 注解,提取其属性,包装成 TransactionAttribute ,这样 TransactionInterceptor 的增强便有了依据。

前面我们已经见过, spring-tx 使用 AnnotationTransactionAttributeSource 来做具体的解析工作,其父类 AbstractFallbackTransactionAttributeSource 定义了解析 TransactionAttribute 的优先级,核心方法是 computeTransactionAttribute(...) 。

AnnotationTransactionAttributeSource 默认只解析 public 修饰的方法,这也是导致 @Transactional 注解失效的一个原因,除此之外它还实现了父类中定义的两个模板方法:

同时为了支持 EJB 中定义的 javax.ejb.TransactionAttribute 和 JTA 中定义的 javax.transaction.Transactional 注解, AnnotationTransactionAttributeSource 选择将实际的提取工作代理给 TransactionAnnotationParser 。Spring 提供的 @Transactional 注解由 SpringTransactionAnnotationParser 进行解析。

SpringTransactionAnnotationParser 的源码还是很简单的,它使用 AnnotatedElementUtils 工具类定义的 find 语义来获取 @Transactional 注解信息。 RuleBasedTransactionAttribute 中 rollbackOn(...) 的实现还是挺有意思的,其它的都平平无奇。

RollbackRuleAttribute 是用来确定在发生特定类型的异常(或其子类)时是否应该回滚,而 NoRollbackRuleAttribute 继承自 RollbackRuleAttribute ,但表达的是相反的含义。 RollbackRuleAttribute 持有某个异常的名称,通过 getDepth(Throwable ex) 算法来计算指定的 Throwable 和持有的异常在继承链上的距离。

  程序猿只有在拿到需求以后才能开工, TransactionInterceptor 也一样,有了 TransactionAttributeSource 之后就可以有依据的增强了。观察类图, TransactionInterceptor 实现了 MethodInterceptor 接口,那么自然要实现接口中的方法:

可以看到, TransactionInterceptor 本身是没有实现任何逻辑的,它更像一个适配器。这样分层以后, TransactionAspectSupport 理论上就可以支持任意类型的 Advice 而不只是 MethodInterceptor 。实现上 TransactionAspectSupport 确实也考虑了这一点,我们马上就会看到。

invokeWithinTransaction(...) 的流程还是非常清晰的:

第一步前文已经分析过了,我们来看第二步。

TransactionInfo 是一个非常简单的类,我们就不费什么笔墨去分析它了。接着看第三步,这一步涉及到两个不同的操作——提交或回滚。

至此, TransactionInterceptor 于我们而言已经没有任何秘密了。

  本篇我们一起分析了 spring-tx 是如何通过 spring-aop 的拦截器将普通方法增强为事务方法的,下篇就该说道说道 PlatformTransactionManager 抽象下的事务管理细节啦,我们下篇再见~~

详解Spring mvc工作原理及源码分析

Model 模型层 (javaBean组件 = 领域模型(javaBean) + 业务层 + 持久层)

View 视图层( html、jsp…)

Controller 控制层(委托模型层进行数据处理)

springmvc是一个web层mvc框架,类似struts2。

springmvc是spring的部分,其实就是spring在原有基础上,又提供了web应用的mvc模块。

实现机制:

struts2是基于过滤器实现的。

springmvc是基于servlet实现的。

运行速度:

因为过滤器底层是servlet,所以springmvc的运行速度会稍微比structs2快。

struts2是多例的

springmvc单例的

参数封装:

struts2参数封装是基于属性进行封装。

springmvc是基于方法封装。颗粒度更细。

⑴ 用户发送请求至DispatcherServlet。

⑵ DispatcherServlet收到请求调用HandlerMapping查询具体的Handler。

⑶ HandlerMapping找到具体的处理器(具体配置的是哪个处理器的实现类),生成处理器对象及处理器拦截器(HandlerExcutorChain包含了Handler以及拦截器集合)返回给DispatcherServlet。

⑷ DispatcherServlet接收到HandlerMapping返回的HandlerExcutorChain后,调用HandlerAdapter请求执行具体的Handler(Controller)。

⑸ HandlerAdapter经过适配调用具体的Handler(Controller即后端控制器)。

⑹ Controller执行完成返回ModelAndView(其中包含逻辑视图和数据)给HandlerAdaptor。

⑺ HandlerAdaptor再将ModelAndView返回给DispatcherServlet。

⑻ DispatcherServlet请求视图解析器ViewReslover解析ModelAndView。

⑼ ViewReslover解析后返回具体View(物理视图)到DispatcherServlet。

⑽ DispatcherServlet请求渲染视图(即将模型数据填充至视图中) 根据View进行渲染视图。

⑾ 将渲染后的视图返回给DispatcherServlet。

⑿ DispatcherServlet将响应结果返回给用户。

(1)前端控制器DispatcherServlet(配置即可)

功能:中央处理器,接收请求,自己不做任何处理,而是将请求发送给其他组件进行处理。DispatcherServlet 是整个流程的控制中心。

(2)处理器映射器HandlerMapping(配置即可)

功能:根据DispatcherServlet发送的url请求路径查找Handler

常见的处理器映射器:BeanNameUrlHandlerMapping,SimpleUrlHandlerMapping,

ControllerClassNameHandlerMapping,DefaultAnnotationHandlerMapping(不建议使用)

(3)处理器适配器HandlerAdapter(配置即可)

功能:按照特定规则(HandlerAdapter要求的规则)去执行Handler。

通过HandlerAdapter对处理器进行执行,这是适配器模式的应用,通过扩展多个适配器对更多类型的处理器进行执行。

常见的处理器适配器:HttpRequestHandlerAdapter,SimpleControllerHandlerAdapter,AnnotationMethodHandlerAdapter

(4)处理器Handler即Controller(程序猿编写)

功能:编写Handler时按照HandlerAdapter的要求去做,这样适配器才可以去正确执行Handler。

(5)视图解析器ViewReslover(配置即可)

功能:进行视图解析,根据逻辑视图名解析成真正的视图。

ViewResolver负责将处理结果生成View视图,ViewResolver首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成View视图对象,最后对View进行渲染将处理结果通过页面展示给用户。

springmvc框架提供了多种View视图类型,如:jstlView、freemarkerView、pdfView...

(6)视图View(程序猿编写)

View是一个接口,实现类支持不同的View类型(jsp、freemarker、pdf...)

引入相关依赖:spring的基本包、springmvc需要的spring-webmvc,日志相关的slf4j-log4j12,jsp相关的jstl、servlet-api、jsp-api。

因为DispatcherServlet本身就是一个Servlet,所以需要在web.xml配置。

一、使用默认加载springmvc配置文件的方式,必须按照以下规范:

①命名规则:-servlet.xml ==== springmvc-servlet.xml

②路径规则:-servlet.xml必须放在WEB-INF下边

二、如果要不按照默认加载位置,则需要在web.xml中通过标签来指定springmvc配置文件的加载路径,如上图所示。

将自定义的 Controller 处理器配置到 spring 容器中交由 spring 容器来管理,因为这里的 springmvc.xml 配置文件中处理器映射器配置的是 BeanNameUrlHandlerMapping ,根据名字可知这个处理器映射器是根据 bean (自定义Controller) 的 name 属性值url去寻找执行类 Handler(Controller) , 所以bean的name属性值即是要和用户发送的请求路径匹配的 url 。

根据视图解析路径:WEB-INF/jsps/index.jsp

功能:根据bean(自定义Controller)的name属性的url去寻找执行类Controller。

功能:自定义的处理器(Controller)实现了Controller接口时,适配器就会执行Controller的具体方法。

SimpleControllerHandlerAdapter会自动判断自定义的处理器(Controller)是否实现了Controller接口,如果是,它将会自动调用处理器的handleRequest方法。

Controller接口中有一个方法叫handleRequest,也就是处理器方法。

因此,自定义的Controller要想被调用就必须实现Controller接口,重写Controller接口中的处理器方法。

发表评论

评论列表

  • 酒奴寰鸾(2023-02-25 01:00:20)回复取消回复

    troller)是否实现了Controller接口,如果是,它将会自动调用处理器的handleRequest方法。 Controller接口中有一个方法叫handleRequest,也就是处理器方法。 因此,自定义的C

  • 萌懂长野(2023-02-25 09:59:24)回复取消回复

    和 JTA 中定义的 javax.transaction.Transactional 注解, AnnotationTransactionAttributeSource 选择将实际的提取工作代理给 TransactionAn