简单解释下AOP
能在程序运行期间,能动态的将某段代码切入到指定的位置进行运行的编程方式
测试过程
* 1、模块导入spring-aspects
* 2、定义一个业务逻辑类MathCalculator,在业务逻辑运行的时候,将日志进行打印
* 3、定义一个日志切面类:LogAspect,需要感知MathCalculator运行到哪里,并进行执行
* 通知方法:
* 前置通知(@Before):logStart
* 后置通知(@After):logEnd
* 返回通知(@AfterReturning):logReturn
* 异常通知(@AfterThrowing):logException
* 环绕通知(@Around):动态代理,手动推进目标方法的运行(joinPoint.procced())
* 4、给切面类的目标方法标注何时何地运行
* 5、将切面类和业务逻辑类都加入到容器中
* 6、告诉Spring,哪个类是切面类(给切面类上家一个注解)
* 7、需要给配置类加上@EnableAspectJAutoProxy,表示【开启基于注解的AOP模式】
* 在spring中有很多的Enable开头的注解,都是开启某个基于注解的功能
逻辑类
/**
* @author huangxiaoting
* @date 2019/8/26 15:24
*/
public class MathCalculator {
public int div(int i,int j){
return i/j;
}
}
切面类
/**
* @author huangxiaoting
* @date 2019/8/26 15:27
*/
//目的是告诉spring,这是一个切面类
@Aspect
public class LogAspect {
@Pointcut("execution(public int com.dwd.snail.testspring.test.aop.MathCalculator.*(..))")
public void pointCut(){
}
@Before("pointCut()")
//JoinPoint一定要出现在参数比表的第一位
public void logStart(JoinPoint joinPoint){
Object[] args = joinPoint.getArgs();
System.out.println(""+ joinPoint.getSignature().getName()+"运行。。。参数列表是:{"+ Arrays.asList(args) +"}");
}
@After("com.dwd.snail.testspring.test.aop.LogAspect.pointCut()")
public void logEnd(JoinPoint joinPoint){
System.out.println(""+ joinPoint.getSignature().getName()+"除法结束。。。");
}
@AfterReturning(value = "pointCut()",returning = "result")
public void logReturn(Object result){
System.out.println("除法正常返回。。。计算结果是:{"+result+"}");
}
@AfterThrowing(value ="pointCut()",throwing = "exception")
public void logException(Exception exception){
System.out.println("除法异常。。。异常信息是:{"+exception+"}");
}
}
配置类
@EnableAspectJAutoProxy
@Configuration
public class MainConfigOfAOP {
//业务逻辑类加入到容器中
@Bean
public MathCalculator mathCalculator(){
return new MathCalculator();
}
//切面类也加入到容器中
@Bean
public LogAspect logAspect(){
return new LogAspect();
}
}
测试类
public class IocTest_Aop {
AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(MainConfigOfAOP.class);
@Test
public void test01(){
// printBeans(applicationContext);
// applicationContext.close();
MathCalculator mathCalculator = applicationContext.getBean(MathCalculator.class);
mathCalculator.div(1,1);
//这种方式是是普通的new一个实例对象,并没有交给spring容器管理,所以切面的功能也不会渗透进去
// MathCalculator mathCalculator2=new MathCalculator();
// mathCalculator2.div(1,2);
}
// private void printBeans(AnnotationConfigApplicationContext applicationContext){
// String[] names=applicationContext.getBeanDefinitionNames();
// for (String name:names){
// System.out.println(name);
// System.out.println(applicationContext.getBean(name));
// }
// }
}
正常的结果展示
div运行。。。参数列表是:{[1, 1]}
div除法结束。。。
除法正常返回。。。计算结果是:{1}
异常的结果展示
div运行。。。参数列表是:{[1, 0]}
div除法结束。。。
除法异常。。。异常信息是:{java.lang.ArithmeticException: / by zero}