在了解和使用springAOP注解之前,我们有必要学习一下java5.0中新增的注解(Annotation)技术。

1.1、了解注解  

注解遵循着一个基本原则:注解不能直接干扰代码运行,无论增加或删除注解,代码都能够正常运行。java语言解释器会忽略这些注解,而由第三方工具负责对注解进行处理。第三方工具可以利用代码中的注解间接控制程序代码的运行,它们通过java反射机制读取注解的信息,并根据这些信息更改目标程序的逻辑。下面用一个简单的例子来说明注解的使用。

java aop注解实现 java 注解 aop_@Aspect

成员声明有以下几点规则限制:

1.成员是以无入参、无抛出异常的方式声明,如boolean isAllowedNullObject(String str)、boolean isAllowedNullObject() throws Exception等方式都是非法声明。

2.成员可以通过defult为其指定一个默认值

3.成员的类型是受限的,合法的类型包括原始类及其封装类、String、Class、enums等注解类型以及上述类型的数组类型,都是合法的,如List key()是非法的。

1.2、使用注解

java aop注解实现 java 注解 aop_@Aspect_02

注:如果注解类和目标类不在同一个包中,需要通过import引用注解类。

由于ShardRedisCache注解的保留期限是RetentionPolicy.RUNTIME类型,因此当ForumService被加载到JVM时,仍可通过反射机制访问到ForumService各个方法的注解信息。

1.3、访问注解

直接上一个测试类的例子:

java aop注解实现 java 注解 aop_aop注解_03

在标注的3处通过方法的反射对象,获取方法上所标注的ShardedRedisCache注解对象,接着就可以访问注解对象的成员,从而得到ForumService类方法的测试需求。运行以上代码,输出以下信息:

java aop注解实现 java 注解 aop_spring_04

2.1使用@Aspect

常用的几个增加类型注解

1.@Before 前置增强(目标方法执行之前,执行注解标注的内容)

2.@AfterReturning 后置增强(目标方法正常执行完毕后,执行)

3.@Around 环绕增强(目标方法执行前后,分别执行一些代码)

           4.@AfterThrowing 抛出增强(目标方法发生异常,执行)

5.@After Final增强(不管是抛出异常还是正常退出,该增强都会得到执行。一般用于释放资源,相当于try{}finally{})。

切点函数注解常用详解

1.@annotation()

@annotation表示标注了某个注解的所有方法,以下实例说明@annotation的用法。TestAspect定义了一个后置增强切面,该增强将应用到标注了ShardedRedisCache的目标方法中。

java aop注解实现 java 注解 aop_spring_05

java aop注解实现 java 注解 aop_@Aspect_06

java aop注解实现 java 注解 aop_java aop注解实现_07

通过spring配置自动应用切面。

java aop注解实现 java 注解 aop_aop_08

运行测试代码

 

java aop注解实现 java 注解 aop_spring_09

  

输出以下信息

java aop注解实现 java 注解 aop_java aop注解实现_10

2.execution()

execution()是最常用的切点函数,它的语法格式为execution(<修饰符模式><返回类型模式><方法名模式>(<参数模式>)<异常模式>)

1.通过方法签名定义切点

execution(public * *(..)):匹配所有目标类public的方法,第一个*代表返回类型,第二个*代表返回名,而..代表任意入参的方法。

2.通过类定义切点

execution(* com.suning.www.Instrument.*(..)):匹配Instrument接口的所有方法,第一个*代表返回任意类型,com.suning.www.Instrument.*代表Instrument接口中所有的方法。

3.通过类包定义切点

execution(* com.suning.www*(..)):匹配com.suning.www包下所有类的所有方法。

execution(* com.suning..*(..)):匹配com.suning包,子孙包下所有类的所有方法。

4.通过方法入参定义切点

exexution(*play(String,int)):匹配play(String,int)方法,且play()方法的第一个入参类型是String,第二个是int。