自定义注解类:
@Documented:注解信息会被添加到Java文档中
@Retention:注解的生命周期,表示注解会被保留到什么阶段,可以选择编译阶段、类加载阶段,或运行阶段
@Target:注解作用的位置,ElementType.METHOD表示该注解仅能作用于方法上
然后我们可以把注解添加到方法上:
@KthLog("这是日志内容")
@RequestMapping("user/{id}")
public User findUser(@PathVariable("id") Integer id) {
return userService.findUserById(id);
}
这个注解目前是没有任何作用的,因为我们仅仅是对注解进行了声明,并没有在任何地方来使用这个注解,注解的本质也是一种广义的语法糖,最终还是要利用Java的反射来进行操作一般使用AOP机制,可以对类或方法进行动态的扩展
使用 AOP让注解生效
@Component
@Aspect
public class KthLogAspect {
@Pointcut("@annotation(com.example.demo.annotation.KthLog)")
private void pointcut() {}
@Before("pointcut() && @annotation(logger)")
public void advice(KthLog logger) {
System.out.println("--- Kth日志的内容为[" + logger.value() + "] ---");
}
}
使用拦截器让注解生效
通过实现HandlerInterceptor接口,在拦截器方法动态获取注解,然后获取注解的值进行一些操作
package com.xxx.core.filter;
import com.xxx.common.exception.FastRuntimeException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class TestFilter extends HandlerInterceptorAdapter {
private final Logger logger = LoggerFactory.getLogger(TestFilter.class);
/**
* 预处理回调方法,实现处理器的预处理(如检查登陆),第三个参数为响应的处理器,自定义Controller
* 返回值:true表示继续流程(如调用下一个拦截器或处理器);
* false表示流程中断(如登录检查失败),不会继续调用其他的拦截器或处理器,此时我们需要通过response来产生响应;
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
//request.getHeader(String) 从请求头中获取数据
//从请求头中获取用户token(登陆凭证根据业务而定)
Long userId= getUserId(request.getHeader("H-User-Token"));
if (userId != null && checkAuth(userId,request.getRequestURI())){
return true;
}
//这里写获取注解值和做一下注解业务的操作
}
}
拦截请求配置
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
@Configuration
public class WebSecurityConfig extends WebMvcConfigurationSupport {
@Bean
public SecurityInterceptor getSecurityInterceptor() {
return new SecurityInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
InterceptorRegistration addInterceptor = registry.addInterceptor(getSecurityInterceptor());
// 排除配置
addInterceptor.excludePathPatterns("/403");
addInterceptor.excludePathPatterns("/toLogin");
addInterceptor.excludePathPatterns("/login**");
// 拦截配置
addInterceptor.addPathPatterns("/**");
}
}