AOP术语
- 1、连接点:类里面可以被增强的方法
- 2、切入点:实际被增强的方法
- 3、通知(增强):实际增强的逻辑部分。通知类型有多种:前置通知@Before、后置通知@AfterReturning、环绕通知@Around、异常通知@AfterThrowing、最终通知@After
- 4、切面:是动作,吧通知应用到接入点过程
1、Spring 框架一般都是基于 AspectJ 实现 AOP 操作
(1)AspectJ 不是 Spring 组成部分,独立 AOP 框架,一般把 AspectJ 和 Spirng 框架一起使用,进行 AOP 操作
2、基于 AspectJ 实现 AOP 操作
- (1)基于 xml 配置文件实现
- (2)基于注解方式实现
3、切入点表达式
- (1)切入点表达式作用:知道对哪个类里面的哪个方法进行增强
- (2)语法结构: execution([权限修饰符] [返回类型] [类全路径] [方法名称]([参数列表]) )返回类型可不写
- 例如:execution(* com.dao.BookDao.add(…)) *表示全部
4、执行顺序为:
①无错误情况
- @Around环绕之前
- @Before前置通知
- 被增强方法add
- @Around环绕之后
- @After最终通知
- @AfterReturning后置通知
②、有错误情况
- @Around环绕之前
- @Before前置通知
- @After最终通知
- @AfterThrowing异常通知
(1)、基于注解方式实现
①创建配置类
@Configuration
@ComponentScan(value = "com.springtest.aopanno")
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class SpringConfig {
}
②创建被增强类
@Component
public class User {
public void add() {
System.out.println("add .......................");
}
}
③创建代理类、并使用@Pointcut注解抽离相同的切入点
@Component
@Aspect //生成代理对象
public class UserProxy {
// 抽取相同切入点
@Pointcut(value = "execution(* com.springtest.aopanno.User.add())")
public void pointdemo() {
}
// 前置通知
// @Before(value = "execution(* com.springtest.aopanno.User.add())")
@Before(value = "pointdemo()")
public void before() {
System.out.println("before ..................");
}
// 最终通知
// @After(value = "execution(* com.springtest.aopanno.User.add())")
@After(value = "pointdemo()")
public void after() {
System.out.println("after ..................");
}
// 后置通知 返回值之后执行
// @AfterReturning(value = "execution(* com.springtest.aopanno.User.add())")
@AfterReturning(value = "pointdemo()")
public void afterReturning() {
System.out.println("afterReturning ..................");
}
// 异常通知
// @AfterThrowing(value = "execution(* com.springtest.aopanno.User.add())")
@AfterThrowing(value = "pointdemo()")
public void afterThrowing() {
System.out.println("afterThrowing ..................");
}
// 环绕通知
// @Around(value = "execution(* com.springtest.aopanno.User.add())")
@Around(value = "pointdemo()")
public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("around环绕之前 ..................");
// 执行被增强的方法
proceedingJoinPoint.proceed();
System.out.println("around环绕之后 ..................");
}
}
当一个方法被多个同种通知修饰时可使用 @Order(1)") 注解指定其优先级,数值越小优先级越高
@Before(value = “execution(* com.springtest.aopanno.User.add())”)
@Order(1)
public void before1() {
System.out.println(“before …”);
}
@Before(value = “execution(* com.springtest.aopanno.User.add())”)
@Order(2)
public void before2() {
System.out.println(“before …”);
}
(1)、基于xml方式实现
<!--创建对象-->
<bean id="book" class="com.springtest.aopxml.Book"></bean>
<bean id="bookProxy" class="com.springtest.aopxml.BookProxy"></bean>
<!--配置aop增强-->
<aop:config>
<!--切入点-->
<aop:pointcut id="p" expression="execution(* com.springtest.aopxml.Book.buy(..))"/>
<!--配置切面-->
<aop:aspect ref="bookProxy">
<!--增强作用在具体的方法上-->
<aop:before method="beafter" pointcut-ref="p"/>
</aop:aspect>
</aop:config>