• Spring学习(21)--- AOP之Advice应用(上)


    前置通知(Before advice) 在某个连接点(join point)之前执行的通知,但不能阻止连接点前的执行(除非它抛出异常)
    返回后通知(After returning advice) 在某个连接点(join point)正常完成后执行的通知
    抛出异常后通知(After throwing advice) 在方法抛出异常退出时执行的通知
    后通知(After(finally) advice) 当某个连接点退出的时候执行的通知(无论是正常返回还是异常退出)
    环绕通知(Around advice) 包围一个连接点(join point)的通知

    导入需要的包:aspectjweaver.jar、aopalliance-1.0.jar

    (一)Before Advice

    例子:

    新建两个类:

    package com.aop.schema;
    /**
    *
    * 切面类
    *
    */
    public class MyAspect {
    
    	public void before(){
    		System.out.println("MyAspect.before");
    	}
    }
    
    package com.aop.schema;
    /**
    *
    * 业务类
    *
    */
    public class ApsectBiz {
    
    	public void biz(){
    		System.out.println("ApsectBiz.biz");
    	}
    }
    

    XML配置:

    <?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-4.1.xsd
                http://www.springframework.org/schema/context
                http://www.springframework.org/schema/context/spring-context-4.1.xsd
                http://www.springframework.org/schema/aop
                http://www.springframework.org/schema/aop/spring-aop-4.1.xsd">
             
         <bean id="myAspect" class="com.aop.schema.MyAspect"></bean>
          
         <bean id="apsectBiz" class="com.aop.schema.ApsectBiz"></bean>
          
         <aop:config>
              <aop:aspect id="myAspectAOP" ref="myAspect">
                <aop:pointcut id="myPointcut" expression="execution(* com.aop.schema.ApsectBiz.*(..))" />
                <aop:before method="before" pointcut-ref="myPointcut"/>
              </aop:aspect>
         </aop:config>
     
    </beans>
    

    单元测试:

    package com.aop.schema;
    
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class UnitTest {
    
    	@Test
    	public void test(){
    		ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring-aop.xml");
    		ApsectBiz biz = (ApsectBiz)context.getBean("apsectBiz");
    		biz.biz();
    	}
    }
    

    结果:

    七月 09, 2015 10:30:24 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
    INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@31b3c607: startup date [Thu Jul 09 22:30:24 CST 2015]; root of context hierarchy
    七月 09, 2015 10:30:24 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
    INFO: Loading XML bean definitions from class path resource [spring-aop.xml]
    MyAspect.before
    ApsectBiz.biz

    PS:ApsectBiz.biz是业务方法,在它之前,执行了前置通知MyAspect.before,符合想要的结果

    (二)After returning advice

    例子:

    修改一下切面类MyAspect(添加afterreturning方法):

    package com.aop.schema;
    /**
    *
    * 切面类
    *
    */
    public class MyAspect {
    
    	public void before(){
    		System.out.println("MyAspect.before");
    	}
    	
    	public void afterreturning(){
    		System.out.println("MyAspect.afterreturning");
    	}
    }
    

    XML配置修改为:

    <?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-4.1.xsd
                http://www.springframework.org/schema/context
                http://www.springframework.org/schema/context/spring-context-4.1.xsd
                http://www.springframework.org/schema/aop
                http://www.springframework.org/schema/aop/spring-aop-4.1.xsd">
             
         <bean id="myAspect" class="com.aop.schema.MyAspect"></bean>
          
         <bean id="apsectBiz" class="com.aop.schema.ApsectBiz"></bean>
          
         <aop:config>
              <aop:aspect id="myAspectAOP" ref="myAspect">
                <aop:pointcut id="myPointcut" expression="execution(* com.aop.schema.ApsectBiz.*(..))" />
                <aop:before method="before" pointcut-ref="myPointcut"/>
                <aop:after-returning method="afterreturning" pointcut-ref="myPointcut"/>
              </aop:aspect>
         </aop:config>
     
    </beans>
    

    单元测试同上:

    结果:

    七月 09, 2015 10:38:41 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
    INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@31b3c607: startup date [Thu Jul 09 22:38:41 CST 2015]; root of context hierarchy
    七月 09, 2015 10:38:41 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
    INFO: Loading XML bean definitions from class path resource [spring-aop.xml]
    MyAspect.before
    ApsectBiz.biz
    MyAspect.afterreturning

    (三)After throwing advice

    说明:使用throwing属性来指定可被传递的异常的参数名称

    例子:

    修改一下切面类MyAspect(添加afterthrowing方法):

    package com.aop.schema;
    /**
    *
    * 切面类
    *
    */
    public class MyAspect {
    
    	public void before(){
    		System.out.println("MyAspect.before");
    	}
    	
    	public void afterreturning(){
    		System.out.println("MyAspect.afterreturning");
    	}
    	
    	public void afterthrowing(){
    		System.out.println("MyAspect.afterthrowing");
    	}
    }
    

    修改业务类ApsectBiz(抛出一个异常):

    package com.aop.schema;
    
    /**
    *
    * 业务类
    *
    */
    public class ApsectBiz {
    
    	public void biz(){
    		System.out.println("ApsectBiz.biz");
    		throw new RuntimeException();  //故意抛出异常
    	}
    }
    

    XML配置:

    <?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-4.1.xsd
                http://www.springframework.org/schema/context
                http://www.springframework.org/schema/context/spring-context-4.1.xsd
                http://www.springframework.org/schema/aop
                http://www.springframework.org/schema/aop/spring-aop-4.1.xsd">
             
         <bean id="myAspect" class="com.aop.schema.MyAspect"></bean>
          
         <bean id="apsectBiz" class="com.aop.schema.ApsectBiz"></bean>
          
         <aop:config>
              <aop:aspect id="myAspectAOP" ref="myAspect">
                <aop:pointcut id="myPointcut" expression="execution(* com.aop.schema.ApsectBiz.*(..))" />
                <aop:before method="before" pointcut-ref="myPointcut"/>
                <aop:after-returning method="afterreturning" pointcut-ref="myPointcut"/>
                <aop:after-throwing method="afterthrowing" pointcut-ref="myPointcut"/>
              </aop:aspect>
         </aop:config>
     
    </beans>
    

    单元测试同上:

    测试结果:

    七月 09, 2015 10:47:46 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
    INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@31b3c607: startup date [Thu Jul 09 22:47:46 CST 2015]; root of context hierarchy
    七月 09, 2015 10:47:46 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
    INFO: Loading XML bean definitions from class path resource [spring-aop.xml]
    MyAspect.before
    ApsectBiz.biz
    MyAspect.afterthrowing

    PS:有没有发现有什么问题? MyAspect.afterreturning没有了,biz()中抛出异常,biz()方法没有正常返回,所以MyAspect.afterreturning没有了。

    (四)After(finally) advice

    修改一下切面类MyAspect(添加after方法):

    package com.aop.schema;
    /**
    *
    * 切面类
    *
    */
    public class MyAspect {
    
    	public void before(){
    		System.out.println("MyAspect.before");
    	}
    	
    	public void afterreturning(){
    		System.out.println("MyAspect.afterreturning");
    	}
    	
    	public void afterthrowing(){
    		System.out.println("MyAspect.afterthrowing");
    	}
    	
    	public void after(){
    		System.out.println("MyAspect.after");
    	}
    }
    

    XML配置:

    <?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-4.1.xsd
                http://www.springframework.org/schema/context
                http://www.springframework.org/schema/context/spring-context-4.1.xsd
                http://www.springframework.org/schema/aop
                http://www.springframework.org/schema/aop/spring-aop-4.1.xsd">
             
         <bean id="myAspect" class="com.aop.schema.MyAspect"></bean>
          
         <bean id="apsectBiz" class="com.aop.schema.ApsectBiz"></bean>
          
         <aop:config>
              <aop:aspect id="myAspectAOP" ref="myAspect">
                <aop:pointcut id="myPointcut" expression="execution(* com.aop.schema.ApsectBiz.*(..))" />
                <aop:before method="before" pointcut-ref="myPointcut"/>
                <aop:after-returning method="afterreturning" pointcut-ref="myPointcut"/>
                <aop:after-throwing method="afterthrowing" pointcut-ref="myPointcut"/>
                <aop:after method="after" pointcut-ref="myPointcut"/>
              </aop:aspect>
         </aop:config>
     
    </beans>
    

    单元测试同上:

    结果:

    七月 09, 2015 10:56:10 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
    INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@31b3c607: startup date [Thu Jul 09 22:56:10 CST 2015]; root of context hierarchy
    七月 09, 2015 10:56:10 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
    INFO: Loading XML bean definitions from class path resource [spring-aop.xml]
    MyAspect.before
    ApsectBiz.biz
    MyAspect.afterthrowing
    MyAspect.after

    (五)Around advice

    注意:通知方法的第一个参数必ProceedingJoinPoint类型

    例子:

    修改一下切面类MyAspect(添加around方法):

    package com.aop.schema;
    
    import org.aspectj.lang.ProceedingJoinPoint;
    
    /**
    *
    * 切面类
    *
    */
    public class MyAspect {
    
    	public void before(){
    		System.out.println("MyAspect.before");
    	}
    	
    	public void afterreturning(){
    		System.out.println("MyAspect.afterreturning");
    	}
    	
    	public void afterthrowing(){
    		System.out.println("MyAspect.afterthrowing");
    	}
    	
    	public void after(){
    		System.out.println("MyAspect.after");
    	}
    	
    	public void around(ProceedingJoinPoint pjp) throws Throwable{
    		System.out.println("MyAspect.around_1");
    		Object obj=pjp.proceed();
    		System.out.println("MyAspect.around_2");
    	}
    }
    

    XML配置:

    <?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-4.1.xsd
                http://www.springframework.org/schema/context
                http://www.springframework.org/schema/context/spring-context-4.1.xsd
                http://www.springframework.org/schema/aop
                http://www.springframework.org/schema/aop/spring-aop-4.1.xsd">
             
         <bean id="myAspect" class="com.aop.schema.MyAspect"></bean>
          
         <bean id="apsectBiz" class="com.aop.schema.ApsectBiz"></bean>
          
         <aop:config>
              <aop:aspect id="myAspectAOP" ref="myAspect">
                <aop:pointcut id="myPointcut" expression="execution(* com.aop.schema.ApsectBiz.*(..))" />
                <aop:before method="before" pointcut-ref="myPointcut"/>
                <aop:after-returning method="afterreturning" pointcut-ref="myPointcut"/>
                <aop:after-throwing method="afterthrowing" pointcut-ref="myPointcut"/>
                <aop:after method="after" pointcut-ref="myPointcut"/>
                <aop:around method="around" pointcut-ref="myPointcut"/>
              </aop:aspect>
         </aop:config>
     
    </beans>
    

    单元测试同上:

    结果:

    七月 09, 2015 11:15:20 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
    INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@31b3c607: startup date [Thu Jul 09 23:15:20 CST 2015]; root of context hierarchy
    七月 09, 2015 11:15:20 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
    INFO: Loading XML bean definitions from class path resource [spring-aop.xml]
    MyAspect.before
    MyAspect.around_1
    ApsectBiz.biz
    java.lang.RuntimeException
        at com.aop.schema.ApsectBiz.biz(ApsectBiz.java:11)
        at com.aop.schema.ApsectBiz$$FastClassBySpringCGLIB$$ae10254d.invoke(<generated>)
        at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
        at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85)
        at com.aop.schema.MyAspect.around(MyAspect.java:31)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:621)
        at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:610)
        at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:68)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.aop.aspectj.AspectJAfterAdvice.invoke(AspectJAfterAdvice.java:43)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:58)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:52)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:52)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)
        at com.aop.schema.ApsectBiz$$EnhancerBySpringCGLIB$$1fbf7bae.biz(<generated>)
        at com.aop.schema.UnitTest.test(UnitTest.java:13)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
        at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
        at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
        at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
        at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
    MyAspect.after
    MyAspect.afterreturning
    View Code

    PS:有异常,仔细看,原来是around(ProceedingJoinPoint pjp)的try catch捕捉到了biz()抛出的异常,现在把异常注释掉(try catch里面怎么处理异常?这里要看具体的业务需要,这里先注释掉)

    package com.aop.schema;
    /**
    *
    * 业务类
    *
    */
    public class ApsectBiz {
    
    	public void biz(){
    		System.out.println("ApsectBiz.biz");
    		//throw new RuntimeException();  //故意抛出异常
    	}
    }
    

    测试结果:

    七月 09, 2015 11:18:17 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
    INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@31b3c607: startup date [Thu Jul 09 23:18:17 CST 2015]; root of context hierarchy
    七月 09, 2015 11:18:17 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
    INFO: Loading XML bean definitions from class path resource [spring-aop.xml]
    MyAspect.before
    MyAspect.around_1
    ApsectBiz.biz
    MyAspect.around_2
    MyAspect.after
    MyAspect.afterreturning
  • 相关阅读:
    把影响集中到一个点
    How to avoid Over-fitting using Regularization?
    适定性问题
    Numerical Differentiation 数值微分
    What Every Computer Scientist Should Know About Floating-Point Arithmetic
    Generally a good method to avoid this is to randomly shuffle the data prior to each epoch of training.
    What is the difference between iterations and epochs in Convolution neural networks?
    Every norm is a convex function
    Moore-Penrose Matrix Inverse 摩尔-彭若斯广义逆 埃尔米特矩阵 Hermitian matrix
    perl 类里的函数调用其他类的函数
  • 原文地址:https://www.cnblogs.com/JsonShare/p/4633713.html
Copyright © 2020-2023  润新知