最近在做权限管理,希望能够在容器初始化后,自动的将所有Controller上的url进行收集,并存放到权限表中,从而代替人工配置的方式。实现思路如下:
spring事件驱动机制+注解来实现。
spring事件驱动机制
spring在容器初始化之后,会触发ContextRefreshedEvent等事件,只要实现了ApplicationListener就可以捕获这个事件,这个时候,我们就可以做很多事情了,比如权限信息的提取,加载缓存等等,所以,我们的思路也是基于此的。
1、自定义注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 权限注解,后台会在容器中所有的类都加载完毕之后,通过扫描该注解,将系统中所有url对应的权限信息存到数据库中,
* 减少人为配置
* 注意:之所以加该注解而不直接用RequestMapping原因如下:
* 1、经测试,classpath下其他的框架中也可能存在使用RequestMapping的情况,这样就会出错,例如org.springframework.boot.autoconfigure.web.BasicErrorController类
* 2、RequestMapping没有其他的需要的信息,用起来也不灵活
* @author chhliu
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface PermissionPath {
// 权限路径,需要和RequestMapping里面的路径一致
public String path() default "";
// 当前Controller对应的模块名称
public String moduleName() default "";
// 当前Url对应的操作
public Operation operation();
}
/**
* controller中url对应的操作权限,目前限定的操作为4种
* @author chhliu
*/
public enum Operation {
VIEW, UPDATE, ADD, DELETE
}
2、实现ApplicationListener
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Map.Entry;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;
import com.chhliu.srd.rdcloud.annotation.PermissionPath;
/**
* spring的事件驱动机制
* 实现ApplicationListener后,容器会在初始化所有的bean之后,触发refresh事件
* 所以在该方法中,可以实现对系统中所有Controller中url的提取
* @author chhliu
*
*/
@Component
public class ExtractPermissionInformationContext implements ApplicationListener<ContextRefre