+-
1.什么是AOP
面向切面编程
AOP底层使用动态代理
(1)有接口情况 【使用JDK动态代理】
创建代理对象
要想创建一个代理对象,需要使用Proxy类的newProxyInstance方法。这个方法有三个参数:
(2)无接口情况 【使用CGLIB动态代理】
AOP术语
(1)连接点:可以被增强的方法就是连接点
(2)切入点:实际被增强的方法就是切入点
(3)通知【增强】:实际增强方法中增强的部分
- 前置通知
- 后置通知
- 环绕通知
- 异常通知
- 最终通知
(4)切面:
使用AspectJ进行AOP操作
execution(权限修饰符 返回类型 类全路径 方法名称(参数列表))
(1)创建类
@Component
public class User {
public void add(){
System.out.println("add...");
}
}
(2)创建增强类
@Component
@Aspect
public class UserProxy {
//前置通知
@Before(value = "execution(* com.example.demo.entity.User.add())")
public void before(){
System.out.println("before...");
}
//最终通知[有没有异常都会执行]
@After(value = "execution(* com.example.demo.entity.User.add())")
public void after(){
System.out.println("after...");
}
//后置通知
@AfterReturning(value = "execution(* com.example.demo.entity.User.add())")
public void afterReturing(){
System.out.println("afterReturning...");
}
//异常通知
@AfterThrowing(value = "execution(* com.example.demo.entity.User.add())")
public void afterThrowing(){
System.out.println("afterThrowing...");
}
//环绕通知
@Around(value = "execution(* com.example.demo.entity.User.add())")
public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("around before...");
proceedingJoinPoint.proceed();
System.out.println("around after...");
}
}
(3)进行通知的配置
1. 在Spring配置文件中,开启注解开发
2. 使用注解创建User和UserProxy对象
3. 在增强类上面添加注解@Aspect
4. 在Spring配置文件中开启生成代理对象
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--开启注解扫描-->
<context:component-scan base-package="com.example.demo.entity"></context:component-scan>
<!--开启Aspect生成代理对象-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
(4)公共切入点抽取
@Pointcut(value = "execution(* com.example.demo.entity.User.add())")
public void point(){
}
//前置通知
@Before(value = "point()")
public void before(){
System.out.println("before...");
}
(5)增强类优先级【多个增强类对同一方法进行增强】
增强类上添加注解@Order(数字类型值),数字值越小优先级越高