DEMO
自定义注解
@Target(ElementType.METHOD) //TYPE类 FIeld 变量
@Retention(RetentionPolicy.RUNTIME)
public @interface BusinessLog {
String url() default "";
String value() default "";
}
使用自定义注解
public class StudentService {
@BusinessLog(value = "学习接口",url = "/user/study")
public void study() {
System.out.println("正在教室学习");
}
}
反射读取注释内容
class WadeApplicationTests {
public static void main(String[] args) {
Class<StudentService> studentServiceClass = StudentService.class;
for (Method m : studentServiceClass.getDeclaredMethods()) {
BusinessLog annotation = m.getAnnotation(BusinessLog.class);
System.out.println("读取自定义注解内容"+annotation.url()+"----"+annotation.value()); // 读取自定义注解内容:user/study----学习接口
}
}
}
使用场景
登录鉴权或资源鉴权
1.自定义注解
//接口需要登录认证
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LoginRequird {
}
2.controller的方法中使用
@LoginRequird
@RequestMapping
public Object index(ModelAndView modelAndView, @RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "5") Integer size,HttpSession session) {
PageHelper.startPage(pageNum, size);
List<User> userList = userService.getUserList();
PageInfo<User> stringPageInfo = new PageInfo<>(userList);
modelAndView.addObject("page", stringPageInfo);
modelAndView.setViewName("index");
return modelAndView;
}
3.HandlerInterceptor 拦截器定义拦截请求
@Component
@Slf4j
public class MyHandlerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HandlerMethod handlerMethod = (HandlerMethod)handler;
LoginRequird annotation = handlerMethod.getMethod().getAnnotation(LoginRequird.class);
//有LoginRequired表明要鉴权,否则放行
if (annotation != null) {
Object name = request.getSession().getAttribute("name");
log.info("name : {}", name);
if (name == null) {
response.sendRedirect("/user/login");
return false;
} else {
return true;
}
}
log.info("prehandler通过");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
4.使用拦截器
@Configuration
public class MyWebConfig implements WebMvcConfigurer {
@Autowired
private MyHandlerInterceptor myHandlerInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(myHandlerInterceptor).addPathPatterns("/**");
}
}
做资源权限认证,比如某些接口管理员权限用户才能访问。代码实现类似!
自定义注解+AOP做日志系统
自定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface BussinessLog {
/**
* 业务的名称,例如:"修改菜单"
*/
String value() default "";
/**
* 被修改的实体的唯一标识,例如:菜单实体的唯一标识为"id"
*/
String key() default "id";
/**
* 字典(用于查找key的中文名称和字段的中文名称)
*/
Class<? extends AbstractDictMap> dict() default SystemDict.class;
/**
* 菜单url
*/
String url() default "";
}
AOP
@Aspect
@Component
public class LogAop {
private Logger log = LoggerFactory.getLogger(this.getClass());
@Pointcut(value = "@annotation(cn.wyb.wade.annotion.BussinessLog)")
public void cutService() {
}
@Around("cutService()")
public Object recordSysLog(ProceedingJoinPoint point) throws Throwable {
//先执行业务
Object result = point.proceed();
try {
handle(point);
} catch (Exception e) {
log.error("日志记录出错!", e);
}
return result;
}
private void handle(ProceedingJoinPoint point) throws Exception {
//获取拦截的方法名
Signature sig = point.getSignature();
MethodSignature msig = null;
if (!(sig instanceof MethodSignature)) {
throw new IllegalArgumentException("该注解只能用于方法");
}
msig = (MethodSignature) sig;
Object target = point.getTarget();
Method currentMethod = target.getClass().getMethod(msig.getName(), msig.getParameterTypes());
String methodName = currentMethod.getName();
//如果当前用户未登录,不做日志
ShiroUser user = ShiroKit.getUser();
if (null == user) {
return;
}
//获取拦截方法的参数
String className = point.getTarget().getClass().getName();
Object[] params = point.getArgs();
//获取操作名称
BussinessLog annotation = currentMethod.getAnnotation(BussinessLog.class);
String bussinessName = annotation.value();
String key = annotation.key();
Class dictClass = annotation.dict();
String url = annotation.url();
StringBuilder sb = new StringBuilder();
for (Object param : params) {
sb.append(param);
sb.append(" & ");
}
//保存日志
LogManager.me().executeLog(LogTaskFactory.bussinessLog(user.getId(), user.getShopId(), bussinessName, className, methodName, msg, url));
}
}