Spring Aop完整实例,按照下面说明配置和代码即可完成,因为在刚接触新东西时,最简单的就是一个可以运行的DEMO,可查了很多文章都是不全或者运行有问题,所以自己写一个。

说明:本文需要有Spring IOC基础。

Spring 环境搭建就不说了,可以看我其他文章里面内容,不过要使用AOP需要一个 aspectjweaver-1.6.9.jar,下载后放入项目里面。

一、XML方式

1. TestAspect:切面类

1. package
2.   
3. import
4. import
5.   
6. public class
7.   
8. public void
9. "log Ending method: " + jp.getTarget().getClass().getName() + "."
10.     }  
11.   
12. public Object doAround(ProceedingJoinPoint pjp) throws
13. long
14.         Object retVal = pjp.proceed();  
15.         time = System.currentTimeMillis() - time;  
16. "process time: " + time + " ms");  
17. return
18.     }  
19.   
20. public void
21. "log Begining method: " + jp.getTarget().getClass().getName() + "."
22.     }  
23.   
24. public void
25. "method " + jp.getTarget().getClass().getName() + "." + jp.getSignature().getName() + " throw exception");  
26.         System.out.println(ex.getMessage());  
27.     }  
28. }


2. AServiceImpl:目标对象

1. package
2.   
3. // 使用jdk动态代理
4. public class AServiceImpl implements
5.   
6. public void
7. "AServiceImpl.barA()");  
8.     }  
9.   
10. public void
11. "AServiceImpl.fooA(msg:" + _msg + ")");  
12.     }  
13. }


3. BServiceImpl:目标对象

1. package
2.   
3. // 使用cglib
4. public class
5.   
6. public void barB(String _msg, int
7. "BServiceImpl.barB(msg:" + _msg + " type:" + _type + ")");  
8. if (_type == 1)  
9. throw new IllegalArgumentException("测试异常");  
10.     }  
11.   
12. public void
13. "BServiceImpl.fooB()");  
14.     }  
15.   
16. }


4. ApplicationContext:Spring配置文件

1. <?xml version="1.0" encoding="UTF-8"?>
2. <beans xmlns="http://www.springframework.org/schema/beans"
3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4. xmlns:aop="http://www.springframework.org/schema/aop"
5. xmlns:context="http://www.springframework.org/schema/context"
6. xmlns:tx="http://www.springframework.org/schema/tx"
7. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd  
8.         http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd  
9.         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd  
10. >
11. <aop:config>
12. <aop:aspect id="TestAspect" ref="aspectBean">
13. <!--配置com.spring.service包下所有类或接口的所有方法-->
14. <aop:pointcut id="businessService" expression="execution(* com.spring.service.*.*(..))" />
15. <aop:before pointcut-ref="businessService" method="doBefore"/>
16. <aop:after pointcut-ref="businessService" method="doAfter"/>
17. <aop:around pointcut-ref="businessService" method="doAround"/>
18. <aop:after-throwing pointcut-ref="businessService" method="doThrowing" throwing="ex"/>
19. </aop:aspect>
20. </aop:config>
21.       
22. <bean id="aspectBean" class="com.spring.aop.TestAspect" />
23. <bean id="aService" class="com.spring.service.AServiceImpl"></bean>
24. <bean id="bService" class="com.spring.service.BServiceImpl"></bean>
25. </beans>


说明:这里 * com.spring.service.*.*(..))

测试类:

import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
  public class TestMain {

	/**
	 * @param args
	 */
	public static void testSpringAOP(){
	ApplicationContext ctx = new ClassPathXmlApplicationContext("config/applicationContext.xml");
    
	AService aService = (AService)ctx.getBean("aService");
	aService.fooA("zhangsan");
	}
	public static void main(String[] args) {
		testSpringAOP();
	}

}

运行结果:

log Begining method: com.aop.test.AServiceImpl.fooA
AServiceImpl.fooA(msg:zhangsan)
logEndingmethod: com.aop.test.AServiceImpl.fooA
process time: 1 ms

