要使用注解去配置AOP,首先要在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" xmlns:context="http://www.springframework.org/schema/context"
4 xmlns:aop="http://www.springframework.org/schema/aop"
5 xsi:schemaLocation="http://www.springframework.org/schema/beans
6 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
7 http://www.springframework.org/schema/context
8 http://www.springframework.org/schema/context/spring-context-3.0.xsd
9 http://www.springframework.org/schema/aop
10 http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
11
12 <!-- 开启注解 -->
13 <context:annotation-config />
14 <!-- 指定哪些需要加入扫描 -->
15 <context:component-scan base-package="org.duyt.*" />
16 <!-- 开启AOP切面自动代理 -->
17 <aop:aspectj-autoproxy />
18
19 </beans>
此时,需要加入aop对应的命名空间,虽然搜索一下会有一大堆,但是这种命名空间的声明会在spring-XXX相应的包下找到,要加入aop的声明,可在spring-aop-X.X.X.jar包,META-INF下的spring.schemas,spring.tooling配置文件中找到。
在定义切面之前,还是先理清一些概念
1,切入点(point-cut),核心是切入点表达式,可以确定请求流程中的某一个点。
2,通知(advice),可以理解为在切入点的某个位置(常见如切入点之前,之后,或者环绕着切入点)添加需要拓展的功能,通知包含切入的具体位置和拓展的内容。
3,切面(aspect),一类切入点(比如专门添加日志的切面,或者专门记录异常的切面)可以理解为组成了一个切面,切面包含了切入点和所需要的通知。
下面定义一个切面:
1 package org.duyt.autoProxy;
2
3 import org.aspectj.lang.JoinPoint;
4 import org.aspectj.lang.ProceedingJoinPoint;
5 import org.aspectj.lang.annotation.After;
6 import org.aspectj.lang.annotation.Around;
7 import org.aspectj.lang.annotation.Aspect;
8 import org.aspectj.lang.annotation.Before;
9 import org.duyt.util.Logger;
10 import org.springframework.stereotype.Component;
11
12 /**
13 * Spring使用了第三方AspectJ来实现AOP功能,AOP相关的注解需要添加AspectJ的饮用
14 * @author Administrator
15 *
16 */
17 //注明这是一个切面类
18 @Aspect
19 //添加spring的管理
20 @Component("loggerAspect")
21 public class LoggerAspect {
22 //@Before标注的方法意为将该方法作用于切入点表达式注明的方法之前执行,可以理解为创建一个通知,
23 //关于切入点表达式:execution(* org.duyt.dao.*.add*(..)
24 //第一个*代表着任意类型返回值的方法
25 //之后跟空格,添加一个包的路径,第二个*表示该包路径下的所有类
26 //之后添加“.”,再跟需要切入的方法,此处指定了所有以add,delete,update开头的方法,使用“||”并列连接这些表达式
27 //最后的“(..)”表示任意个数的参数列表
28 @Before("execution(* org.duyt.dao.*.add*(..))||"
29 + "execution(* org.duyt.dao.*.delete*(..))||"
30 + "execution(* org.duyt.dao.*.update*(..))")
31 public void loggerBefore(JoinPoint jp) {
32 // System.out.println(jp.getTarget());//org.duyt.dao.impl.UserDao@71eecfa7,获取执行的对象
33 // System.out.println(jp.getSignature().getName());//add,获取方法签名
34 Logger.info("前置切入点:execute==>" + jp.getTarget() + "==>"
35 + jp.getSignature().getName() + " method");
36 }
37 @After("execution(* org.duyt.dao.*.add*(..))||"
38 + "execution(* org.duyt.dao.*.delete*(..))||"
39 + "execution(* org.duyt.dao.*.update*(..))")
40 public void loggerAfter(JoinPoint jp) {
41 Logger.info("后置切入点:execute==>" + jp.getTarget() + "==>"
42 + jp.getSignature().getName() + " method");
43 }
44 @Around("execution(* org.duyt.dao.*.add*(..))||"
45 + "execution(* org.duyt.dao.*.delete*(..))||"
46 + "execution(* org.duyt.dao.*.update*(..))")
47 public void loggerAround(ProceedingJoinPoint pjp) throws Throwable {
48 Logger.info("环绕开始切入点:execute==>" + pjp.getTarget() + "==>"
49 + pjp.getSignature().getName() + " method");
50 pjp.proceed();//执行方法
51 Logger.info("环绕结束切入点:execute==>" + pjp.getTarget() + "==>"
52 + pjp.getSignature().getName() + " method");
53 }
54 }
55
DAO和Service内容略,测试类如下
1 package org.duyt.test;
2
3 import org.duyt.action.UserAction;
4 import org.junit.Test;
5 import org.springframework.beans.factory.BeanFactory;
6 import org.springframework.context.support.ClassPathXmlApplicationContext;
7
8 public class IocTest {
9
10 private BeanFactory factory = new ClassPathXmlApplicationContext("beans.xml");
11
12 @Test
13 public void test(){
14 //基于annotation的AOP
15 UserAction ua = (UserAction) factory.getBean("userAction");
16 ua.addUser();
17 }
18
19 }
20
结果:
前置切入点:execute==>org.duyt.dao.impl.UserDao@6fc8ddb5==>add method
环绕开始切入点:execute==>org.duyt.dao.impl.UserDao@6fc8ddb5==>add method
用户增加方法
后置切入点:execute==>org.duyt.dao.impl.UserDao@6fc8ddb5==>add method
环绕结束切入点:execute==>org.duyt.dao.impl.UserDao@6fc8ddb5==>add method