-
定义切面类
-
切面类进行增强的两种写法
-
切点匹配注解和规则
切面类定义
-
引入相应的aop包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency> -
定义切面类(类名自定义)
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class DatabaseResourceToggle {
}
切入点定义注解说明
@Pointcut :用来定义一个切面(切入点),即所关注的某件事情的入口。切入点决定了连接点关注的内容,使得我们可以控制通知什么时候执行。
切入点表达式说明
先说明两个通配符:*、..
-
*:主要用于匹配单个单词,或者是以某个词为前缀或后缀的单词
-
..:表示0个或多个项。主要用于类全路径或者参数,用于类全路径中表示匹配当前包及其子包,如果用于参数中,则表示匹配0个或多个参
1、匹配使用自定义注解的方法:
@Pointcut("@annotation()")
@Pointcut("@within()")
@Pointcut("@args()")
@Pointcut("@target()")
2、匹配对象下的方法:
@Pointcut("this()")
@Pointcut("bean()")
@Pointcut("target()")
3、匹配方法和参数:
@Pointcut("within()")
@Pointcut("args()")
@Pointcut("execution()")
@Pointcut("@annotation(com.gzt.annotation.DatabaseResourcedefine)"):匹配方法上有DatabaseResourcedefine注解的方法
@Pointcut("@within(com.gzt.annotation.DatabaseResourcedefine)"):匹配有DatabaseResourcedefine注解标记的类里面的方法(最常用)
@Pointcut("@args(com.gzt.annotation.DatabaseResourcedefine)"):匹配传入的参数有DatabaseResourcedefine注解标记的方法
@Pointcut("@target(com.gzt.annotation.DatabaseResourcedefine)"):匹配有DatabaseResourcedefine注解标记的类及其子类里面的方法
@Pointcut("this(com.gzt.annotation.DatabaseResourcedefine)"):匹配AOP对象的目标对象为指定类型的方法
@Pointcut("target(com.gzt.annotation.DatabaseResourcedefine)"):匹配实现DatabaseResourcedefine接口的目标对象里面的方法
@Pointcut("bean(DatabaseResourcedefine)"):匹配指定的bean
@Pointcut("within(com.gzt.annotation.DatabaseResourcedefine)"):匹配指定包下的方法
@Pointcut("args(Long,..)"):匹配任何以Long参数开头的方法(一般搭配其他匹配条件使用)
@Pointcut("execution(* com.gzt.service.implTestImpl.*(..))"):匹配某个方法(最常用)
@within、execution两个一般最常用,使用@within+自定义注解,可以很好的对某一个类下面的方法进行增强,execution用来匹配单个的
增强方式
@before(前置通知): 在方法开始执行前执行
@after(后置通知): 在方法执行后执行
@afterReturning(返回后通知): 在方法返回后执行
@afterThrowing(异常通知): 在抛出异常时执行
@around(环绕通知): 在方法执行前和执行后都会执行
例子:
public class DatabaseResourceToggle {
final Logger logger = LoggerFactory.getLogger(getClass());
@Pointcut("execution(* com.gzt.service.implTestImpl.*(..))")
//@Pointcut("@within(com.gzt.annotation.DatabaseResourcedefine)")
public void pointCut() {}
@Before(value = "pointCut()")
public void before1(JoinPoint joinPoint) {
Object[] args = joinPoint.getArgs();
for (Object arg : args) {
System.out.println(arg.toString());
}
Object target = joinPoint.getTarget();
System.out.println(target.getClass().getTypeName());
Object target1 = joinPoint.getTarget();
DatabaseResourcedefine annotation = target1.getClass().getAnnotation(DatabaseResourcedefine.class);
String value = annotation.value();
System.out.println("value:"+value);
DatabaseAdapt.flag = value;
logger.info(value);
}
//使用前置通知或者是环绕通知
//@Before("@annotation(databaseResourcedefine) || @within(databaseResourcedefine)")
//public void before(JoinPoint joinPoint, DatabaseResourcedefine databaseResourcedefine) {
// String value = databaseResourcedefine.value();
// DatabaseAdapt.flag = value;
// logger.info(value);
//}
}