spring之AspectJ面向切面编程 博客分类: java springbootaop
程序员文章站
2024-02-12 22:15:40
...
spring之AspectJ面向切面编程
面向切面编程,实现方式有三种,最常用的是
1、实现InvocationHandler接口:这样需要根据代理的类
2、基于Spring 的AOP方式:这种和实现接口一样,也需要有个新的类来代理
3、基于Aspectj + 自定义注解来实现,这个很完美,对外调用不需要重写类
使用Aspectj注解实现切面编程
增加jar包:
dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.9</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
</dependency>
切面:
//使用@Aspect实现面向切面编程:如controller方法调用的耗时
@Aspect
@Component
public class TimerAspectInterceptor {
private Logger logger = LoggerFactory.getLogger(TimerAspectInterceptor.class);
@Pointcut("execution(* cn.web.controller.UserController..*(..))")
public void controllerMethodPointCut() {
}
//匹配那些有指定注解的连接点@Logable(带用这个注解的所有方法作为连接点)
@Pointcut("@annotation(cn.web.controller.Logable)")
public void multiMethodPointCut() {
}
/*@Before(value="controllerMethodPointCut()")
public void before2(JoinPoint point) {
Object[] args = point.getArgs();
logger.info("before..args={}", args.length);
}
@Before(value = "beforePointcut(param)", argNames = "param")
public void beforeAdvice(String param) {
System.out.println("===========before advice param:" + param);
}
@After("controllerMethodPointCut()")
public void after() {
logger.info("after..");
}
@AfterReturning(value = "controllerMethodPointCut()")
public void afterReturn() {
logger.info("afterReturn..");
}
*/
@AfterThrowing(value = "controllerMethodPointCut()")
public void afterThrow() {
logger.info("afterThrow..");
}
//@Around(value = "controllerMethodPointCut() || multiMethodPointCut()")
//@Around(value = "controllerMethodPointCut()")
@Around("multiMethodPointCut()") //环饶通知如果原有抛出异常,会调用afterThrow()
public void aroundControllerMethod(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
//回调目标的原有方法
joinPoint.proceed();
logger.info("op=look method={} cost={}", joinPoint.getSignature().getName(),
System.currentTimeMillis() - start);
}
}
连接点:
使用注解作为连接点
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Logable {
//long timeoutMillis() default 0;
}
面向切面编程,实现方式有三种,最常用的是
1、实现InvocationHandler接口:这样需要根据代理的类
2、基于Spring 的AOP方式:这种和实现接口一样,也需要有个新的类来代理
3、基于Aspectj + 自定义注解来实现,这个很完美,对外调用不需要重写类
使用Aspectj注解实现切面编程
增加jar包:
dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.9</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
</dependency>
切面:
//使用@Aspect实现面向切面编程:如controller方法调用的耗时
@Aspect
@Component
public class TimerAspectInterceptor {
private Logger logger = LoggerFactory.getLogger(TimerAspectInterceptor.class);
@Pointcut("execution(* cn.web.controller.UserController..*(..))")
public void controllerMethodPointCut() {
}
//匹配那些有指定注解的连接点@Logable(带用这个注解的所有方法作为连接点)
@Pointcut("@annotation(cn.web.controller.Logable)")
public void multiMethodPointCut() {
}
/*@Before(value="controllerMethodPointCut()")
public void before2(JoinPoint point) {
Object[] args = point.getArgs();
logger.info("before..args={}", args.length);
}
@Before(value = "beforePointcut(param)", argNames = "param")
public void beforeAdvice(String param) {
System.out.println("===========before advice param:" + param);
}
@After("controllerMethodPointCut()")
public void after() {
logger.info("after..");
}
@AfterReturning(value = "controllerMethodPointCut()")
public void afterReturn() {
logger.info("afterReturn..");
}
*/
@AfterThrowing(value = "controllerMethodPointCut()")
public void afterThrow() {
logger.info("afterThrow..");
}
//@Around(value = "controllerMethodPointCut() || multiMethodPointCut()")
//@Around(value = "controllerMethodPointCut()")
@Around("multiMethodPointCut()") //环饶通知如果原有抛出异常,会调用afterThrow()
public void aroundControllerMethod(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
//回调目标的原有方法
joinPoint.proceed();
logger.info("op=look method={} cost={}", joinPoint.getSignature().getName(),
System.currentTimeMillis() - start);
}
}
连接点:
使用注解作为连接点
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Logable {
//long timeoutMillis() default 0;
}