如果报异常:java.lang.NoClassDefFoundError: org/aopalliance/aop/Advice

缺少包.aopalliance-1.0.0.jar,下载地址 http:///repository/app/bundle/version/download;jsessionid=BEA6BAD3421E4C82FCF33C4D8EA98867.jvm1?name=.aopalliance&version=1.0.0&type=binary

 

二、注解(Annotation)方式

1. TestAnnotationAspect

1. package
2.   
3. import
4. import
5. import
6. import
7. import
8. import
9. import
10. import
11.   
12. @Aspect
13. public class
14.   
15. @Pointcut("execution(* com.spring.service.*.*(..))")  
16. private void
17.     }  
18.   
19. //声明前置通知
20. @Before("pointCutMethod()")  
21. public void
22. "前置通知");  
23.     }  
24.   
25. //声明后置通知
26. @AfterReturning(pointcut = "pointCutMethod()", returning = "result")  
27. public void
28. "后置通知");  
29. "---" + result + "---");  
30.     }  
31.   
32. //声明例外通知
33. @AfterThrowing(pointcut = "pointCutMethod()", throwing = "e")  
34. public void
35. "例外通知");  
36.         System.out.println(e.getMessage());  
37.     }  
38.   
39. //声明最终通知
40. @After("pointCutMethod()")  
41. public void
42. "最终通知");  
43.     }  
44.   
45. //声明环绕通知
46. @Around("pointCutMethod()")  
47. public Object doAround(ProceedingJoinPoint pjp) throws
48. "进入方法---环绕通知");  
49.         Object o = pjp.proceed();  
50. "退出方法---环绕通知");  
51. return
52.     }  
53. }


2. ApplicationContext:Spring配置文件

1. <?xml version="1.0" encoding="UTF-8"?>  
2. <beans xmlns="http://www.springframework.org/schema/beans"
3. "http://www.w3.org/2001/XMLSchema-instance"
4. "http://www.springframework.org/schema/aop"
5. "http://www.springframework.org/schema/context"
6. "http://www.springframework.org/schema/tx"
7. //www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
8. //www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
9. //www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
10. //www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
11.     <aop:aspectj-autoproxy></aop:aspectj-autoproxy>  
12. class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator"
13.   
14. "aspectBean" class="com.spring.aop.TestAnnotationAspect"
15. "aService" class="com.spring.service.AServiceImpl"></bean>  
16. "bService" class="com.spring.service.BServiceImpl"></bean>  
17. </beans>


注意:bean 的路径

测试类:

import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
  public class TestMain {

	/**
	 * @param args
	 */
	public static void testSpringAOP(){
	ApplicationContext ctx = new ClassPathXmlApplicationContext("config/applicationContext.xml");
    
	AService aService = (AService)ctx.getBean("aService");
	aService.fooA("zhangsan");
	}
	public static void main(String[] args) {
		testSpringAOP();
	}

}

运行测试结果:

进入方法---环绕通知
前置通知
进入方法---环绕通知
前置通知
AServiceImpl.fooA(msg:zhangsan)
退出方法---环绕通知
最终通知
后置通知
---null---
退出方法---环绕通知
最终通知
后置通知
---null---

关于切入点表达式,大家需要好好练习才能深入理解其中含义。即使看的懂,但是写起来却非常麻烦,并没有想象中那么简单。

最后,再告诉大家:

任何通知(Advice)方法可以将第一个参数定义为 org.aspectj.lang.JoinPoint类型。JoinPoint接口提供了一系列有用的方法, 比如 getArgs() (返回方法参数)、getThis() (返回代理对象)、getTarget() (返回目标)、getSignature() (返回正在被通知的方法相关信息)和 toString() (打印出正在被通知的方法的有用信息。

其中getSignature()返回的Signature对象可强制转换为MethodSignature,其功能非常强大,能获取包括参数名称在内的一切方法信息。