spring AOP

纸上得来终觉浅

前面学习和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)

Spring Aop的功能基本上到这里可以明白了。

你可能感兴趣的:(spring,AOP,AOP,面向切面编程)