Files
geg-gas-pcitc/itc-pcitc-dependencies/itc-pcitc-dependencies-service/src/main/java/com/pictc/utils/SpringAnnotationUtils.java
2025-10-10 09:20:48 +08:00

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;
}
}