版权声明:欢迎大家转载,指正。 https://blog.csdn.net/yin__ren/article/details/81037549
1. Spring对AOP的支持
Spring对AOP功能进行了很重要的增强:
- ①新值了基于Schema的配置支持,为AOP专门提供了aop命名空间
- ②新增了对AspectJ切点表达式语言的支持。@AspectJ允许开发者在POJO中定义切面。Spring使用和@AspectJ相同风格的注解,并通过AspectJ提供的注解库和解析库处理切点。由于Spring只支持方法级的切点,仅对@AspectJ提供了有限的支持
- ③可以无缝地集成AspectJ
2. 注解知识快速进阶
1. 注解类:
@Retention(RetentionPolicy.RUNTIME) //①声明注解的保留期限
@Target(ElementType.METHOD) //②声明可以使用该注解的目标类型
public @interface NeedTest { //③定义注解
boolean value() default true; //④声明注解成员
}
注解类成员声明有几点限制:
- 成员以无入参,无抛出异常的方式声明:如boolean value(String str),boolean value() throws Exception 等方式是非法的
- 可以通过default为成员指定一个默认值: 如String level() default “LOW_LEVEL”,int high() default 2是合法的,也可以不指定默认值
- 成员类型是受限的,合法的类型包括原始类型及其封装类,String,Class,enums,注解类型,以及上述类型的数组类型: 如ForumService value(),List foo()是非法的
在①和②所看到的注解是Java预定义的注解,称为元注解(Meta-Annotation),它们被Java编译器使用,会对注解类的行为产生影响
@Retention(RetentionPolicy.RUNTIME): 表示NeedTest这个注解可以在运行期被JVM读取,注解的保留期限类型在java.lang.annotation.Retention类中定义,介绍如下:
- ①SOURCE: 注解信息仅保留在目标类代码的源码文件中,但对应的字节码文件将不再保留
- ②CLASS: 注解信息将进入目标类代码的字节码文件中,但类加载器加载字节码文件时不会将注解加载到JVM,即运行期不能获取注解信息
- ③RUNTIME: 注解信息在目标类加载到JVM后仍能保留,在运行期可以通过反射机制读取类中的注解信息
- Target(ElementType.METHOD): 表示NeedTest这个注解只能应用到目标类的方法上,注解的应用目标在java.lang.annotation.ElementType,介绍如下:
- ①TYPE: 类,接口,注解类,Enum声明处,相应的注解称为类型注解
- ② FIELD: 类成员变量或常量声明处,相应的注解称为域值注解
- ③METHOD: 方法声明处,相应的注解称为方法注解
- ④PARAMETER: 参数声明处,相应的注解称为参数注解
- ⑤CONSTRUCTOR: 构造函数声明处,相应的注解称为构造函数注解
- ⑥LOCAL_VARIABLE: 局部变量声明处,相应的注解称为局部变量注解
- ⑦ANNOTATION_TYPE: 注解类声明处,相应的注解称为注解类注解,ElementType.TYPE包含ElementType.ANNOTATION_TYPE
- ⑧PACKAGE: 包声明处,相应的注解称为包注解
- 注解只有一个成员,则成员名必须取名为value(),在使用时可以忽略成员名和赋值号(=),如@NeedTest(true)。
- 注解类拥有多个成员时,如果仅对value成员进行赋值,也可以不使用赋值号,如果同时对多个成员进行赋值,则必须使用赋值号,如DeclareParents(value=”NaiveWaiter”,defaultImpl=SmartSeller.class).
- 注解类可以没有成员,没有成员的注解称为标识注解,解释程序以标识注解存在与否进行相应的处理;此外,所有的注解类偶读隐式继承于java.lang.annotation.Annotation,但注解不允许显式继承于其他的接口
2. 使用注解
3. 访问注解
- 注解不会直接影响程序的运行,但第三方工具或程序可以利用代码中的注解完成特殊的任务,间接控制程序的运行
- 在Java中,Package,Class,Constructor,Method及Field等反射对象都有访问注解信息的方法
<T extends Annotation>T getAnnotation(Class<T>annotationClass)
,该方法支持通过泛型直接返回注解对象
public class ToolTest {
@Test
public void tool(){
//①得到ForumService对应的Class对象
Class clazz=ForumService.class;
//②得到ForumService对应的Method数组
Method[] methods=clazz.getDeclaredMethods();
System.out.println(methods.length);
for(Method method:methods){
//③获取方法上所标注的注解对象
NeedTest nt=method.getAnnotation(NeedTest.class);
if(nt!=null){
if(nt.value()){
System.out.println(method.getName()+"()需要测试");
}else{
System.out.println(method.getName()+"()不需要测试");
}
}
}
}
}