0.概述
本文主要介绍利用AOP和注解技术权限、操作日志解耦出来~
1.AOP(面向切面编程)简介
Aspect是一种新的模块化机制,用来描述分散在对象、类或函数中的横切关注点(crosscutting concern)。从关注点中分离出横切关注点是面向切面的程序设计的核心概念。分离关注点使解决特定领域问题的代码从业务逻辑中独立出来,业务逻辑的代码中不再含有针对特定领域问题代码的调用,业务逻辑同特定领域问题的关系通过切面来封装、维护,这样原本分散在整个应用程序中的变动就可以很好地管理起来。(来源spring 技术内幕)
2.具体实现
权限注解,利用注解中code区分
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AuthCode {
String code() default "";
}
操作日志注解(具体对象和操作类型可以设置为枚举)
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ActionLog {
//对象类型
String objectType() default "";
//操作类型
String operateType() default "";;
//处理对象
Class<? extends ActionLogHandler> handler() default DefaultActionLogHandler.class;
}
操作日志handler 接口(可以根据需要设计相关接口)
public interface ActionLogHandler {
boolean process(Object[] args, ApplicationContext ctx, ActionLog actionLog);
}
public class DefaultActionLogHandler implements ActionLogHandler {
public boolean process(Object[] args, ApplicationContext ctx, ActionLog actionLog) {
return false;
}
}
@Component
@Aspect
public class AspectTest implements ApplicationContextAware {
private static ApplicationContext context;
@Around("public execution( * com.hsc.study.aop.*.*(..))")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
//获取方法
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
Object[] args = joinPoint.getArgs();
//获取方法上的权限注解
AuthCode authCode = method.getAnnotation(AuthCode.class);
if (authCode != null) {
String code = authCode.code();
//校验权限
}
//获取日志操作注解
ActionLog actionLog = method.getAnnotation(ActionLog.class);
ActionLogHandler actionLogHandler = null;
Object ret = joinPoint.proceed();
//如果返回成功,且加的有注解,执行相应的方法
if (actionLog != null) {
//实例化处理对象
actionLogHandler = actionLog.handler().newInstance();
actionLogHandler.process(args, getContext(), actionLog);
}
return ret;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
public static ApplicationContext getContext() {
return context;
}
}
使用实例
@Service
public class StudentService {
@ActionLog(objectType = "学生",operateType = "添加",handler = DefaultActionLogHandler.class)
@AuthCode(code="write")
public Student insert(Student i)
{
return null;
}
}
实现ApplicationContextAware接口是为了获取上下文环境,可能handler要用。
3.总结
aop和注解相结合可以很好将权限和操作日志与业务代码解耦出来,aop还可以做统一异常处理,这样不至于每个service层的方法都有try catch。