通过自定义注解标记方法,利用AOP拦截方法输出日志。
(案例主要是访问页面输出日志信息)
参考:利用反射获取类或者方法或者字段上的注解的值
1 .环境搭建
使用SpringBoot整合AOP。
<!-- 引入aop支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
再引入thymeleaf和web模块
<!--web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--thymeleaf-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
2 .自定义注解类
/**
* 自定义注解类
* 提到注解就不能不说反射,Java自定义注解是通过运行时靠反射获取注解。
* 实际开发中,例如我们要获取某个方法的调用日志,
* 可以通过AOP(动态代理机制)给方法添加切面,通过反射来获取方法包含的注解,如果包含日志注解,就进行日志记录。
*/
@Target(ElementType.METHOD)//说明注解范围,如果Target元注解不存在,那么该注解就可以使用在任何程序元素之上
@Retention(RetentionPolicy.RUNTIME)//注解生命周期,这里必须用RUNTIME,使用Java反射机制从一个类中解析注解,请记住,注解保持性策略应该是RUNTIME,否则它的信息在运行期无效,我们也不能从中获取任何数据。
public @interface MyLog {
/**
* 时间格式化
* @return
*/
String time() default "";
/**
* 信息
* @return
*/
String info() default "";
}
3 .切面类
@Component//加入到IOC容器
@Aspect//这是一个切面
public class MyAop {
@AfterReturning(value = "execution(* com.example.myanno.controller.IndexController.toIndex(..))")
//JointPoint是程序运行过程中可识别的点,
// 这个点可以用来作为AOP切入点。JointPoint对象则包含了和切入相关的很多信息。
// 比如切入点的对象,方法,属性等。我们可以通过反射的方式获取这些点的状态和信息,
// 用于追踪tracing和记录logging应用信息。
public void indexAop(JoinPoint joinPoint){
//1.获取方法上的注解
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
if(method!=null){
MyLog annotation = method.getAnnotation(MyLog.class);
if(annotation!=null){
String time = annotation.time();
String formatTime = new SimpleDateFormat(time).format(new Date());
System.out.println("["+formatTime+"] "+annotation.info());//输出日志信息
}
}
}
}
4 .测试
@Controller
public class IndexController {
@MyLog(time = "yyyy-MM-dd hh:mm:ss",info = "访问了首页")
@RequestMapping(path = "/index")
public String toIndex(){
return "index";
}
}
整个demo工程结构
6 .测试