《从入门到精通:方法拦截器与切入点表达式的使用指南》

MethodInterceptir(方法拦截器)

methodInteceptor接口:额外功能可以根据需要运行在原始方法执行前、后、前后

public class Arround implements MethodInterceptor {
    /*
        invoke方法作用:额外功能书写在invoke
                     原始方法之前 之后 /之前之后


        参数:MethodInvocation:额外功能所增加的那个原始方法
        invocation.proceed():执行原始方法

        返回值:返回原始方法的执行结果
     */
    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        System.out.println("around before");
        Object proceed = methodInvocation.proceed();//void 返回Null
        return proceed;
    }
}

 额外功能运行在原始方法之前、之后运行

 什么样的额外功能,运行在原始方法执行之前,之后要添加

事务

public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        System.out.println("around before");
        Object proceed = methodInvocation.proceed();//void 返回Null
        System.out.println("around after");
        return proceed;
    }

额外功能运行在原始方法抛出异常的时候

public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        System.out.println("around before");
        Object proceed = null;//void 返回Null
        try {
            proceed = methodInvocation.proceed();
        } catch (Throwable throwable) {
            System.out.println("额外功能抛出异常 执行的功能-------");
        }
        System.out.println("around after");
        return proceed;
    }

MethodInterceptor影响原始方法的返回值

原始方法的返回值:直接作为invoke方法的返回值返回,MethodInterceptor不会影响原始方法的返回值

MethodInterceptor影响原始方法的返回值

Invoke方法的返回值,不要直接返回方法的运行结果即可

public Object invoke(MethodInvocation methodInvocation) throws Throwable {
    Object proceed = null;//void 返回Null
    return false;//影响
}

切入点

切入点决定额外功能加入位置(方法)

execution(* *(..)) --->匹配了所有方法

1.execution() 切入点函数

2.* *(..)         切入点表达式

切入点表达式 

  • 方法切入点表达式

定义一个方法

public void add(int int)

* *(..)         切入点表达式

  • 第一个*代表对修饰符没有要求
  • 第二个*代表对于方法名没有要求
  • ...代表对参数没有要求(参数有没有、参数有几个、参数是什么类型)

案例

  • 定义login方法作为切入点

execution(* login(..))

  • 定义login方法 且必须有个字符串类型的参数

execution(* login(String,String))

#注意: 非java.lang包中的类型 必须写全限定类名

#register(com.User)

#

* login(String,..)  -->第一个参数是String就可以

  • 上面方法切入点并不精准 

 修饰符 返回值     包.类.方法(参数)
*    com.gao.proxy.UserServiceImpl.login(..)

 类切入点

指定特定类作为切入点(额外功能加入的位置) 自然这个类中的所有方法,都会加上对应的额外功能
 

  • 语法1 

 #类中所有方法加入了额外方法
com.gao*(...)

  •  语法2

#忽略包

1.类只存在一级包 com.UserServiceImpl

*.UserServiceImpl.*(..)

2.类存在多级包 com.gao.UserServiceImpl

* *..UserServiceImpl.*(..)

包切入点 

指定包作为额外功能加入的位置 自然包中所有类及其方法都会加入额外的功能 

  •  语法

* com.gao.com.proxy.* *(..) 

* com.gao.com.proxy..* *(..) //当前包以及子包

 切入点函数

1.execution

切入点函数:用于执行切入点表达式

执行 方法切入点表达式 类切入点表达式 包切入点表达式

弊端: execution执行切入点表示 书写麻烦

注意:其它的切入点函数 简化

2.args

作用 主要用于函数(方法)参数的匹配
切入点:方法参数必须是2个字符串类型的参数

execution(* *(String,String))

args(String,String)

3.within

作用:主要用于进行类、包切入点的匹配 

切入点:UserServiceImpl

execution(* *..UserServiceImpl.*(..))

within(*..UserServiceImpl)

execution(* com.gao.proxy..*.*(..))

within(com.gao.proxy..*)

4. @annotation

作用:为具有特殊注解的方法加入额外功能

5.切入点函数的逻辑运算 

指的是 整合多个切入点函数一起配合工作 完成更为复杂的需求

and与操作

案例 login 同时参数 2个字符串

1.execution(* login(String,String))
2.exectuion(* login(..)) and args(String,String)

注意:与操作不能用于同种类型的切入点函数

 or或操作

execution(* login(...)) or execution(* register(..))

你可能感兴趣的:(Spring,java,开发语言,spring,后端)