zoukankan      html  css  js  c++  java
  • Spring-AOP的五种通知和切面的优先级、通知变量声明

    SpringAOP的通知分为以下五种:

    1前置通知(@before)
    在连接点执行之前执行的代码

    2后置通知(@after)
    在连接点执行之后执行的代码,不管连接点执行后是否出现异常,后置通知都会执行,但是不能访问连接点返回值

    3返回通知
    返回通知:就是可以获取连接点的返回值,
          当连接点执行之后,若没有异常,则执行返回通知,返回通知在后置通知执行后才会执行

    4异常通知
    在连接点执行的时候,若出现异常,则会执行异常通知,可以根据异常类型来定义执行对应的异常通知

    5环绕通知
    相当于一个动态代理,也就是说其动能包括了前面四个通知的功能,

    示例代码:

    package com.jeremy.aop.example;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.After;
    import org.aspectj.lang.annotation.AfterReturning;
    import org.aspectj.lang.annotation.AfterThrowing;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.springframework.stereotype.Component;
    /*
     * 使用AOP的步骤
     * 1声明一个切面,切面必须是在IOC容器中,所以必须添加@component注解,而且还说明是一个切面,所以还要添加@Aspect注解
     * 2定义通知:通知有五种,分别是前置通知、后置通知、返回通知、异常通知、环绕通知,根据业务需求定义所需的通知
     * 3在通知里说明通知时由那个类的那个方法执行
     * 4在Spring的配置文件自动扫描<context:component-scan>和配置AspectJ
     * 配置AspectJ是当我们调用一个目标方法时,而这个目标方法跟我注解声明的方法相匹配的时候,那么AOP框架应该自动的为那个方法所在的那个类生成一个代理对象,
     * 在我目标方法执行之前先来执行切面的对应的方法
     */
    
    @Aspect
    @Component
    public class LoggingAspect {
    	@Before("execution(* com.jeremy.aop.example.ArithmeticCalculator.*(..))")
    	private void beforeMethod() {
    		System.out.println("the Method begins........");
    
    	}
    	
    	
    	@After("execution(* com.jeremy.aop.example.ArithmeticCalculator.*(..))")
    	private void afterMethod() {
    		// TODO Auto-generated method stub
    		System.out.println("The Method after ................");
    	}
    	
    	@AfterReturning(value="execution(* com.jeremy.aop.example.ArithmeticCalculator.*(..))",returning="result")
    	
    	public void AfterReturning(JoinPoint joinPoint,Object result){
    	
    		System.out.println("The Method after ................"+result);
    	}
    	
    	@AfterThrowing(value="execution(* com.jeremy.aop.example.ArithmeticCalculator.*(..))",throwing="e")
    	public void AfterThrowing(JoinPoint joinPoint,Exception e){
    		System.out.println("The Method afterThrowing  ................"+e.getMessage().toString());
    	}
    	
    	@Around(value="execution(* com.jeremy.aop.example.ArithmeticCalculator.*(..))")
    	public Object aroundTest(ProceedingJoinPoint pjp){
    		
    		String methodName=pjp.getSignature().getName();
    		Object object=null;
    		try {
    			
    			// 前置通知
    			 
    			System.out.println("The Method "+methodName+"before  ................");
    			object=pjp.proceed();
    			//返回通知
    			System.out.println(object);
    		} catch (Throwable e) {
    			// TODO Auto-generated catch block
    			//异常通知
    			System.out.println(e.getMessage().toString());
    		}
    		System.out.println("The Method "+methodName+"    after  ................");
    		return object;
    	}
    }
    

      

    切面优先级:也就是切面运行的先后

          比如当我们一个系统涉及权限,日志,验证。。等等各种功能我们一般是需要先验证有没有这个权限,然后再打印日志,但是系统并不知道怎么去识别使用哪个切面

          所以我们就要硬性的规定一下优先使用哪个切面(使用@order注解既可以了)
    示例:

        
         

    声明切面表达式:在实际的开发中切面表达式可能被多个通知 重复利用,所以如果同意在一处声明就可能不用那么麻烦的去书写了
    示例:

    /**
    	 * 定义一个方法, 用于声明切入点表达式. 一般地, 该方法中再不需要添入其他的代码. 
    	 * 使用 @Pointcut 来声明切入点表达式. 
    	 * 后面的其他通知直接使用方法名来引用当前的切入点表达式. 
    	 */
    	@Pointcut("execution(public int com.atguigu.spring.aop.ArithmeticCalculator.*(..))")
    	public void declareJointPointExpression(){}
    	
    	/**
    	 * 在 com.atguigu.spring.aop.ArithmeticCalculator 接口的每一个实现类的每一个方法开始之前执行一段代码
    	 */
    	@Before("declareJointPointExpression()")
    	public void beforeMethod(JoinPoint joinPoint){
    		String methodName = joinPoint.getSignature().getName();
    		Object [] args = joinPoint.getArgs();
    		
    		System.out.println("The method " + methodName + " begins with " + Arrays.asList(args));
    	}
    	
    

      

  • 相关阅读:
    windows已经阻止此软件因为无法验证发行者解决方案
    vs用resharp如何调试到源码而不是对象浏览器
    Android环境变量的设置(详细图解版)
    js为xml添加节点和属性
    javascript操作xml文件综合实例
    js如何循环读取xml文件的节点
    游标的简单理解
    关于DATE函数datediff dateadd datename等
    分组数据where & having ,group by & order by
    SQL拼接字段,算数计算
  • 原文地址:https://www.cnblogs.com/jeremy-blog/p/4054841.html
Copyright © 2011-2022 走看看