当前位置: 首页 > news >正文

网络安全企业十大seo公司

网络安全企业,十大seo公司,国外最新设计产品,福田做网站福田网站建设福田建网站500前言 我们在日常开发的时候经常会用到组合注解,比如:EnableTransactionManagement Transactional、EnableAsync Async、EnableAspectJAutoProxy Aspect。今天我们就来抽丝剥茧,揭开Transactional注解的神秘面纱 EnableTransactionManagement注解的作用 当我们看到类似Ena…前言 我们在日常开发的时候经常会用到组合注解,比如:EnableTransactionManagement Transactional、EnableAsync Async、EnableAspectJAutoProxy Aspect。今天我们就来抽丝剥茧,揭开Transactional注解的神秘面纱 EnableTransactionManagement注解的作用 当我们看到类似Enablexxx这样的注解,一般源码中都会存在Import注解。Import注解在Spring的解析阶段有着十分重要的地位,是Spring的一个重要的扩展点。其注入的class一般继承ImportSelector或ImportBeanDefinitionRegistrar接口,作用分别如下 继承ImportSelector接口selectImports方法返回的类名数组会被解析成bean继承ImportBeanDefinitionRegistrar接口会在解析阶段执行registerBeanDefinitions方法 感兴趣的小伙伴可以阅读下方链接对应博文,该博文主要讲解了Spring对ComponentScan、Import、PropertySource、Bean等注解的解析流程,可以更好的帮助我们理解本篇文章Spring之ConfigurationClassPostProcessor解析流程https://blog.csdn.net/qq_38257958/article/details/134761961?spm1001.2014.3001.5501 1.EnableTransactionManagement注解源码 通过上面的源码,我们简单理论分析 EnableTransactionManagement注解会注入一个类型为TransactionManagementConfigurationSelector的class,该class的父类实现selectImports方法,父类方法又会调用子类的同名方法。根据上文中阐述的Import注解的作用,此时Spring容器中多了两个BeanDefinition:一个beanClass为AutoProxyRegistrar,另一个beanClass为ProxyTransactionManagementConfiguration 结论1:EnableTransactionManagement注解会import一个类型为TransactionManagementConfigurationSelector的class,该class实现ImportSelector接口,其接口方法返回[AutoProxyRegistrar,ProxyTransactionManagementConfiguration]类名数组,即Spring容器在后期会存在beanClass为AutoProxyRegistrar和ProxyTransactionManagementConfiguration的两个bean 2.AutoProxyRegistrar源码 AutoProxyRegistrar实现ImportBeanDefinitionRegistrar接口,所以会在Spring的解析阶段执行registerBeanDefinitions方法,我们重点关注截图框住的方法,它会注入一个beanClass为InfrastructureAdvisorAutoProxyCreator的BeanDefinition。InfrastructureAdvisorAutoProxyCreator是BeanPostProcessor(后文简称bpp)的子类,它会在普通bean的生命周期对bean进行一些干预,比如当前bpp就会在Spring执行bpp的postProcessAfterInitialization方法的时候会对bean进行动态代理(这个我们后文分析) 结论2:AutoProxyRegistrar会注入一个类型为InfrastructureAdvisorAutoProxyCreator的bean 3.ProxyTransactionManagementConfiguration源码 这个类比较简单,就是一个配置类,利用Configuration Bean的组合,创建了几个bean 结论3:ProxyTransactionManagementConfiguration会注入beanClass为BeanFactoryTransactionAttributeSourceAdvisor、TransactionAttributeSource、TransactionInterceptor的三个bean 小结 EnableTransactionManagement注解会import一个实现ImportSelector接口的类,import的类会注入两个bean(beanClass分别为AutoProxyRegistrar和ProxyTransactionManagementConfiguration),其中AutoProxyRegistrar会进一步解析,然后注入一个类型为InfrastructureAdvisorAutoProxyCreator的bpp。ProxyTransactionManagementConfiguration是一个配置类会注入几个bean协助EnableTransactionManagement注解完成相关功能 2.什么是BeanPostProcessor BeanPostProcessor从本质上说它也是一个bean不过它优先实例化然后作用于普通bean。比如我们耳熟能详的属性注入、动态代理都是BeanPostProcessor在不同阶段对普通bean进行的处理。 详情阅读下方链接博文Spring之BeanPostProcessorhttps://blog.csdn.net/qq_38257958/article/details/134753005?spm1001.2014.3001.5502 3.InfrastructureAdvisorAutoProxyCreator的作用 InfrastructureAdvisorAutoProxyCreator继承BeanPostProcessor,在spring执行到postProcessAfterInitialization的时候会查找可以作用于当前bean的Advisors,如果存在符合条件的Advisors,则进行动态代理 具体查找过程可以查看下方链接博文。简单来说就是查找普通bean所属的class和方法上有没有Transactional注解,如果满足条件则进行AOP动态代理。Spring之AOP源码解析(下)https://blog.csdn.net/qq_38257958/article/details/136182213?spm1001.2014.3001.5502 根据我们设置的参数有可能进行JDK动态代理也有可能进行cglib动态代理,如果是JDK动态代理我们关注JdkDynamicAopProxy这个类,如果是cglib动态代理我们关注DynamicAdvisedInterceptor这个类。不管是什么动态代理都会有一个field(advised),这个参数存储了可以作用于当前bean的Advisors,每个Advisor都有一个advice对象(MethodInterceptor的父接口),Spring会将这些advice串成一个拦截器链,链式调用各个拦截器的invoke方法,我们画图演示流程 PS:有兴趣的小伙伴可以把我写的几篇关于AOP的文章都阅读一下,可以更好的帮助我们理解这篇博文。 4.TransactionInterceptor源码 主要关注其invoke方法,invoke方法主要调用了invokeWithinTransaction方法 主体流程 protected Object invokeWithinTransaction(Method method, Nullable Class? targetClass,final TransactionAspectSupport.InvocationCallback invocation) throws Throwable {// 上文分析的ProxyTransactionManagementConfiguration注入的三个bean之一(AnnotationTransactionAttributeSource)TransactionAttributeSource tas getTransactionAttributeSource();// 1.从类上查找Transactional注解// 2.从方法上查找Transactional注解// 3.将步骤1或2查找到的Transactional注解进行解析,构建成TransactionAttribute对象(RuleBasedTransactionAttribute)final TransactionAttribute txAttr (tas ! null ? tas.getTransactionAttribute(method, targetClass) : null);// 1.如果txAttr为null或者beanFactory为null返回注入的TransactionManager// 2.如果txAttr.getQualifier不为null(即Transactional注解的value属性值)则从beanFactory获取配置的bean返回// 3.如果注入了transactionManagerBeanName则从beanFactory获取bean返回// 4.如果没注入TransactionManager就从beanFactory获取class为PlatformTransactionManager的bean返回final TransactionManager tm determineTransactionManager(txAttr);// 省略webFlux相关代码PlatformTransactionManager ptm asPlatformTransactionManager(tm);final String joinpointIdentification methodIdentification(method, targetClass, txAttr);if (txAttr null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {// 开启事务(如果需要)TransactionAspectSupport.TransactionInfo txInfo createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);Object retVal;try {// 执行下一个拦截器的invoke方法或者目标方法retVal invocation.proceedWithInvocation();} catch (Throwable ex) {// 处理异常completeTransactionAfterThrowing(txInfo, ex);throw ex;} finally {// 解除线程和事务的绑定关系cleanupTransactionInfo(txInfo);}if (retVal ! null vavrPresent TransactionAspectSupport.VavrDelegate.isVavrTry(retVal)) {// Set rollback-only in case of Vavr failure matching our rollback rules...TransactionStatus status txInfo.getTransactionStatus();if (status ! null txAttr ! null) {retVal TransactionAspectSupport.VavrDelegate.evaluateTryFailure(retVal, txAttr, status);}}// 提交事务commitTransactionAfterReturning(txInfo);return retVal;}} 基础数据准备 获取TransactionAttributeSource获取TransactionAttribute推断TransactionManager开启事务执行拦截器方法或者目标方法处理异常(如果存在)提交事务 事务同步管理器TransactionSynchronizationManager 这个类在Transactional源码中起着重要作用,它不仅管理每个线程的资源和事务同步,也协助完成与mybatis的集成 开启事务 TransactionAspectSupport#createTransactionIfNecessary AbstractPlatformTransactionManager#getTransaction AbstractPlatformTransactionManager#startTransaction DataSourceTransactionManager#doBegin protected void doBegin(Object transaction, TransactionDefinition definition) {DataSourceTransactionManager.DataSourceTransactionObject txObject (DataSourceTransactionManager.DataSourceTransactionObject) transaction;Connection con null;try {// 如果事务还没有获取Connection或者Connection还没标记为与事务同步if (!txObject.hasConnectionHolder() ||txObject.getConnectionHolder().isSynchronizedWithTransaction()) {// 获取ConnectionConnection newCon obtainDataSource().getConnection();if (logger.isDebugEnabled()) {logger.debug(Acquired Connection [ newCon ] for JDBC transaction);}// 将Connection标记为new ConnectiontxObject.setConnectionHolder(new ConnectionHolder(newCon), true);}// 将Connection没标记为与事务同步txObject.getConnectionHolder().setSynchronizedWithTransaction(true);con txObject.getConnectionHolder().getConnection();// 设置事务的隔离级别Integer previousIsolationLevel DataSourceUtils.prepareConnectionForTransaction(con, definition);txObject.setPreviousIsolationLevel(previousIsolationLevel);txObject.setReadOnly(definition.isReadOnly());// 将Connection的自动提交关闭if (con.getAutoCommit()) {txObject.setMustRestoreAutoCommit(true);if (logger.isDebugEnabled()) {logger.debug(Switching JDBC Connection [ con ] to manual commit);}con.setAutoCommit(false);}prepareTransactionalConnection(con, definition);// 将事务标记为已激活txObject.getConnectionHolder().setTransactionActive(true);// 设置过期时间(如果手动设置了)int timeout determineTimeout(definition);if (timeout ! TransactionDefinition.TIMEOUT_DEFAULT) {txObject.getConnectionHolder().setTimeoutInSeconds(timeout);}// 如果是新连接,事务同步管理器同步资源if (txObject.isNewConnectionHolder()) {TransactionSynchronizationManager.bindResource(obtainDataSource(), txObject.getConnectionHolder());}}catch (Throwable ex) {if (txObject.isNewConnectionHolder()) {DataSourceUtils.releaseConnection(con, obtainDataSource());txObject.setConnectionHolder(null, false);}throw new CannotCreateTransactionException(Could not open JDBC Connection for transaction, ex);}} PS : Spring源码中存在很多模板模式,很多方法都是交给子类去实现,比如上文中的doGetTransaction,isExistingTransaction,doBegin等方法,如果我们不确定具体走的是那个子类,可以多多去debug看看。这里TransactionManager主要是子类DataSourceTransactionManager 注意:我们在mysql中开启事务,可以使用BEGIN、START TRANSACTION等但是在源码中我们并没有发现这样的sql语句。其实事务可以隐式开启在上述doBegin方法的源码中,存在con.setAutoCommit(false)这样的方法其实这就等价于执行sql语句set autocommit OFF(隐式开启事务) 事务隔离级别 REQUIREDSUPPORTSMANDATORYREQUIRES_NEWNOT_SUPPORTEDNEVERNESTED 通过源码整理事务处理流程 异常处理 TransactionAspectSupport#completeTransactionAfterThrowing 我们在上文中指出该TransactionAttribute类型为RuleBasedTransactionAttribut,然后如果我们指定Transactional注解的rollbackFor、rollbackForClassName、noRollbackFor、noRollbackForClassName属性,后期会被解析成RollbackRuleAttribute对象,相关源码明细可以查看AbstractFallbackTransactionAttributeSource(AnnotationTransactionAttributeSource的父类)的getTransactionAttribute方法 case1:未指定rollbackFor、rollbackForClassName、noRollbackFor、noRollbackForClassName 当我们未指定上述四个属性,会调用super.rollbackOn的方法 当我们未指定rollbackFor、rollbackForClassName、noRollbackFor、noRollbackForClassName属性的时候,事务只有在遇到RuntimeException异常或者Error的时候才会回滚 case2:指定rollbackFor、rollbackForClassName、noRollbackFor、noRollbackForClassName 当我们指定了四个属性中的一个或者多个,就会被解析成RollbackRuleAttribute(NoRollbackRuleAttribute),最后通过getDepth方法获取winner,如果winner是RollbackRuleAttribute旧回滚,否则就提交事务 getDepth方法主要判断抛出的异常与指定的异常之间的关系 如果抛出异常和指定异常一致,则depth为0如果抛出异常和指定异常子类,则depth加1(递归判断)如果抛出异常为Throwable,则depth为-1 depth值越小(大于0),优先级越高 触发器 不管最后事务是提交还是回滚,都会执行相应的触发器方法,我们可以利用这一特性,做一些扩展 与mybatis的整合 mybatis相关接口会被JDK动态代理,代理对象的类型是MapperProxy。感兴趣小伙伴可以阅读我之前的博文 《MapperScan源码解析》 MapperProxy#invoke PlainMethodInvoker#invokeMapperMethod#executeSqlSessionTemplate#selectOne SqlSessionInterceptor#invoke(sqlSessionProxy是一个代理对象,所以会进入相应拦截器方法)SqlSessionUtils#getSqlSession  我们看到了我们熟悉的TransactionSynchronizationManager,当mybatis执行sql的时候会从事务同步管理器里面获取resource,保证了同个事务里面的增删改查都是使用的同一个SqlSession
http://www.hkea.cn/news/14427857/

