-
Spring框架一般都是基于AspectJ实现AOP操作
- AspectJ不是Spring组成部分,独立AOP框架,一般吧AspectJ和Spring框架一起使用,进行AOP操作
-
基于AspectJ实现AOP操作
- 基于xml配置文件实现
- 基于注解方式实现(使用)
-
在项目中引入AOP依赖
- 使用maven
-
切入点表达式
- 切入点表达式作用:知道对哪个类型里面的哪个方法进行增强
- 语法结构:execution(【权限修饰符】【返回类型】【类全路径】【参数列表】)
举例1:对com.qi.dao.BookDao类里面的add进行增强
execution(* com.qi.dao.BookDao.add(…))
举例2:对com.qi.dao.BookDao类里面的所有方法进行增强
execution(* com.qi.dao.BookDao.*(…))
举例3:对com.qi.dao包里面的所有类,类中的所有方法进行增强
execution(* com.qi.dao.* .*(…))
AOP操作(AspectJ注解)
-
创建一个类,在类中定义方法
public class User { public void add(){ System.out.println("执行add方法。。。。。"); } }
-
创建增强类(编写增强逻辑)
public class UserProxy { public void before(){ System.out.println("在add方法之前执行。。。"); } }
-
进行通知的配置
-
在Spring配置文件中,开启注解扫描
<!-- 开启注解扫描--> <context:component-scan base-package="com.qi.annoAOP"></context:component-scan>
-
使用注解创建User和UserProxy对象
@Component public class User { public void add(){ System.out.println("执行add方法。。。。。"); } }
@Component public class UserProxy { //前置通知 public void before(){ System.out.println("在add方法之前执行。。。"); } }
-
在增强类上面添加注解@AspectJ
@Component @Aspect //生产代理对象 public class UserProxy { //前置通知 public void before(){ System.out.println("在add方法之前执行。。。"); } }
-
在Spring配置文件中开启生产代理对象
<!-- 开启AspectJ 生成代理对象--> <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
-
-
配置不同的类型通知
- 在增强类的里面,在作为通知方法上面添加通知类型的注解,使用切入点表达式配置
//增强的类 @Component @Aspect //生产代理对象 public class UserProxy { //前置通知 // 使用Before注解表示作为前置通知 @Before("execution(* com.qi.annoAOP.User.add(..))") public void before(){ System.out.println("前置Before通知。。。"); } //最终通知 @After("execution(* com.qi.annoAOP.User.add(..))") public void after(){ System.out.println("后置After通知。。。"); } //后置通知,在程序有返回值的时候执行 @AfterReturning("execution(* com.qi.annoAOP.User.add(..))") public void afterReturning(){ System.out.println("afterReturning通知。。。"); } //出现异常才执行 @AfterThrowing("execution(* com.qi.annoAOP.User.add(..))") public void afterThrowing(){ System.out.println("AfterThrowing通知。。。"); } //环绕通知 @Around("execution(* com.qi.annoAOP.User.add(..))") public void around(ProceedingJoinPoint proceedingJoinPoint){ System.out.println("环绕之前。。。"); try { proceedingJoinPoint.proceed(); } catch (Throwable throwable) { throwable.printStackTrace(); } System.out.println("环绕之后。。。"); } }
-
公共切入点的提取
@Component
@Aspect //生产代理对象
public class UserProxy {
@Pointcut("execution(* com.qi.annoAOP.User.add(..))")
public void pointDemo(){
}
//前置通知
// 使用Before注解表示作为前置通知
@Before("pointDemo()")
public void before(){
System.out.println("前置Before通知。。。");
}
}
-
有多个增强类对同一方法进行增强,设置增强类优先级
- 在增强类上面增加注解@Order(数字值),数字值越小,优先级越高
@Component @Aspect @Order(1) public class PersonProxy { //前置通知 @Before("execution(* com.qi.annoAOP.User.add())") public void befor(){ System.out.println("Person的前置通知"); } }
-
完全使用注解开发
@Configuration @ComponentScan(basePackages = {"com.qi"}) @EnableAspectJAutoProxy(proxyTargetClass = true) public class ConfigAOP { }
AOP操作(AspectJ配置文件)
<!-- 使用配置文件 -->
<!-- 创建对象-->
<bean id="book" class="com.qi.xmlAOP.Book"></bean>
<bean id="bookProxy" class="com.qi.xmlAOP.BookProxy"></bean>
<!-- 配置AOP增强-->
<aop:config>
<!-- 切入点-->
<aop:pointcut id="pointcut" expression="execution(* com.qi.xmlAOP.Book.buy(..))"/>
<!-- 切面-->
<aop:aspect ref="bookProxy">
<!-- 增强作用在具体方法上-->
<aop:before method="before" pointcut-ref="pointcut"></aop:before>
</aop:aspect>
</aop:config>