欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

spring之AspectJ面向切面编程

程序员文章站 2022-03-13 09:24:47
...
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;
}
相关标签: springboot aop