问题描述
每次都加载资源,效率低下。
解决方案
/**
* @author ShenTuZhiGang
* @version 1.2.0
* @date 2020-03-07 21:57
*/
@Slf4j
@Component
public class CustomFilterInvocationSecurityMetadataSource
implements FilterInvocationSecurityMetadataSource {
private final IResourceService iResourceService;
private final IRoleService iRoleService;
private final AntPathMatcher antPathMatcher = new AntPathMatcher();
private final Map<RequestMatcher, Collection<ConfigAttribute>> requestMap = new HashMap<>();
/**
* 适用于很多线程从一个数据结构读取数据而很少的线程修改其中数据
*/
ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
/**
* 该锁可以被多个读操作共用的读锁,但会排斥写操作
*/
Lock readLock = rwl.readLock();
/**
* 该锁排斥所有其他的读操作和写操作
*/
Lock writeLock = rwl.writeLock();
public CustomFilterInvocationSecurityMetadataSource(IResourceService iResourceService,
IRoleService iRoleService) {
this.iResourceService = iResourceService;
this.iRoleService = iRoleService;
this.loadResourcePermission();
}
/**
* 加载权限
*/
private void loadResourcePermission() {
writeLock.lock(); //locks all readers and writers
try{
// do write data
log.info("加载权限");
requestMap.clear();
List<Resource> resources = iResourceService.list();
for (Resource resource : resources) {
List<Role> roles = iRoleService.listRoleBySid(resource.getId());
String[] roleArr = new String[roles.size()];
for (int i = 0; i < roleArr.length; i++) {
roleArr[i] = roles.get(i).getName();
}
requestMap.put(new AntPathRequestMatcher(resource.getPattern()),
SecurityConfig.createList(roleArr));
}
}finally {
writeLock.unlock();
}
}
/**
* 权限重载
*/
public void resetResourcePermission(){
log.info("权限重载");
loadResourcePermission();
}
@Override
public Collection<ConfigAttribute> getAttributes(Object o) throws IllegalArgumentException {
Set<ConfigAttribute> attributes = new HashSet<>();
readLock.lock(); //blocks writers only
try{
//there should be data now
final HttpServletRequest request = ((FilterInvocation) o).getRequest();
for (Map.Entry<RequestMatcher, Collection<ConfigAttribute>> entry : requestMap
.entrySet()) {
if (entry.getKey().matches(request)) {
attributes.addAll(entry.getValue());
}
}
}finally {
readLock.unlock();
}
// final String requestUrl = ((FilterInvocation) o).getRequestUrl();
// List<Resource> resources = iResourceService.list();
// Set<ConfigAttribute> attributes = new HashSet<>();
// for (Resource resource : resources) {
// if (antPathMatcher.match(resource.getPattern(), requestUrl)) {
// List<Role> roles = iRoleService.listRoleBySid(resource.getId());
// if (roles.size() > 0) {
// String[] roleArr = new String[roles.size()];
// for (int i = 0; i < roleArr.length; i++) {
// roleArr[i] = roles.get(i).getName();
// }
// attributes.addAll(SecurityConfig.createList(roleArr));
// }
// }
// }
if (attributes.size() == 0) {
attributes.addAll(SecurityConfig.createList("ROLE_LOGIN"));
}
return attributes;
}
@Override
public Collection<ConfigAttribute> getAllConfigAttributes() {
Set<ConfigAttribute> allAttributes = new HashSet<>();
readLock.lock(); //blocks writers only
try{
for (Map.Entry<RequestMatcher, Collection<ConfigAttribute>> entry : requestMap
.entrySet()) {
allAttributes.addAll(entry.getValue());
}
}finally {
readLock.unlock();
}
return allAttributes;
}
@Override
public boolean supports(Class<?> aClass) {
return FilterInvocation.class.isAssignableFrom(aClass);
}
}