• 面向切面编程AOP[一](java 代码详解)


    前言

    说句实话,在工作中,使用的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);
    }
    

    好的,看下结果吧。

    总结

    即将开启源码模式。

  • 相关阅读:
    socket错误码获取
    代码整洁之道读书笔记函数
    算法学习之堆排序
    包含与继承区别
    提高 LayerBacked Memory Use
    RenderBuffer
    算法学习之快速排序
    NSTimer
    DNS and BIND ... (转载) zhumao
    Samba学习笔记(转载) zhumao
  • 原文地址:https://www.cnblogs.com/aoximin/p/12952923.html
Copyright © 2020-2023  润新知