Spring 自定义注解开发
AOP的基本概念
(1)Aspect(切面):通常是一个类,里面可以定义切入点和通知
(2)JointPoint(连接点):所谓的连接点指那些被拦截到的点。在Spring中,这些点指的是方法,因为Spring只支持方法类型的连接点
(3)Advice(通知):所谓通知是指拦截到JointPoint之后要做的事情就是通知,通知分为前置通知、后置通知、异常通知、最终通知、环绕通知。(切面要完成的功能)
(4)Pointcut(切入点):所谓切入点就是指我们要对哪些Joinpoint进行拦截的定义
(5)Introduction(引介):引介是一种特殊的通知,在不修改类代码的前提下,Introduction可以在运行期为类动态的添加一些方法或Filed
(6)Target(目标对象):代理的目标对象
(7)Weaving(织入):是指把增强应用到目标对象来创建新的代理对象的过程,Spring采用动态代理织入,而AspectJ采用编译期织入和类装载期织入
(8)Proxy(代理):一个类被AOP织入增强后,就产生一个结果代理类
自定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface MyLog {
String requestUrl();
}
@Target:指定注解支持的使用范围,取值范围 ElementType
@Retention: 指定注解的保留时间,取值范围 RetentionPolicy
@Documented: 指定拥有这个注解的元素是否可以被Javadoc工具文档化
@Inherited: 指定该注解是否可以被继承
解析注解
@Aspect
@Component
public class MyLogAspect {
@Pointcut(value = " @annotation(com.test.annotation.MyLog)")
private void pointcut(){
}
/**
* 环绕通知
*
* @param null
* @author liang.jin
* @return
*/
@Around(value = "pointcut() && @annotation(myLog)")
public Object around(ProceedingJoinPoint point, MyLog myLog){
System.out.println("====执行了around方法====");
String req = myLog.requestUrl();
Class<?> clazz = point.getTarget().getClass();
Method method = ((MethodSignature) point.getSignature()).getMethod();
System.out.println("执行了类"+clazz+" 方法:"+method+" 请求地址:"+req);
try {
return point.proceed();
} catch (Throwable throwable) {
throwable.printStackTrace();
return throwable.getMessage();
}
}
/**
* 方法执行后
*
* @author liang.jin
* @return
*/
@AfterReturning(value = "pointcut() && @annotation(myLog)",returning = "result")
public Object afterReturning(JoinPoint joinPoint,MyLog myLog, Object result){
System.out.println("执行了afterReturning方法");
System.out.println("执行结果:"+result);
return result;
}
@AfterThrowing(value = "pointcut() && @annotation(myLog)",throwing = "e")
public void afterThrowing(JoinPoint joinPoint,MyLog myLog,Exception e){
System.out.println("执行了afterThrowing方法");
System.out.println("请求"+myLog.requestUrl()+" 出现异常");
}
}
使用注解
@MyLog(requestUrl = "/index请求")
@RequestMapping(value = "/index",method = RequestMethod.GET)
public String index(){
return "index";
}
响应结果
====执行了around方法====
执行了类class com.hand.Appliaction$$EnhancerBySpringCGLIB$$7dc73fde 方法:public java.lang.String com.hand.Appliaction.index() 请求地址:/index请求
执行了afterReturning方法
执行结果:index