Spring枚举变量的注入&构造函数

public enum EventType {
    IP_CHANGE,REGISTER_SERVER
}
   @Data
    static public class Entry{
        private EventType eventType;
        private CopyOnWriteArrayList<EventListener> listeners;

        public Entry(EventType eventType){
            this.eventType = eventType;
            this.listeners = new CopyOnWriteArrayList<>();
        }

        //public Entry(){
        //}
    }

想使用Spring 构建一个bean id="IP_CHANGE_ENTRY"的Entry对象,可是EventType是枚举类型,因此必须使用java

org.springframework.beans.factory.config.FieldRetrievingFactoryBean实现枚举类型的注入,将EventType.IP_CHANGE放入静态字段便可。spring

为何是静态字段呢,由于Java枚举型是静态常量,隐式地用static final修饰过,使用CRFjava -jar cfr_0_124.jar EventType.class --sugarenums false反编译结果以下:函数

当静态字段注册完成后,运行会报错this

从错误里看是由于存在两个EventType,在Entry构造函数中注入EventType时,Spring不知道注入谁。解决方法有二种,第一种:3d

为何要必需要添加默认无参构造函数呢,源码关键在code

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

这里是返回candidateConstructors 仍是null会影响到下面的走势,若是是null,直接进入instantiateBean,反之,进入autowireConstructor,一旦进入这个,会存在缺乏primary致使的没法决策哪个bean的问题。对象

第二种:使用primary=true来告诉Spring优先使用这个Bean,默认是false,解释:Indicates that a bean should be given preference when multiple candidates are qualified to autowire a single-valued dependency. If exactly one 'primary' bean exists among the candidates, it will be the autowired value.blog

当一个类有多个bean时,添加primary=true表示该bean优先于其余bean被注入ip

下面分析与primary相关的源码

org.springframework.beans.factory.support.DefaultListableBeanFactory#doResolveDependency

进入org.springframework.beans.factory.support.DefaultListableBeanFactory#determineAutowireCandidate

在选择自动注入的bean时,有2个选择依据,分别是primary & priority。若是IP_CHANGE_TYPE设置了primary,则primaryCandidate会被设置为IP_CHANGE_TYPE,并做为被注入者返回

若是bean中定义了primary,例如

<bean id = "IP_CHANGE_TYPE" primary="true" class="..."/>,则该方法会返回true,会执行到primaryName=candidateBeanName,primaryName被赋值为IP_CHANGE_TYPE

getMergedLocalBeanDefition会返回一个REGISTER_SERVER_TYPE的AbstractBeanDefition对象,该对象描述了xml中REGISTER_SERVER_TYPE bean的定义规则,该bean没有定义primary,默认为false,因此isPrimary()返回的是false

相关文章
相关标签/搜索