139 lines
4.3 KiB
Java
139 lines
4.3 KiB
Java
package com.pictc.utils;
|
|
|
|
import java.lang.annotation.Annotation;
|
|
import java.lang.reflect.AnnotatedElement;
|
|
import java.lang.reflect.Field;
|
|
import java.lang.reflect.InvocationHandler;
|
|
import java.lang.reflect.Proxy;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Map.Entry;
|
|
import java.util.Set;
|
|
|
|
import org.springframework.context.EnvironmentAware;
|
|
import org.springframework.core.annotation.AnnotationUtils;
|
|
import org.springframework.core.env.Environment;
|
|
import org.springframework.stereotype.Component;
|
|
|
|
import com.pictc.cache.CacheFactory;
|
|
import com.pictc.cache.TanukiCache;
|
|
|
|
/**
|
|
* @Description TODO(这里用一句话描述这个类的作用)
|
|
* @author zhangfucai
|
|
* @Date 2022年11月6日 上午10:22:31
|
|
* @version 1.0.0
|
|
*/
|
|
@Component
|
|
public class SpringAnnotationUtils implements EnvironmentAware{
|
|
|
|
private static final TanukiCache<String,InvocationHandler> handlerCache= CacheFactory.factory("Invocation-cache");
|
|
|
|
private static final TanukiCache<String,Annotation> findCache = CacheFactory.factory("Annotation-cache");
|
|
|
|
private static final String findKeyFormat="%s@%s";
|
|
|
|
private static final String handlerKeyFormat="%s@%s";
|
|
|
|
private static Environment environment;
|
|
|
|
@SuppressWarnings("unchecked")
|
|
public static <A extends Annotation>A findAnnotation(Class<?> clazz,Class<A> annotationType){
|
|
if(!clazz.isAnnotationPresent(annotationType)) {
|
|
return null;
|
|
}
|
|
String key=String.format(findKeyFormat, clazz.getName(),annotationType.getName());
|
|
if(!findCache.containsKey(key)) {
|
|
findCache.save(key, resolveAnnotationEnvValue(clazz.getAnnotation(annotationType)));
|
|
}
|
|
return (A) findCache.get(key);
|
|
}
|
|
|
|
@SuppressWarnings("unchecked")
|
|
public static <A extends Annotation>A findAnnotation(AnnotatedElement element,Class<A> annotationType){
|
|
if(!element.isAnnotationPresent(annotationType)) {
|
|
return null;
|
|
}
|
|
String key=String.format(findKeyFormat,System.identityHashCode(element),annotationType.getName());
|
|
if(!findCache.containsKey(key)) {
|
|
findCache.save(key, resolveAnnotationEnvValue(element.getAnnotation(annotationType)));
|
|
}
|
|
return (A) findCache.get(key);
|
|
}
|
|
|
|
private static <A extends Annotation>A resolveAnnotationEnvValue(A annotation) {
|
|
Map<String, Object> values=AnnotationUtils.getAnnotationAttributes(annotation);
|
|
if(values!=null) {
|
|
Set<Entry<String, Object>> vs= values.entrySet();
|
|
for (Entry<String, Object> entry : vs) {
|
|
values.put(entry.getKey(),parseValue(entry.getValue()));
|
|
}
|
|
}
|
|
changeValues(annotation, values);
|
|
return annotation;
|
|
}
|
|
|
|
@SuppressWarnings("unchecked")
|
|
public static Map<String,Object> getValues(Annotation annotation){
|
|
String key=String.format(handlerKeyFormat,annotation.getClass().getName(),System.identityHashCode(annotation));
|
|
if(!handlerCache.containsKey(key)) {
|
|
handlerCache.save(key, Proxy.getInvocationHandler(annotation));
|
|
}
|
|
InvocationHandler invocationHandler =handlerCache.get(key);
|
|
try {
|
|
Field declaredField = invocationHandler.getClass().getDeclaredField("memberValues");
|
|
declaredField.setAccessible(true);
|
|
return (Map<String, Object>) declaredField.get(invocationHandler);
|
|
} catch (Exception e) {}
|
|
return null;
|
|
}
|
|
|
|
public static void changeValue(Annotation annotation,String name,Object value) {
|
|
Map<String, Object> values = getValues(annotation);
|
|
if(values!=null) {
|
|
values.put(name,value);
|
|
}
|
|
}
|
|
|
|
public static void changeValues(Annotation annotation,Map<String,Object> attrs) {
|
|
Map<String, Object> values = getValues(annotation);
|
|
if(values!=null) {
|
|
values.putAll(attrs);
|
|
}
|
|
}
|
|
|
|
|
|
private static Object parseValue(Object val) {
|
|
if(environment==null) {
|
|
return val;
|
|
}
|
|
if(val!=null && val instanceof String && RegexUtils.has(val.toString())) {
|
|
String strVal=val.toString();
|
|
List<String> names=RegexUtils.findPlaceholder(strVal);
|
|
String[] values=new String[names.size()];
|
|
for (int i = 0; i < values.length; i++) {
|
|
String key=names.get(i);
|
|
String[] keys=key.split(":");
|
|
if(keys.length==2) {
|
|
if(environment.containsProperty(keys[0])) {
|
|
values[i]=environment.getProperty(keys[0]);
|
|
}else {
|
|
values[i]=keys[1];
|
|
}
|
|
}else {
|
|
values[i] = environment.getProperty(key);
|
|
}
|
|
}
|
|
return RegexUtils.replacePlaceholder(strVal, values);
|
|
}
|
|
return val;
|
|
}
|
|
|
|
|
|
@Override
|
|
public void setEnvironment(Environment environment) {
|
|
SpringAnnotationUtils.environment=environment;
|
|
}
|
|
|
|
}
|