相关文章:

  • 公司网站建设合规吗为什么我的网站无法访问
  • 瀑布流分享网站源代码下载专业建设主考学校是什么意思
  • 上海学习网站建设天津网站制作建设
  • 中国最大的免费素材网站番号网站怎么做
  • 网站功能建设上海门户网站制
  • 网站开发和优化关系六安短视频优化费用
  • 昆明hph网站建设中国新闻社副社长
  • 静安西安网站建设网上做室内设计好的网站
  • 中国建设教育协会培训中心网站百度ocpc如何优化
  • 有主体新增网站海南省两学一做网站
  • 深圳网站建设及优化阿里云认证网站建设题库
  • 网站建设 软件 开源台州网站建设哪家便宜
  • 做展示网站要恋用什么程序软件工程最好的出路
  • 制作网站软件网站上海市建设干部学校网站
  • 甜品网站建设策划书wordpress jiathis
  • 电子购物网站开发公司莱芜做网站的商家有哪些
  • 58网站建设的目的php网站跟随导航
  • 建设信用卡商城网站深圳市建工集团
  • 你认为公司在建立网站时应满足哪些目标经典软文案例100例
  • 智趣游戏型网站开发网页制作教材素材
  • 怎样选择 网站建设常州做网站软件
  • 如何做话费卡回收网站雨颜色网站建设
  • 深圳网站建设服务合同健身网站建设
  • 网站备案号省份深圳高端做网站公司
  • 商场网站建设模板网站开发的程序平台
  • 深圳有实力的seo公司南京广告宣传公司seo
  • 自贡北京网站建设南山网站制作联系电话
  • ps网站导航制作wordpress商品按钮代码
  • 盐城企业网站制作电商网站建设与运营哦
  • 买个域名自己做网站wordpress分类页打不开