zoukankan      html  css  js  c++  java
  • Spring课程 Spring入门篇 5-7 advisors

    课程链接:

    1    简析

    1.1  advisor简析

    2    代码演练

    2.1  类似顾问通知实现:(代码演练中没有用到顾问标签)

     

     

     

    1    简析

    顾问:在通知的基础之上,在细化我们的aop切面!


    通知和顾问都是切面的实现方式!
    通知是顾问的一个属性!

    顾问会通过我们的设置,将不同的通知,在不通过的时间点,把切面
    织入到不同的切入点!

    PointCutAdvisor接口!
    比较常用的两个实现类:
    NameMatchMethodPointcutAdvisor :根据切入点(主业务方法)名称织入切面!
    RegexpMethodPointcutAdvisor :根据自定义的正则表达式织入切面!

    正则表达式中常用的三个运算符
    .   任意单个字符
    +   表示字符出现一次或者多次
    *   表示字符出现0次或者多次

    1.1  advisor简析(更加灵活的配置切面,详细的可以参见2.1)

    Advisor是Pointcut和Advice的配置器,它包括PointcutAdvice,是将Advice注入程序中Pointcut位置的代码

    <aop:aspectj-autoproxy/>
       <aop:config proxy-target-class="true">
           <aop:pointcut id="servicePointcut"
                         expression="execution(* com.cpic..*Service.*(..))" />
           <aop:advisor pointcut-ref="servicePointcut" advice-ref="txAdvice"
                        order="3" />
       </aop:config>
       <tx:advice id="txAdvice" transaction-manager="transactionManager">
           <tx:attributes>
               <tx:method name="add*" />
               <tx:method name="insert*" />
               <tx:method name="remove*" />
               <tx:method name="save*" />
               <tx:method name="update*" />
               <tx:method name="delete*" />
               <tx:method name="cancel*" />
               <tx:method name="trans*" />
               <tx:method name="commit*" />
               <tx:method name="submit*" />
               <tx:method name="issue*" />
               <tx:method name="accept*" />
               <tx:method name="underwrite*" />
               <tx:method name="modify*" />
               <tx:method name="calculate*" />
               <tx:method name="copy*" />
               <tx:method name="print*" />
               <tx:method name="create*" />
               <tx:method name="send*" />
               <tx:method name="activate*" />
               <tx:method name="generate*" /> 
               <tx:method name="do*" />
               <tx:method name="find*" read-only="true" />
               <tx:method name="get*" read-only="true" />
               <tx:method name="load*" read-only="true" />
               <tx:method name="list*" read-only="true" />
               <!-- log方法会启动一个新事务 -->
               <tx:method name="log*" propagation="REQUIRES_NEW"
                          isolation="READ_COMMITTED" />
               <!-- 如果通过java代码来进行分库判断,这里exeNewTS方法需要启动一个新事务 ,切换数据源时使用-->
               <tx:method name="exeNewTS*" propagation="REQUIRES_NEW"
                          isolation="READ_COMMITTED" />
              <!--  <tx:method name="exeNewTS*"/> -->
           </tx:attributes>
       </tx:advice>

    2    代码演练

    2.1  类似顾问通知实现:(代码演练中没有用到顾问标签)

    测试类:

    package com.imooc.test.aop;
    
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.junit.runners.BlockJUnit4ClassRunner;
    
    import com.imooc.aop.schema.advisors.service.InvokeService;
    import com.imooc.test.base.UnitTestBase;
    
    @RunWith(BlockJUnit4ClassRunner.class)
    public class TestAOPSchemaAdvisors extends UnitTestBase {
        
        public TestAOPSchemaAdvisors() {
            super("classpath:spring-aop-schema-advisors.xml");
        }
        
            
    
        @Test
        /**
         * 1    这里问题的关键:在 ConcurrentOperationExecutor.java类中的try方法中
         *         把正常的方法service.invoke() 和出现异常的方法service.invokeException() 进行对比
         * 
         * 2    从xml传值    <property name="maxRetries" value="3"/>
         */
        public void testSave(){
            InvokeService service  = super.getbean("invokeService");
            service.invoke();
            
            System.out.println("===================================================================================================================");
            service.invokeException();
        }
    }

    配置类:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop" 
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd"
     >
    
    
    <!-- 扫描包 -->
    <context:component-scan base-package="com.imooc.aop.schema"></context:component-scan>
    
    <!-- 配置aop -->
    <aop:config>
        <aop:aspect id="concurrentOperationRetry" ref="concurrentOperationExecutor">
            <!-- 注意:此处有小空格 -->

          <aop:pointcut id="idempotentOperation" 

            expression="execution(* com.imooc.aop.schema.advisors.service.*.*(..)) " />

         <aop:around pointcut-ref="idempotentOperation" method="doConcurrentOperation"/>

        </aop:aspect>
    </aop:config>
    
    
    
    
    <!-- 配置bean类 ,当下类作为通知类存在-->
    <bean id="concurrentOperationExecutor" class="com.imooc.aop.schema.advisors.ConcurrentOperationExecutor">

        <property name="maxRetries" value="3"/>

        <property name="order" value="100"/>
    </bean>
    
    </beans>

    实体类:

    package com.imooc.aop.schema.advisors.service;
    
    import org.springframework.dao.PessimisticLockingFailureException;
    import org.springframework.stereotype.Service;
    
    @Service
    public class InvokeService {
        
        public void invoke() {
            System.out.println("Invoke Service ....");
        }
        
        public void invokeException(){
            throw new PessimisticLockingFailureException("");
        }
    
    }

    通知类:

    package com.imooc.aop.schema.advisors;
    
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.springframework.core.Ordered;
    import org.springframework.dao.PessimisticLockingFailureException;
    
    public class ConcurrentOperationExecutor implements Ordered{
    
        private static final int DEFAULT_MAX_RETRIES = 2;
        
        private int maxRetries = DEFAULT_MAX_RETRIES;
        
        private int order = 1;
    
        public int getMaxRetries() {
            return maxRetries;
        }
    
        public void setMaxRetries(int maxRetries) {
            this.maxRetries = maxRetries;
        }
    
        public int getOrder() {
            return order;
        }
    
        public void setOrder(int order) {
            this.order = order;
        }
        
        /**
         * 通知对应的方法
         * @param pjp
         * @return
         * @throws Throwable 
         */
        public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable{
            int numAttempts = 0;    //次数
            PessimisticLockingFailureException lockFailureException;
            do {
                numAttempts++;
                System.out.println("Try Times : "+numAttempts);
                try {
                    return pjp.proceed();
                } catch (PessimisticLockingFailureException e) {
                    lockFailureException = e;
                }
            } while (numAttempts<=this.maxRetries);//次数递增,当小于常量(xml传入的次数)时
            System.out.println("Try error:"+numAttempts);
            return lockFailureException;
            
        }
        
        
        
    }

    打印日志:

    四月 20, 2019 3:01:36 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
    信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@45a5049a: startup date [Sat Apr 20 15:01:36 CST 2019]; root of context hierarchy
    四月 20, 2019 3:01:36 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
    信息: Loading XML bean definitions from class path resource [spring-aop-schema-advisors.xml]
    四月 20, 2019 3:01:36 下午 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor <init>
    信息: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
    Try Times : 1
    Invoke Service ....
    ===================================================================================================================
    Try Times : 1
    Try Times : 2
    Try Times : 3
    Try Times :4
    Try error:4
    四月 20, 2019 3:01:37 下午 org.springframework.context.support.ClassPathXmlApplicationContext doClose
    信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@45a5049a: startup date [Sat Apr 20 15:01:36 CST 2019]; root of context hierarchy
  • 相关阅读:
    基于 IAR 修改工程名称
    Baidu IoT Study
    msp430f5438a Information Flash Seg Write -- Chapter
    MFC 编辑框内容更新方法以及滚动条设置
    通过打开按钮打开文件和通过左键移动打开文件并计算crc
    移动文件并将文件路径显示到编辑框内
    Aritronix Virtual Device 运行
    将一个char类型的数转换成曼切斯特数
    数组中重复的数字
    平衡二叉树
  • 原文地址:https://www.cnblogs.com/1446358788-qq/p/10740126.html
Copyright © 2011-2022 走看看