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 handlerCache= CacheFactory.factory("Invocation-cache"); private static final TanukiCache 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 findAnnotation(Class clazz,Class 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 findAnnotation(AnnotatedElement element,Class 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 resolveAnnotationEnvValue(A annotation) { Map values=AnnotationUtils.getAnnotationAttributes(annotation); if(values!=null) { Set> vs= values.entrySet(); for (Entry entry : vs) { values.put(entry.getKey(),parseValue(entry.getValue())); } } changeValues(annotation, values); return annotation; } @SuppressWarnings("unchecked") public static Map 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) declaredField.get(invocationHandler); } catch (Exception e) {} return null; } public static void changeValue(Annotation annotation,String name,Object value) { Map values = getValues(annotation); if(values!=null) { values.put(name,value); } } public static void changeValues(Annotation annotation,Map attrs) { Map 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 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; } }