说句实话,在工作中,使用的aop不是特别多,但是特别重要,一般是辅助程序,在现代开发者辅助程序相当重要,比如说我们需要打印一些log,但是我们不可能去卸载我们的业务程序中,因为这太。。。。。
那么如何开启一个aop呢?用log举例,我们不可能去写log在我们的业务程序中,如果是这样的话,是真的难以维护。
下面实例一个需求来显示出一些问题:
/**
 *需求
 * 将一个方法的发生前打印出log,发生后打印log,异常打印log,要求解耦
 * 通知:
 *     前置通知(@Befor)
 *     后置通知 (@After)
 *     返回通知 (@AfterReturning)
 *     异常通知 (@AfterThrowing)
 *     环绕通知(@Around):动态代理,手动推进目标方法运行(joinpoint.procced)
 * 步骤:
 *    1.将业务逻辑组件和切面类都加入到容器中,告诉spring 哪个是切面类,开启基于注解的aop模式@EnableAspectJAutoProxy
 *    2.在切面类上的每一个通知方法上标注通知注解,告诉spring 何时何地运行(切入点表达式)
首先加入容器中:
@Configuration
@EnableAspectJAutoProxy
public class MainConfigofAOP {
    //业务逻辑类加入到容器中
    @Bean
    public MathCalculator calculator(){
        return  new MathCalculator();
    }
    //切面类加入到容器中
    @Bean
    public LogAspects logAspects(){
        return  new LogAspects();
    }
}
将切面类和业务逻辑类加入到容器中,然后开启切面@EnableAspectJAutoProxy。
接下来我们看下如何告诉切面注解实现类,哪个是切面,看下切面类:
/**
 * 切面类
 */
@Aspect
public class LogAspects {
    //公共的切入点表达式
    @Pointcut("execution(public int com.axm.demo.aop.MathCalculator.*(..))")
    public  void pointCut(){
    }
//    @Before("public  int com.axm.demo.aop.div(int i,int j)")
    @Before("pointCut()")
    public  void logStart(JoinPoint joinPoint)
    {
        System.out.println(""+joinPoint.getSignature().getName()+"方法运行前执行,参数是:"+Arrays.asList(joinPoint.getArgs()));
    }
    @After("pointCut())")
    public  void  logEnd(JoinPoint joinPoint)
    {
        System.out.println(""+joinPoint.getSignature().getName()+"方法运行后执行,无论是否异常都会执行");
    }
    @AfterReturning(value="pointCut()",returning = "result")
    public  void resultReturn(JoinPoint joinPoint,Object result)
    {
        System.out.println(""+joinPoint.getSignature().getName()+"方法成功后执行!获取返回结果:"+result);
    }
    @AfterThrowing(value = "pointCut()",throwing = "exception")
    public  void logException(JoinPoint joinPoint,Exception exception)
    {
        System.out.println(""+joinPoint.getSignature().getName()+"方法成功后执行!查看异常:"+exception.getMessage());
    }
}
注解:@Aspect 告诉应用该类为切面类。
@Pointcut("execution(public int com.axm.demo.aop.MathCalculator.*(..))")
是公共表达式,@Before("pointCut()")表示继承pointCut方法的注解。
public int com.axm.demo.aop.MathCalculator.*(..) 表示在MathCalculator 中的所以方法将会被监听。
JoinPoint joinPoint 表示目标方法的一些信息。
这些都可以去文档中查看。
再看下业务逻辑类:
public class MathCalculator {
    public  int div(int i,int j){
        return  i/j;
    }
}
业务逻辑类,就像是正常一样去书写即可,只要加入容器中。
也就是说我们在不影响现在代码的情况下,可以去实现一些辅助功能。
这里,测试一下。
@Test
public  void  test()
{
	AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(MainConfigofAOP.class);
	MathCalculator mathCalculator=applicationContext.getBean(MathCalculator.class);
	mathCalculator.div(1,1);
}
好的,看下结果吧。

即将开启源码模式。
原文:https://www.cnblogs.com/aoximin/p/12952923.html