静态注入注解@StaticAutowired,@StaticValue(构建思路抄Spring的然后改)
构建注解@StaticValue
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
@Documented
public @interface StaticValue {
/**
* 注入静态属性值
*/
String value();
}
构建@StaticValue解析类
主要学习了这个方法是如何处理的
import org.sonder.ydzy.annotation.StaticValue;
import org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.annotation.AnnotationAttributes;
import java.lang.annotation.Annotation;
public class ExContextAnnotationAutowireCandidateResolver extends ContextAnnotationAutowireCandidateResolver {
private Class<? extends Annotation> valueAnnotationType = StaticValue.class;
@Override
protected Object findValue(Annotation[] annotationsToSearch) {
// 父类 对 @Value 的 value 值解析出来
Object value = super.findValue(annotationsToSearch);
if (value != null) {
return value;
}
//父类解析之后去看这个字段上时候有我们自己的注解,然后拿到这个注解再学习父类那样去解析
if (annotationsToSearch.length > 0) {
AnnotationAttributes attr = AnnotatedElementUtils.getMergedAnnotationAttributes(AnnotatedElementUtils.forAnnotations(annotationsToSearch), this.valueAnnotationType);
if (attr != null) {
return this.extractValue(attr);
}
}
return null;
}
}
构建注解@StaticAutowired
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
@Documented
public @interface StaticAutowired{
/**
* 是否必须有
*/
boolean required() default true;
}
构建@StaticAutowired解析类
这块的话主要是对AutowiredAnnotationBeanPostProcessor的一个学习然后好些方法都是从里面拿,主要思路就是从入口方法开始先拿,然后看入口方法里需要啥我们再拿一个,最后再是去修改
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.sonder.ydzy.annotation.StaticAutowired;
import org.sonder.ydzy.annotation.StaticValue;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.TypeConverter;
import org.springframework.beans.factory.*;
import org.springframework.beans.factory.annotation.InjectionMetadata;
import org.springframework.beans.factory.config.DependencyDescriptor;
import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor;
import org.springframework.beans.factory.support.AutowireCandidateResolver;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.core.Ordered;
import org.springframework.core.PriorityOrdered;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
import java.beans.PropertyDescriptor;
import java.lang.annotation.Annotation;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
@Component
public class StaticAutowiredAnnotationBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
protected final Log logger = LogFactory.getLog(this.getClass());
/**
* 支持的注解
*/
private final Set<Class<? extends Annotation>> autowiredAnnotationTypes = new LinkedHashSet<>(4);
private final String requiredParameterName = "required";
private final boolean requiredParameterValue = true;
private final ExContextAnnotationAutowireCandidateResolver
exContextAnnotationAutowireCandidateResolver = new ExContextAnnotationAutowireCandidateResolver();
@Nullable
private DefaultListableBeanFactory beanFactory;
private final Map<String, InjectionMetadata> injectionMetadataCache = new ConcurrentHashMap(256);
public StaticAutowiredAnnotationBeanPostProcessor() {
this.autowiredAnnotationTypes.add(StaticAutowired.class);
this.autowiredAnnotationTypes.add(StaticValue.class);
}
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
AutowireCandidateResolver autowireCandidateResolver = beanFactory.getAutowireCandidateResolver();
// 为了 解析 @StaticValue 必须使用 自定义的 ExContextAnnotationAutowireCandidateResolver
boolean isExContextAnnotationAutowireCandidateResolver = autowireCandidateResolver instanceof ExContextAnnotationAutowireCandidateResolver;
try {
if (!isExContextAnnotationAutowireCandidateResolver) {
beanFactory.setAutowireCandidateResolver(exContextAnnotationAutowireCandidateResolver);
}
metadata.inject(bean, beanName, pvs);
} catch (BeanCreationException ex) {
throw ex;
} catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of static autowired dependencies failed", ex);
} finally {
// 设置回原来的
if (!isExContextAnnotationAutowireCandidateResolver) {
beanFactory.setAutowireCandidateResolver(autowireCandidateResolver);
}
}
return pvs;
}
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
String cacheKey = StringUtils.hasLength(beanName) ? beanName : clazz.getName();
InjectionMetadata metadata = (InjectionMetadata) this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized (this.injectionMetadataCache) {
metadata = (InjectionMetadata) this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
if (metadata != null) {
metadata.clear(pvs);
}
metadata = this.buildAutowiringMetadata(clazz);
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
private InjectionMetadata buildAutowiringMetadata(Class<?> clazz) {
List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
Class<?> targetClass = clazz;
do {
List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
ReflectionUtils.doWithLocalFields(targetClass, (field) -> {
AnnotationAttributes ann = this.findAutowiredAnnotation(field);
// 这里改动
if (ann != null) {
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("StaticAutowired annotation is supported on static fields: " + field);
}
}
// 这里也有改动让其用我们自己的去处理
boolean required = this.determineRequiredStatus(ann);
currElements.add(new StaticAutowiredAnnotationBeanPostProcessor.AutowiredFieldElement(field, required));
}
});
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
} while (targetClass != null && targetClass != Object.class);
return new InjectionMetadata(clazz, elements);
}
protected boolean determineRequiredStatus(AnnotationAttributes ann) {
return !ann.containsKey(this.requiredParameterName) || this.requiredParameterValue == ann.getBoolean(this.requiredParameterName);
}
@Nullable
private AnnotationAttributes findAutowiredAnnotation(AccessibleObject ao) {
if (ao.getAnnotations().length > 0) {
for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(ao, type);
if (attributes != null) {
return attributes;
}
}
}
return null;
}
@Nullable
private Object resolvedCachedArgument(@Nullable String beanName, @Nullable Object cachedArgument) {
if (cachedArgument instanceof DependencyDescriptor descriptor) {
Assert.state(this.beanFactory != null, "No BeanFactory available");
return this.beanFactory.resolveDependency(descriptor, beanName, null, null);
} else {
return cachedArgument;
}
}
private void registerDependentBeans(@Nullable String beanName, Set<String> autowiredBeanNames) {
if (beanName != null) {
for (String autowiredBeanName : autowiredBeanNames) {
if (this.beanFactory != null && this.beanFactory.containsBean(autowiredBeanName)) {
this.beanFactory.registerDependentBean(autowiredBeanName, beanName);
}
if (this.logger.isDebugEnabled()) {
this.logger.debug("Autowiring by type from bean name '" + beanName + "' to bean named '" + autowiredBeanName + "'");
}
}
}
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
if (!(beanFactory instanceof DefaultListableBeanFactory)) {
throw new IllegalArgumentException("StaticAutowiredAnnotationBeanPostProcessor requires a DefaultListableBeanFactory: " + beanFactory);
} else {
this.beanFactory = (DefaultListableBeanFactory) beanFactory;
}
}
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
InjectionMetadata metadata = this.findAutowiringMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE - 2;
}
private static class ShortcutDependencyDescriptor extends DependencyDescriptor {
private final String shortcut;
private final Class<?> requiredType;
public ShortcutDependencyDescriptor(DependencyDescriptor original, String shortcut, Class<?> requiredType) {
super(original);
this.shortcut = shortcut;
this.requiredType = requiredType;
}
@Override
public Object resolveShortcut(BeanFactory beanFactory) {
return beanFactory.getBean(this.shortcut, this.requiredType);
}
}
private class AutowiredFieldElement extends InjectionMetadata.InjectedElement {
private final boolean required;
private volatile boolean cached = false;
@Nullable
private volatile Object cachedFieldValue;
public AutowiredFieldElement(Field field, boolean required) {
super(field, (PropertyDescriptor) null);
this.required = required;
}
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
// 把数组改成了的那个元素
Object value;
if (this.cached) {
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
} else {
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
Assert.state(beanFactory != null, "No BeanFactory available");
TypeConverter typeConverter = beanFactory.getTypeConverter();
try {
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
} catch (BeansException var12) {
throw new UnsatisfiedDependencyException((String) null, beanName, new InjectionPoint(field), var12);
}
synchronized (this) {
if (!this.cached) {
if (value == null && !this.required) {
this.cachedFieldValue = null;
} else {
this.cachedFieldValue = desc;
registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = (String) autowiredBeanNames.iterator().next();
if (beanFactory.containsBean(autowiredBeanName) && beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
this.cachedFieldValue = new StaticAutowiredAnnotationBeanPostProcessor.ShortcutDependencyDescriptor(desc, autowiredBeanName, field.getType());
}
}
}
this.cached = true;
}
}
}
if (value != null) {
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
}
}
总结
从解析的入口方法开始,从AutowiredAnnotationBeanPostProcessor缺啥拿啥
buildAutowiringMetadata中去掉了对静态属性的直接退出
- 未经尝试的方法
另一篇大佬的博客https://blog.csdn.net/NaTook/article/details/121727539
使用@InjectStaticField
通过实现 SpringApplicationRunListener 接口,在Spring应用启动时实现注入静态变量的逻辑