项目需要做一些权限访问控制,觉得比较好的方案是AOP+annotation,因为在Java EE的权限控制也是使用类似方式实现。
1. AccessRight的注解
@Target( { ElementType.METHOD, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface AccessRight {
String code();
boolean access() default false;
boolean create() default false;
boolean update() default false;
boolean delete() default false;
}
2. AccessControlAspect切面
@Component //如果不加,spring似乎不会识别这是一个切面
@Aspect
public class AccessControlAspect {
private static final Logger log = Logger
.getLogger(AccessControlAspect.class);
@Pointcut("execution(* xx.*Bean.*()) ")
public void accessControl() {
}
@Around("accessControl()")
public Object checkRight(ProceedingJoinPoint jp) throws Throwable {
String methodName = jp.getSignature().getName();
log.info("check right: " + methodName);
Method method = jp.getTarget().getClass().getDeclaredMethod(methodName);
if (method.isAnnotationPresent(AccessRight.class)) {
AccessRight right = method.getAnnotation(AccessRight.class);
FunctionPermission permission = getRight(right.code());
if (right.access() && permission.hasAccessPermission()) {
log.info("has right to do");
return jp.proceed();
} else {
log.error("no right to do");
}
}
return jp.proceed();
}
private FunctionPermission getRight(String code) {
}
}
3. applicationContext.xml加如下内容:
<context:component-scan base-package="xx" />
<aop:aspectj-autoproxy proxy-target-class="false"/> true表示使用cglib代理,否则使用java反射代理
4. 应用在controller中
@Controller
@Scope("request")
public class xxBean {
@AccessRight(code = "something", access = true)
public String foobar() {
log.info("test...");
return "test";
}
}