Spring AOP 针对注解的AOP
2024-08-26 23:36:46
我也忘记是从哪里扒来的代码,不过有了这个思路,以后可以自己针对 Controller 还有 Service层的任意 方法进行代理了
package pw.jonwinters.aop;
import java.lang.annotation.*; /**
*自定义注解 拦截Controller
*/ @Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SystemControllerLog {
String description() default "";
}
package pw.jonwinters.aop; import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; @Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SystemServiceLog {
String description() default "";
}
package pw.jonwinters.aop; import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; import java.lang.reflect.Method; import javax.servlet.http.HttpServletRequest; import pw.jonwinters.service.*;
@Aspect
@Component
public class SystemLogAspect {
@Autowired
@Qualifier("baseLogger")
private Logger log; @Pointcut("@annotation(pw.jonwinters.aop.SystemServiceLog)") //拦截带有此类注解的方法
public void serviceAspect() {
}
@Pointcut("@annotation(pw.jonwinters.aop.SystemControllerLog)")
public void controllerAspect() {
} @Before("controllerAspect()")
public void doBefore(JoinPoint joinPoint) throws Throwable { //joinPoint
log.info("aop is running!");
log.info("请求方法:" + (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()"));
log.info("方法描述:" + getControllerMethodDescription(joinPoint)); //请求的IP
Thread.sleep(20000);
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String ip = request.getRemoteAddr();
try {
//*========控制台输出=========*//
log.info("=====前置通知开始=====");
log.info("请求方法:" + (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()"));
log.info("方法描述:" + getControllerMethodDescription(joinPoint));
log.info("请求IP:" + ip);
// Thread.sleep(2000);
}
finally{ }
} @AfterThrowing(pointcut = "serviceAspect()", throwing = "e")
public void doAfterThrowing(JoinPoint joinPoint, Throwable e) { } }
public static String getControllerMethodDescription(JoinPoint joinPoint) throws Exception {
String targetName = joinPoint.getTarget().getClass().getName(); //这是个工具类, 通过joinPoint对象 获得目标对象的引用 获得拦截对象的Class对象,然后获得Class对象的名称
String methodName = joinPoint.getSignature().getName(); //获得拦截方法的名称
Object[] arguments = joinPoint.getArgs(); //获得拦截方法的参数对象数组
Class<?> targetClass = Class.forName(targetName); //获得拦截对象的Class
Method[] methods = targetClass.getMethods(); //获得拦截对象的所有方法
String description = "";
for (Method method : methods) { //遍历方法
if (method.getName().equals(methodName)) { //当此方法的名称与拦截方法的名称相同时候
Class[] clazzs = method.getParameterTypes(); //获得这个方法的所有参数类型的 Class对象
if (clazzs.length == arguments.length) { //确保拦截的方法的参数个数 与 解析到的参数个数相同
description = method.getAnnotation(SystemControllerLog.class).description(); //然后获得方法的注解的description字段的值 并且返回
break;
}
}
}
return description;
}
最新文章
- 【Android】[转] Android Codec默认profile使用的是Baseline
- 用jQuery调用微信api生成二维码
- 路由器WDS实际案例
- 教官的游戏(codevs 2793)
- entity framework 连接 oracle 发布后出现的问题(Unable to find the requested .Net Framework Data Provider)
- Java正则表达式:Pattern类和Matcher类
- 访问权限系列一(public/private/protected/default):成员变量
- Delphi语言最好的JSON代码库 mORMot学习笔记1
- 用Linux命令行获取本机外网IP地址
- Terminating app due to uncaught exception &#39;NSUnknownKeyException&#39; this class is not key value coding-compliant for the key
- 关于computed使用时报no-side-effects-in-computed-properties错误
- linux服务器运维
- memcached 在windows中的部署和使用
- G2( bizCharts ) React 绘制混合图例
- RAD Studio August 2018 Roadmap
- USACO December 铂金Maxflow
- git第二节----git clone与git tag
- 从零开始学习html(十二)CSS布局模型——下
- json_encode无返回结果
- MyBatis关联查询,一对一关联查询
热门文章
- JavaScript正则表达式小记
- mysql实时同步到mssql的解决方案
- Sharepoint学习笔记—习题系列--70-573习题解析 -(Q107-Q110)
- C语言中do...while(0)用法小结
- C语言原子接口与实现
- windows下vagrant使用及工作环境配置
- Jmeter之HTTP Request Defaults
- 长文件名导致的0x80070057
- 了解linux内存管理机制(转)
- 读书笔记——Windows环境下32位汇编语言程序设计(9)ANSII字符大小写转大写