纸上得来终觉浅
前面学习和java反射机制和动态代理,再学习Spring Aop很容易明白,首先需要两个jar包:com.springsource.org.aopalliance-1.0.0.jar 和 com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar在http://download.csdn.net/download/jintao_ma/9486168免积分下载
代码示例如下:
public interface count { public int add(int a,int b); public int div(int a,int b); }
@Component public class mathCount implements count{ public int add(int a,int b){ return a+b; } public int div(int a,int b){ return a/b; } }
import java.util.Arrays; import java.util.List; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.core.env.JOptCommandLinePropertySource; import org.springframework.stereotype.Component; @Aspect @Component public class LoggingAspect { /*前置通知*/ @Before("execution(public int com.roadArchitectWeb.dyproxy.mathCount.*(int,int))") public void beforeMethod(JoinPoint joinpoint){ System.out.println("LoggingAspect.beforeMethod()"); String methodName = joinpoint.getSignature().getName(); System.out.println("LoggingAspect.MethodName():"+methodName); List args = Arrays.asList(joinpoint.getArgs()); System.out.println("LoggingAspect.args():"+args); } /*后置通知,在目标方法执行后(无论是否异常都会执行,这时候还获取不到方法的返回结果*/ @After("execution(public int com.roadArchitectWeb.dyproxy.mathCount.*(int,int))") public void afterMethod(JoinPoint joinpoint){ System.out.println("LoggingAspect.afterMethod()"); } /*返回通知,是可以访问到方法de返回值的*/ @AfterReturning(value="execution(public int com.roadArchitectWeb.dyproxy.mathCount.*(int,int))", returning="result") public void afterRuturnMethod(JoinPoint joinpoint,Object result){ System.out.println("LoggingAspect.afterRuturnMethod()返回值是:"+result); } /*出现异常时执行,还可以指定特定异常,这里就不写了*/ @AfterThrowing(value="execution(public int com.roadArchitectWeb.dyproxy.mathCount.*(int,int))") public void afterThrowing(JoinPoint joinpoint){ System.out.println("LoggingAspect.afterThrowing()"); } /*环绕通知 * 需要携带ProceedingJoinPoint参数 * 环绕通知类型动态代理的全过程 * 环绕通知必须有返回值,返回值就是目标方法的返回值 * */ // @Around("execution(public int com.roadArchitectWeb.dyproxy.mathCount.*(int,int))") // public Object aroundMethod(ProceedingJoinPoint pjd){ // Object result = null; // // /*执行目标方法*/ // try { // /*这里的通知相当于前置通知*/ // System.out.println("LoggingAspect.aroundMethod()前置"); // result = pjd.proceed(); // /*这里的通知相当于返回通知*/ // System.out.println("LoggingAspect.aroundMethod()返回:"+result); // } catch (Throwable e) { // /*这里的通知相当于异常通知*/ // System.out.println("LoggingAspect.aroundMethod()异常"); // throw new RuntimeException(); // } // /*这里的通知相当于后置通知*/ // System.out.println("LoggingAspect.aroundMethod()后置"); // return result; // } }
<!-- 自动扫描 --> <context:component-scan base-package="com.roadArchitectWeb.dyproxy"></context:component-scan> <!-- 是aspectj注解起作用 --> <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("aop.xml"); count count = (count)ctx.getBean("mathCount"); int result1 = count.add(1,2); System.out.println("Main.main()1:"+result1); int result2 = count.div(3, 0); System.out.println("Main.main()2:"+result2); } }运行结果如下:
LoggingAspect.beforeMethod() LoggingAspect.MethodName():add LoggingAspect.args():[1, 2] LoggingAspect.afterMethod() LoggingAspect.afterRuturnMethod()返回值是:3 Main.main()1:3 LoggingAspect.beforeMethod() LoggingAspect.MethodName():div LoggingAspect.args():[3, 0] LoggingAspect.afterMethod() LoggingAspect.afterThrowing() Exception in thread "main" java.lang.ArithmeticException: / by zero at com.roadArchitectWeb.dyproxy.mathCount.div(mathCount.java:11) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302) at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) 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.aspectj.AspectJAfterAdvice.invoke(AspectJAfterAdvice.java:43) 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.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:58) 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.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207) at com.sun.proxy.$Proxy10.div(Unknown Source) at com.roadArchitectWeb.dyproxy.Main.main(Main.java:12)
LoggingAspect.aroundMethod()前置 Exception in thread "main" LoggingAspect.aroundMethod()返回:3 LoggingAspect.aroundMethod()后置 Main.main()1:3 LoggingAspect.aroundMethod()前置 LoggingAspect.aroundMethod()异常 java.lang.RuntimeException at com.roadArchitectWeb.dyproxy.LoggingAspect.aroundMethod(LoggingAspect.java:69) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) 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.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207) at com.sun.proxy.$Proxy7.div(Unknown Source) at com.roadArchitectWeb.dyproxy.Main.main(Main.java:12)