四大元注解
1.@Target
表示该注解用于什么地方
public enum ElementType {
TYPE,类,接口(包括注解类型)或enum声明
FIELD,域声明(包括 enum 实例)
METHOD,方法声明
PARAMETER,参数声明
CONSTRUCTOR,构造器声明
LOCAL_VARIABLE,局部变量声明
ANNOTATION_TYPE,Annotation type declaration
PACKAGE,包声明
TYPE_PARAMETER,类型参数声明
TYPE_USE 类型的使用
}
2.@Retention
表示该注解可以保存的范围
public enum RetentionPolicy {
SOURCE,源代码:即此注解只能保存在源代码中当编译时,会被丢弃
CLASS,class文件:即此注解可以在class文件中保留但会被jvm丢弃
RUNTIME 运行期:即此注解可以在运行时保留可以通过反、反射获得
}
3.@Documented
即拥有这个注解的元素可以被javadoc此类的工具文档化。它代表着此注解会被javadoc工具提取成文档。在doc文档中的内容会因为此注解的信息内容不同而不同。相当与@return,@param 等。
4.@Inherited
允许子类继承父类中的注解。即拥有此注解的元素其子类可以继承父类的注解。
拦截器实现demo
@Component //让IOC容器管理
@Aspect //定义切面类
@Order(0) //设置优先级,值越低优先级越高
public class TestAspect {
/**
* 系统状态处理切入点
*/
@Pointcut("execution(* com.test.aop.service.*.*(..))")
public void testPointCut() {
}
@Before("testPointCut()")
public void before(JoinPoint joinPoint) {
//方法名
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
//参数名称
String[] params = methodSignature.getParameterNames();
//参数值
Object[] args = joinPoint.getArgs();
//获得注解信息
LogAnnotation logAnnotation = methodSignature.getMethod().getDeclaredAnnotation(LogAnnotation.class);
for (int i = 0 ; i <params.length; i++) {
System.out.println(params[i]+ " = "+ args[i]);
}
}
@After("testPointCut()")
public void after (JoinPoint joinPoint) {
}
@AfterReturning(pointcut = "testPointCut()",returning = "returning")
public Object afterReturn(JoinPoint joinPoint, Object returning) {
}
/**
* 系统状态处理
*
* @param point 处理加入点
* @return 返回结果
*/
@Around("testPointCut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
String classPath = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
//获取参数名称、参数值
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
//取得参数
String[] params = methodSignature.getParameterNames();
//参数值
Object[] args = joinPoint.getArgs();
for (int i = 0; i < params.length; i++) {
System.out.println(params[i]+" = "+args[i]);
}
//取注解
LogAnnotation logAnnotation = methodSignature.getMethod().getDeclaredAnnotation(LogAnnotation.class);
System.out.println("value= "+logAnnotation.value()+",des ="+logAnnotation.description());
Object result = result =joinPoint.proceed(args);
return result;
}
//异常执行
@AfterThrowing(pointcut = "testPointCut()",throwing = "err")
public void throwing(Throwable err) {
}
}
@Around的作用
环绕通知是SpringAOP中最强大的通知,它可以同时实现前置通知和后置通知,它保留了调度被代理对象的原有方法功能,所以它既强大,又灵活,但是可控性不强,如果不需要大量的改业务逻辑,一般而言不需要使用。