簡述
當我在工具類中使用static修飾我要自動注入的類的時候,發(fā)現(xiàn)使用的時候會報空指針,為了解決這個問題,讓工具類更完美,為了簡單性,易用性,最好和 @Autowired 和 @Value 使用方式一致,我自定義的注解是 @StaticAutowired,@StaticValue 分別對標上面兩個注解,實現(xiàn)了 @Autowired 和 @Value 的所有功能,外加支持自動注入靜態(tài)屬性
報錯原因

@Autowired 實現(xiàn)原理
AutoWired實現(xiàn)依賴于他自己的后置處理器AutowiredAnnotationBeanPostProcessor,它的集成圖如下

@Autowired 的Bean 后置處理器自動注入Bean的處理在這里
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean
這populateBean中方法開始進入處理屬性值

點進去看具體方法
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessProperties

org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#findAutowiringMetadata

org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#buildAutowiringMetadata
找到罪魁禍首

@Value的實現(xiàn)原理
org.springframework.beans.factory.annotation.QualifierAnnotationAutowireCandidateResolver#findValue
在這個方法中去對@Value處理

找到我們探尋的地方之后開始構建我們自己的注解
@StaticAutowired,@StaticValue(構建思路抄Spring的然后改)
構建注解@StaticValue
```
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
@Documented
public @interface StaticValue {
? ? /**
? ? * 注入靜態(tài)屬性值
? ? */
? ? String value();
}
構建@StaticValue解析類
主要學習了這個方法是如何處理的

```
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的一個學習然后好些方法都是從里面拿,主要思路就是從入口方法開始先拿,然后看入口方法里需要啥我們再拿一個,最后再是去修改
```
@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 String requiredParameterName = "required";
? ? private 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) {
? ? ? ? ? ? Iterator var2 = this.autowiredAnnotationTypes.iterator();
? ? ? ? ? ? while(var2.hasNext()) {
? ? ? ? ? ? ? ? Class<? extends Annotation> type = (Class)var2.next();
? ? ? ? ? ? ? ? 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) {
? ? ? ? ? ? DependencyDescriptor descriptor = (DependencyDescriptor)cachedArgument;
? ? ? ? ? ? Assert.state(this.beanFactory != null, "No BeanFactory available");
? ? ? ? ? ? return this.beanFactory.resolveDependency(descriptor, beanName, (Set)null, (TypeConverter)null);
? ? ? ? } else {
? ? ? ? ? ? return cachedArgument;
? ? ? ? }
? ? }
? ? private void registerDependentBeans(@Nullable String beanName, Set<String> autowiredBeanNames) {
? ? ? ? if (beanName != null) {
? ? ? ? ? ? Iterator var3 = autowiredBeanNames.iterator();
? ? ? ? ? ? while(var3.hasNext()) {
? ? ? ? ? ? ? ? String autowiredBeanName = (String)var3.next();
? ? ? ? ? ? ? ? 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, (PropertyValues)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;
? ? ? ? ? ? // 把數(shù)組改成了的那個元素
? ? ? ? ? ? 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中去掉了對靜態(tài)屬性的直接退出