面向切面编程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);
}

好的,看下结果吧。

总结

即将开启源码模式。

posted @ 2020-05-24 21:53  敖毛毛  阅读(695)  评论(0编辑  收藏  举报