基于XML和注解的Spring的AOP使用
1。首先基于注解配置的AOP使用:(在学习Spring的AOP之前建意先去学习一下Java的JDK动态代理和CGLIB的代理技术,AOP是基于代理实现的,JDK的动态代理需要目标对象实现一个接口,若没有实现接口则可以使用CGLIB,它的代理对象是继承目标对象。)
目标对象的接口如下:
Java代码
1.public interface PersonService {
2.
3. public abstract void save(String name);
4.
5. public abstract String getPersonName(String personId);
6.
7. public abstract void deletePerson(Integer id);
8.}
目标对象(PersonServiceImple):
Java代码
1.public class PersonServiceImple implements PersonService {
2.
3. public void save(String name) {
4. System.out.println("aop.annotation.service.imple.PersonServiceImple的save()方法");
5. // throw new RuntimeException("手动引用的一个异常信息");
6. }
7.
8. public String getPersonName(String personId) {
9.// throw new RuntimeException("手动抛出的异常信息....");
10. return "http://zmx.iteye.com";
11.
12. }
13.
14. public void deletePerson(Integer id){
15. throw new RuntimeException("手动抛出的异常信息....");
16. }
17.}
使用Spring的注解配置一个Spring的切面
Java代码
1.import org.aspectj.lang.ProceedingJoinPoint;
2.import org.aspectj.lang.annotation.After;
3.import org.aspectj.lang.annotation.AfterReturning;
4.import org.aspectj.lang.annotation.AfterThrowing;
5.import org.aspectj.lang.annotation.Around;
6.import org.aspectj.lang.annotation.Aspect;
7.import org.aspectj.lang.annotation.Before;
8.import org.aspectj.lang.annotation.Pointcut;
9.
10.//@Aspect用来标示一个类为切面
11.@Aspect
12.public class MyInterceptor {
13. // @Pointcut用来设置一个切入点。aop.annotation.service..包(子包)内的所有类,所有方法,任何参数
14. @Pointcut("execution(* aop.annotation.service.imple..*.*(..))")
15. private void anyMethod() {
16.
17. }
18.
19. // 使用@Before(切入点)用来表示目标方法执行前执行的操作(前置通知)
20. // @Before("anyMethod()")
21. @Before("anyMethod() && args(nameArg)")
22. // 使用这个方法可以获取参数。即:在原来的切入点条件上加了另一个条件即:拦截方法的参数有一个并且是String类型
23. public void doBefore(String nameArg) {
24. System.out.println("前置通知...拦截方法执行参数:" + nameArg);
25. }
26.
27. // 使用@AfterReturning(切入点)用来表示目标方法执行完执行的操作(后置通知)
28. // @AfterReturning("anyMethod()")
29. @AfterReturning(pointcut = "anyMethod()", returning = "returnArg")
30. // 使用这个方法可以获取返回结果。即:在原来的切入点条件上加了另一个条件即:拦截方法的返回值类型是String类型
31. public void doAfterReturning(String returnArg) {
32. System.out.println("后置通知...拦截方法返回结查:" + returnArg);
33. }
34.
35. // 使用@After(切入点)用来表示目标方法执行无论是否出现异常都执行的操作(最终通知)
36. @After("anyMethod()")
37. public void doFinally() {
38. System.out.println("最终通知...");
39. }
40.
41. // 使用@AfterThrowing(切入点)用来表示目标方法执行出现异常时执行的操作(例外通知)
42. // @AfterThrowing("anyMethod()")
43. @AfterThrowing(pointcut = "anyMethod()", throwing = "ex")
44. public void doException(Exception ex) {
45. System.out.println("例外通知...取获异常信息:" + ex);
46. }
47.
48.
49. // 使用@Around(切入点)用来表示整个通知(环绕通知:该方法必须接受一个org.aspectj.lang.ProceedingJoinPoint类型的参数)
50. @Around("anyMethod()")
51. public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
52. System.out.println("环绕通知之前...");
53. Object result = pjp.proceed();
54. System.out.println("环绕通知之后...");
55. return result;
56. }
57.
58.}
在Spring的配置XML中打开对象上述注解的功能和向Spring容器中注册该目标对象
Xml代码
1.<beans xmlns="http://www.springframework.org/schema/beans"
2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3. xmlns:aop="http://www.springframework.org/schema/aop"
4. xsi:schemaLocation="http://www.springframework.org/schema/beans
5. http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
6. http://www.springframework.org/schema/aop
7. http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
8. <!-- 基于注解方式的声明切面 -->
9. <aop:aspectj-autoproxy />
10.
11. <bean id="personService"
12. + returnArg);
9. }
10.
11. public void doFinally() {
12. System.out.println("最终通知...");
13. }
14.
15. public void doException(Exception ex) {
16. System.out.println("例外通知...取获异常信息:" + ex);
17. }
18.
19. public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
20. System.out.println("环绕通知之前...");
21. Object[] args = pjp.getArgs();
22. for (int i = 0; i < args.length; i++) {
23. System.out.println(args);
24. }
25. Object result = pjp.proceed();
26. System.out.println("环绕通知之后...");
27. return result;
28. }
29.
30.}
在XML配置上述内容:
Xml代码
1.<beans xmlns="http://www.springframework.org/schema/beans"
2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3. xmlns:aop="http://www.springframework.org/schema/aop"
4. xsi:schemaLocation="http://www.springframework.org/schema/beans
5. http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
6. http://www.springframework.org/schema/aop
7. http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
8.
9. <bean id="personService"
10. ref="myInterceptor">
19. <aop:pointcut id="myAnyMethod"
20. expression="execution(* aop.xml.service.imple.*.*(..))" />
21. <aop:before pointcut-ref="myAnyMethod" method="doBefore"/>
22. <aop:after-returning method="doAfterReturning" pointcut-ref="myAnyMethod" returning="returnArg"/>
23. <aop:after-throwing method="doException" pointcut-ref="myAnyMethod" throwing="ex"/>
24. <aop:after method="doFinally" pointcut-ref="myAnyMethod"/>
25. <aop:around method="doAround" pointcut-ref="myAnyMethod"/>
26. </aop:aspect>
27. </aop:config>
28.
29.</beans>
测试:
Java代码
1.public static void main(String[] args) {
2. ApplicationContext ctx = new ClassPathXmlApplicationContext(
3. "beansAOP2.xml");
4. PersonService personService = (PersonService) ctx.getBean("personService");
5.// personService.save("AOP");
6. personService.getPersonName("123");
7.
8. }