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
  • 相关阅读:
    自然语言交流系统 phxnet团队 创新实训 项目博客 (十一)
    install ubuntu on Android mobile phone
    Mac OS, Mac OSX 与Darwin
    About darwin OS
    自然语言交流系统 phxnet团队 创新实训 项目博客 (十)
    Linux下编译安装qemu和libvirt
    libvirt(virsh命令总结)
    深入浅出 kvm qemu libvirt
    自然语言交流系统 phxnet团队 创新实训 项目博客 (九)
    自然语言交流系统 phxnet团队 创新实训 项目博客 (八)
  • 原文地址:https://www.cnblogs.com/1446358788-qq/p/10740126.html
Copyright © 2011-2022 走看看