【问题标题】:Spring: How to inject a String bean to the constructor?Spring:如何将 String bean 注入构造函数?
【发布时间】:2017-01-10 14:09:36
【问题描述】:

我有一堂课Config

Config.java

public class Config {
    private final String p = "Prop";

    @Bean
    public String getP(){return p;}
}

我如何将它注入一些构造函数,即:

public class SomeC {
    private String p;

    public SomeC(String p) {
        this. p = p;
    }
}

我希望这个字符串 p 从 Config 中注入值。这可能吗?

【问题讨论】:

    标签: java spring spring-mvc


    【解决方案1】:

    您必须为 bean 命名,然后在自动装配引用该名称时使用 @Qualifier 注释。

    例子:

    Config.java

    public class Config {
        private final String p = "Prop";
    
        @Bean(name="p")
        public String getP(){return p;}
    }
    

    SomeC.java

    public class SomeC {
        private String p;
    
        @Autowired
        public SomeC(@Qualifier("p") String p) {
            this. p = p;
        }
    }
    

    【讨论】:

    • 你可以使用类似@Qualifier(Config.BEAN_NAME) 的东西吗?如果你在那里指定 BEAN_NAME?
    • 是的,你可以这样做。我之前在需要在多个位置引用 bean 名称的应用程序中这样做了。
    • 如果你将你的 bean method() 命名为 public String p(){return p;} ,那么 @Qualifier 不是必需的。这很简单。
    • @SundararajGovindasamy 仍然需要限定符,但 @Bean 上不需要 name
    • 你只有一个名为'p'的bean,那你为什么需要@Qualifer?
    【解决方案2】:

    你应该像这样使用@Autowired

    @Autowired
    public SomeC(String p){
      this.p = p;
    }
    

    或者像这样:

    public class SomeC {
    
      @Autowired
      private String p;
    
    }
    

    我更喜欢第二种方法,但这会使类更难测试,因为从外部看不到依赖项,因此请谨慎使用。

    【讨论】:

    • 如果你的应用中有多个 String bean 怎么办?那么它如何知道要自动装配哪一个呢?
    • 按名称或限定符。我更喜欢名字
    【解决方案3】:

    如果只有一个String-type bean,你可以不做任何改变。可以按类型注入。

    @Configuration
    public class Config {
        private final String p = "Prop";
    
        @Bean
        public String getP() {
            return p;
        }
    }
    
    @Component
    public class SomeC {
    
        private String p;
    
        public SomeC(String p) {
            this.p = p;
        }
    }
    

    如果有多个String-type bean,可以按名称注入。

    @Configuration
    public class Config {
        private final String p = "Prop";
        private final String q = "AnotherProp";
    
        @Bean
        public String getP() {
            return p;
        }
        
        @Bean
        public String getQ() {
            return q;
        }
    }
    
    @Component
    public class SomeC {
    
        @Resource(name = "getP")
        private String p;
    

    默认 bean 名称是方法名称 getP。 可以通过@Bean("customName")注解重命名。

    注意:

    如果您打算通过名称来表达注解驱动的注入,请不要主要使用@Autowired (snip)。而是使用 JSR-250 @Resource 注释

    @Resource 仅支持具有单个参数的字段和 bean 属性设置器方法。

    限定符注入可用于构造函数注入。

    @Configuration
    public class Config {
        private final String p = "Prop";
        private final String q = "AnotherProp";
    
        @Bean
        @Qualifier("p")
        public String getP() {
            return p;
        }
    
        @Bean
        @Qualifier("q")
        public String getQ() {
            return q;
        }
    }
    
    @Component
    public class SomeC {
    
        private String p;
    
        public SomeC(@Qualifier("p") String p) {
            this.p = p;
        }
    }
    

    This answer 是一种后备行为。名称和限定符是不同的。

    对于后备匹配,bean 名称被视为默认限定符值。

    【讨论】:

      【解决方案4】:
      public class SomeC {
        private String p;
      
        public SomeC(@Value("prop") String p) {
          this. p = p;
        }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-05-11
        • 2018-04-29
        • 1970-01-01
        • 2019-03-10
        • 1970-01-01
        • 1970-01-01
        • 2016-11-26
        • 2019-05-15
        相关资源
        最近更新 更多