/** 步骤
* 1、导入aop依赖
* 2、创建一个业务逻辑类MathCalculator,用于切面切入进去在(方法之前,之后,正常,异常运行)是调用
* 3、定义一个日志切面类。(LogAspects),它往业务逻辑切面
* 通知方法:
* 前置通知:(@Before),logStart,在目标方法(div)之前执行:
* 后置通知:(@After),logEnd,在目标方法(div)完之后执行,无论是正常和异常结束都执行
* 返回通知:(@AfterReturning),logReturn,在目标方法(div)正常返回执行
* 异常通知:(@AfterThrowing),logException,在目标方法(div)出现异常执行
* 环绕通知:(@Around):动态代理,手动推进目标方法运行(joinpoint.procced())
* 4、给切面类的目标方法标注何时何地运行(通知注解)
* 5、将业务逻辑类和切面类都加入到容器中
* 6、在切面类上添加@Aspects注解
* 7、给容器中添加@EnableAspectJAutoProxy 【开启基于注解aop模式】
*
*/
容器
@EnableAspectJAutoProxy
@Configuration
public class ConfigurationOfAop {
//业务逻辑类加入到容器中
@Bean
public MathCalculator mathCalculator() {
return new MathCalculator();
}
//切面类加入到容器中
@Bean
public LogAspects logAspects() {
return new LogAspects();
}
}
业务逻辑类,等着被切面
public class MathCalculator {
public int div(int i,int j) {
System.out.println("MathCalculator");
return i/j;
}
}
切面类
@Aspect
public class LogAspects {
//抽取公共的切入点表达式
//1.本类引用
//2.其他切面引用
//3.使用规则:execution(修饰符,返回类型,全方法名,参数,参数可以使用通配符)。
//4.好处可以把多个方法设置为被切面。String不灵活
@Pointcut("execution(public int com.cqvie.aop.MathCalculator.*(..))")
public void pointCut1() {}
@Pointcut("execution(public int com.cqvie.aop.MathCalculator2.*(..))")
public void pointCut2() {}
@Pointcut("pointCut1() || pointCut2()") //第一个条件或者第二个条件满足都执行切面
public void pointCut() {}
//在注解上写上方法的名称。
@Before("pointCut()")
public void logStart(JoinPoint joinpoint){
Object[] args = joinpoint.getArgs(); //获取参数的数组
System.out.println(joinpoint.getSignature().getName()+"除法运算。。。。参数列表是:{"+Arrays.asList(args)+"}");
}
@After("pointCut()")
public void logEnd(JoinPoint joinpoint) {
System.out.println(joinpoint.getSignature().getName()+"除法结束。。。。");
}
@AfterReturning(value = "pointCut()",returning="result") //结果放在result
public void logReturn(JoinPoint joinpoint,Object result) { //接收所有返回数据类型
System.out.println(joinpoint+"除法正常返回。。。。运行结果:{"+result+"}");
}
@AfterThrowing(value = "pointCut()",throwing="exception")
public void logException(JoinPoint joinpoint,Exception exception) {
System.out.println(joinpoint.getSignature().getName()+"除法异常。。。。异常信息:{"+exception+"}");
}
}
joinpoint必须放在第一个参数,它可以获取它切面切入方法的相关信息,参数,名称等
测试类
@Test
@SuppressWarnings("resource")
public void test() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(
ConfigurationOfAop.class);
//1、这个对象不要自己创建,要从容器中使用才有切面的效果
// MathCalculator mathCalculator2 = new MathCalculator();
// mathCalculator2.div(1, 1);
MathCalculator mathCalculator = applicationContext.getBean(MathCalculator.class);
mathCalculator.div(8, 2);
applicationContext.close();
}