AOP方法上的注解有:
@Before():这个是前置调用,在方法之前掉调用
@After() 这个称为后置调用,不管方法执行是正常还是异常都会调用
@Around() 这个表示的是环绕 在调用方法之前和之后调用 一般用来记录日志,需要joinPoint.proceed()推动目标进行
@AfterReturning()这个表示的是正常运行后,返回数据的时候调用
@AfterThrowing()这个表示的是抛出异常的时候调用
@Aspect:告诉容器这是一个切面类
@Pointcut() :切入点表达式的位置
@EableAspectjAutoProxy:开启基于注解的aop模式,原来是在xml中配置
例子:
1.需要导入包
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
2.业务类
public class Caculator {
public Integer cal(int a,int b) {
System.out.println("Caculator ..cal");
return a/b;
}
}
3.切面类
@Aspect
public class LogsAspects {
@Pointcut("execution( * com.wusu.aop.Caculator.*(..))")
public void pointcut(){};
@Before("pointcut()")
public void logStart(JoinPoint joinPoint){
System.out.println("开始计算"+joinPoint.getSignature().getName()+": 参数是:"+ Arrays.asList(joinPoint.getArgs()).toString());
}
@After("pointcut()")
public void logEnd(JoinPoint joinPoint){
System.out.println("结束计算"+joinPoint.getSignature().getName());
}
//这个JoinPoint必须放在第一个才能使用
@AfterReturning(value = "pointcut()",returning = "result")
public void logReturn(JoinPoint joinPoint,Object result){
System.out.println("开始返回"+joinPoint.getSignature().getName()+",return :"+ result);
}
@Around("pointcut()") //这个必须要有返回值值,否则正常的有返回值的没有结果
public Object logRound(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("环绕执行前。。。参数是:"+joinPoint.getArgs());
Object object = joinPoint.proceed(joinPoint.getArgs());
System.out.println("环绕执行后。。。参数是:"+joinPoint.getArgs());
return object;
}
@AfterThrowing(value = "pointcut()",throwing = "exception")
public void logThrowing(Exception exception){
System.out.println("抛出异常"+exception);
}
}
对于@PointCut里面的表达式解释:
定义切入点表达式
1>:定义一个没有实现的方法
2>:在这个方法上 使用切入点表达式的注解Pointcut
execution ()你记成语法规则
第一个 * 代表的是返回注入方法的返回数据的类型
第二个 * 代表的是UserDAO这个类里面的所有方法
“..” 代表的是注入方法里面的参数类型 这里因为可以是任意类型 所以使用 “..” ,这里是两个点
4. 配置类,业务类和切面类都需要放入IOC容器中
需要使用@EnableAspectJAutoProxy开启自动代理
@EnableAspectJAutoProxy
@Configuration
public class MainConfig {
@Bean
public Caculator caculator(){
return new Caculator();
}
@Bean
public LogsAspects logsAspects(){
return new LogsAspects();
}
}
5.测试类,需要从IOC容器中获取这个业务类才是被代理后的类
public class TestAop {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
Caculator caculator = applicationContext.getBean(Caculator.class);
int cal = caculator.cal(16, 0);
}
}
结果显示:
开始计算cal: 参数是:[16, 0]
Caculator ..cal
结束计算cal
抛出异常java.lang.ArithmeticException: / by zero