Spring AOP的用法总结

如果说通过继承,实现是一种竖向获取其他类功能的方式,

那么: 切面则是一种横向获取其他类功能的方式.

如何实现AOP?

1. 引入依赖:

<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2. 添加支持:

@SpringBootApplication
@MapperScan("com.xuejian.mybatis.dao")
@EnableAspectJAutoProxy // 开启AOP注解支持
public class App {
public static void main (String[] args) {
SpringApplication.run(App.class, args);
}
}

3. 具体使用:

  3.1 普通使用: A方法想增加B,C逻辑,就把A的路径分别配在B,C上面

@Component
@Aspect
public class MyLog {
@Before("execution(* com.xuejian.mybatis.service.UserService.getUser(..))")
public void logBefore (JoinPoint point) {
Object[] args = point.getArgs();
for (Object arg : args) {
System.out.println(arg);
}
}
@After("execution(* com.xuejian.mybatis.service.UserService.getUser(..))")
public void logAfter (JoinPoint point) {
Object[] args = point.getArgs();
for (Object arg : args) {
System.out.println(arg);
}
}
}
---------------------------------------------------------------------------
public User getUser (String id) {
Map<String, Object> map = this.map;
IUserDao bean = context.getBean(IUserDao.class);
return userDao.getUser(id);
}

  3.2 抽取使用: A方法想增加B,C逻辑,就把A的路径抽取出来声明为切点P, 然后把P分别配在B,C上面(优势: P比路径简单,且如果改路径,只需改一处)

@Component
@Aspect
public class MyLog {
@Pointcut("execution(* com.xuejian.mybatis.service.UserService.getUser(..))")
public void cut(){}

@Before("cut()")
public void logBefore (JoinPoint point) {
Object[] args = point.getArgs();
for (Object arg : args) {
System.out.println(arg);
}
}
@After("cut()")
public void logAfter (JoinPoint point) {
Object[] args = point.getArgs();
for (Object arg : args) {
System.out.println(arg);
}
}
}
---------------------------------------------------------------------------
public User getUser (String id) {
Map<String, Object> map = this.map;
IUserDao bean = context.getBean(IUserDao.class);
return userDao.getUser(id);
}

  3.3 进一步抽取使用:A,D,E,F,G,H,...Y,Z方法都想增加B,C逻辑,弄个中间层注解Anno,把Anno的路径抽取出来声明为切点P,然后把P分别配在B,C上面,然后在A,D,E,F,G,H,...Y,Z方法上贴Anno注解

@Component
@Aspect
public class MyLog {
@Before("@annotation(com.xuejian.mybatis.annotation.MyLogAnnotation)")
public void logBefore (JoinPoint point) {
Object[] args = point.getArgs();
for (Object arg : args) {
System.out.println(arg);
}
}
}
---------------------------------------------------------
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyLogAnnotation {
}
---------------------------------------------------------
@MyLogAnnotation
public User getUser (String id) {
Map<String, Object> map = this.map;
IUserDao bean = context.getBean(IUserDao.class);
return userDao.getUser(id);
}

 总结:

1. 前两种方法是被动增强,后一种方法是主动增强

2. 使用基于注解的AOP,更灵活,因为使用它就像使用开关一样

原文地址:https://www.cnblogs.com/wangxuejian/p/13694060.html