- 面向切面编程,利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可复用性,同时提高开发效率
- 简单来说:就是在不修改源代码的情况下,在主干功能中添加新的功能
-
有接口的情况下,使用JDK的动态代理
-
没有接口的情况下,使用cglb的动态代理
- 连接点:类中可以被增强的方法,都称为连接点
- 切入点:实际被增强的方法,称为切入点
- 通知(增强):实际增强的逻辑部分被称为通知(增强)
- 通知有多种类型:
- 前置通知
- 后置通知
- 环绕通知
- 异常通知
- 最终通知
- 通知有多种类型:
- 切面:把通知应用到切入点的过程被称为切面
- Spring中的AOP是基于AspectJ框架的,AspectJ是独立的AOP框架
- 基于AspectJ实现AOP有两种方式
- 基于xml配置文件实现
- 基于注解方式实现
- 导入AOP的依赖
-
切点表达式的作用:知道对那个类里面的那个方法进行增强
-
语法构造: execution([权限修饰符][返回值类型][类全路径][方法名称][参数列表])
-
看下面例子:
//举例1:对com.mnyuan.dao.UserDao里面的add()方法进行增强 //* 用来代表全部 execution(* com.mnyuan.dao.UserDao.add(..)) //举例2:对com.mnyuan.dao.UserDao类里面的所有方法进行增强 execution(* com.mnyuan.dao.UserDao.*(..)) //举例3:对com.mnyuan.dao暴力所有的类,类里面所有的方法进行增强 execution(* com.mnyuan.dao.*.*(..))
-
配置xml文件,开启注解扫描和开启Aspect,要导入context和aop的约束
-
编写被增强类
@Repository public class UserDao { public void add(){ int i = 1/0; System.out.println("Add...方法"); } } -
编写增强类,使用@Aspect注解标注
@Repository @Aspect//标志这是一个增强代理类 public class UserDaoProxy { //方法执行前增强 @Before(value = "execution(* day01.aopanno.dao.UserDao.add(..))") public void beforeMethod(){ System.out.println("@Before注解对方法进行前置增强"); } //方法执行后增强 @AfterReturning(value = "execution(* day01.aopanno.dao.UserDao.add(..))") public void afterReturning(){ System.out.println("@AfterReturning注解对方法进行后置增强"); } //最终增强,一定会执行,类似finally关键字 @After("execution(* day01.aopanno.dao.UserDao.add(..))") public void afterMethod(){ System.out.println("@After注解对象方法进行最终增强"); } //环绕增强 @Around("execution(* day01.aopanno.dao.UserDao.add(..))") public void aroundMethod(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("在之前增强"); joinPoint.proceed(); System.out.println("在之后增强"); } @AfterThrowing("execution(* day01.aopanno.dao.UserDao.add(..))") public void AfterThrowing(){ System.out.println("@AfterThrowing在出现异常后增强"); } }
@Pointcut("execution(* day01.aopanno.dao.UserDao.add(..))")
public void point(){
}
//方法执行前增强
@Before(value = "point()")
public void beforeMethod(){
System.out.println("@Before注解对方法进行前置增强");
}
8、aop细节问题
-
设置多个增强类对同一方法增强的优先级
- 使用@Order()注解传入int类型的值,值越小,优先级越高
-
全注解开发
-
@Configuration //表示这个一个配置类,用来代替xml文件 @ComponentScan(basePackages = {"day01.annotation"})//表示包扫描 @EnableAspectJAutoProxy(proxyTargetClass = true) //用来代替xml中的 public class SpringConfig { }
-
-
编写被增强类
public class BookDao { public void buy(){ System.out.println("buy方法"); } } -
编写增强类
public class BookDaoProxy { public void before(){ System.out.println("before增强"); } } -
xml配置文件



