掃描指定注解獲取其相關屬性
由來
整個中臺,連個權限選單管理都沒有,遷移資料 制造測驗資料都要手動制造假資料存到資料庫,
每次有更改還要手動改,實在是太慢了,依賴關系和外鍵還容易搞錯,為啥不搞個選單和權限管理呢?
專案經理說:沒必要我們的選單就這些不改,就前期加麻煩點剩了很多事,你搞個excel表格維護一下好了,,,
于是就沒有了,懶嘛 不想每次都加一堆按鈕 于是自定義一個 設定幾個屬性
@AnnotationAction(actionValue="https://www.cnblogs.com/lccsetsun/p/查詢",url="api/quer/manager/details",readme="查詢管理后臺某資料詳情")
嗯!就這樣可以根據自已的需求隨意加
javaCode
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternUtils;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.MethodMetadata;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* author: 夕陽
* date: 2021/1/13
* Description: 掃描指定包下面的 所有指定的注解值
*/
@Component
public class AnnotationUtil {
@Autowired
private ResourceLoader resourceLoader;
private static final String VALUE = "https://www.cnblogs.com/lccsetsun/p/value";
/**
* 獲取指定包下所有添加了執行注解的方法資訊
* @param classPath 包名
* @param tagAnnotationClass 指定注解型別
* @param <T>
* @return
* @throws Exception
*/
public <T> Map<String, Map<String, Object>> getAllAddTagAnnotationUrl(String classPath, Class<T> tagAnnotationClass) throws Exception {
Map<String, Map<String, Object>> resMap = new HashMap<>();
ResourcePatternResolver resolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);
MetadataReaderFactory metaReader = new CachingMetadataReaderFactory(resourceLoader);
Resource[] resources = resolver.getResources(classPath);
for (Resource r : resources) {
MetadataReader reader = metaReader.getMetadataReader(r);
resMap = resolveClass(reader, resMap, tagAnnotationClass);
}
return resMap;
}
private <T> Map<String, Map<String, Object>> resolveClass(
MetadataReader reader, Map<String, Map<String, Object>> resMap, Class<T> tagAnnotationClass)
throws Exception {
String tagAnnotationClassCanonicalName = tagAnnotationClass.getCanonicalName();
//獲取注解元資料
AnnotationMetadata annotationMetadata = https://www.cnblogs.com/lccsetsun/p/reader.getAnnotationMetadata();
//獲取類中RequestMapping注解的屬性
Map annotationAttributes =
annotationMetadata.getAnnotationAttributes(RequestMapping.class.getCanonicalName());
//若類無RequestMapping注解
if (annotationAttributes == null){ return resMap;}
//獲取RequestMapping注解的value
String[] pathParents = (String[]) annotationAttributes.get(VALUE);
if (0 == pathParents.length){ return resMap;}
//獲取RequestMapping注解的value
String pathParent = pathParents[0];
//獲取當前類中已添加要掃描注解的方法
Set annotatedMethods = annotationMetadata.getAnnotatedMethods(tagAnnotationClassCanonicalName);
for (MethodMetadata annotatedMethod : annotatedMethods) {
//獲取當前方法中要掃描注解的屬性
Map targetAttr = annotatedMethod.getAnnotationAttributes(tagAnnotationClassCanonicalName);
//獲取當前方法中要xxxMapping注解的屬性
Map mappingAttr = getPathByMethod(annotatedMethod);
if (mappingAttr == null){
continue;
}
String[] childPath = (String[]) mappingAttr.get(VALUE);
if (targetAttr == null || childPath == null || childPath.length == 0) {
continue;
}
// 組裝路徑
String assembledToBePathStr =pathParent.replace("/"," ")+" "+ childPath[0].replace("/"," ");
String finalPath = assembledToBePathStr.replaceAll("\\s+","/");
boolean isHas = resMap.containsKey(finalPath);
if (isHas){
throw new Exception("重復定義了相同的映射關系");
}
resMap.put(finalPath, targetAttr);
}
return resMap;
}
private Map<String, Object> getPathByMethod(MethodMetadata annotatedMethod) {
Map<String, Object> annotationAttributes = annotatedMethod.getAnnotationAttributes(GetMapping.class.getCanonicalName());
if (annotationAttributes != null && annotationAttributes.get(VALUE) != null) {
return annotationAttributes;
}
annotationAttributes = annotatedMethod.getAnnotationAttributes(PostMapping.class.getCanonicalName());
if (annotationAttributes != null && annotationAttributes.get(VALUE) != null) {
return annotationAttributes;
}
annotationAttributes = annotatedMethod.getAnnotationAttributes(DeleteMapping.class.getCanonicalName());
if (annotationAttributes != null && annotationAttributes.get(VALUE) != null) {
return annotationAttributes;
}
annotationAttributes = annotatedMethod.getAnnotationAttributes(PutMapping.class.getCanonicalName());
if (annotationAttributes != null && annotationAttributes.get(VALUE) != null) {
return annotationAttributes;
}
annotationAttributes = annotatedMethod.getAnnotationAttributes(RequestMapping.class.getCanonicalName());
return annotationAttributes;
}
}
使用示例
@Test
public void test(){
// 省略部分代碼 ,,,
AnnotationUtil annotationUtil = new AnnotationUtil();
try {
Map<String, Map<String,Object>> all = annotationUtil.getAllAddTagAnnotationUrl("classpath*:vip/setsun/controller/**/*.class", AnnotationAction.class);
all.forEach((k,v)->{
// 這里的v 就是注解里面的定義的屬性
System.out.println(k+" : "+ v.get("actionValue"));
});
// 拿到之后就可以做入庫操作和其他的操作
//,,, 此處省略業務的代碼,,,
} catch (Exception e) {
e.printStackTrace();
}
}
- 每日一夸:在這個星球上,你很重要,請珍惜你的可貴
聊點其他的,最近準備搞一下es 產品,不知道做點啥 比如 圖搜 ,也沒個小目標不知道寫點啥,前段時間寫了一個資源監控中臺,有興趣就寫寫總結分享一下難點(提不起來興趣)
es 準備學習以下知識點
- ES CURD
- ES 索引優化
- ES 分頁查詢
- ES 多shard 查詢優化
- ES 針對TB級資料處理和查詢優化(這個是總結之前做的EB級圖搜優化,和服務器方面的優化設定以及相應的組態檔修改,準備入手總結時間暫定)
- ES 集群健康方面的查詢操作
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/248393.html
標籤:Java
