【问题标题】:Injecting Beans using Spring Annotations into Constructor Parameters with Property Placeholder使用 Spring Annotations 将 Beans 注入带有属性占位符的构造函数参数
【发布时间】:2016-09-20 19:20:31
【问题描述】:

我在将 Bean 类型从属性文件注入构造函数参数时遇到问题。 我可以通过直接将值传递给 @Qualifier("beanName") 来注入它,如下所示。

@Component("circle")
public class Circle implements Shape {

}

@RestController  
class MyController {    
    private final Shape shape;

    @Autowired
    public MyClass(@Qualifier("circle")
            Shape shape) {
    this.shape = shape;     
    }
}

但是,以下代码示例不起作用。

这将返回 Null。

@RestController
class MyController {    
    private final Shape shape;

    @Autowired
    public MyClass(@Qualifier("${shape}")
            Shape shape) {
    this.shape = shape;     
    }
}

尝试使用 @Resource(name="${shape}") 代替 @Qualifier ,如此处所述( Spring: Using @Qualifier with Property Placeholder) 但得到编译器错误 " '@Resource' 不适用于参数"

@Resource("${shape}") 给出错误 “找不到方法‘值’”

这也不起作用:

@RestController
class MyController {    
    @Value("${shape}")
    private final String shapeBean; //Compiler error : "Variable 'shapeBean' might not have been initialised"
    //Not declaring shapeBean as final will give a compiler error at @Qualifier: "Attribute value must be constant"
    private final Shape shape;

    @Autowired
    public MyClass(@Qualifier(shapeBean)
            Shape shape) {
    this.shape = shape;     
    }
}

下面的代码也不起作用。在 @Qualifier 处给出编译器错误:“属性值必须是常量”。

@RestController
class MyController {    
    @Value("${shape}")
    private final String shapeBean;
    private final Shape shape;

    @Autowired
    public MyClass(@Qualifier(shapeBean)
            Shape shape) {
    this.shape = shape;     
    }
}

还尝试了以下方法。两者都在尝试访问形状时抛出 NullPointerException。

@Resource(name="${shape}")
private Shape shape; // In addition, throws a warning saying, "Private field 'shape' is never assigned"

@Autowired  
@Resource(name="${shape}")
private Shape shape;

如果构造函数参数是原始参数或字符串,我可以只使用 @Value("${shape}") 并将值注入变量。但由于它是一个类,我不知道如何完成它。
有人可以告诉我我是否配置不正确或我应该做什么?

【问题讨论】:

  • 所以您想在运行时选择不同的形状?一般来说,你会使用类似配置文件的东西。你能更具体地介绍一下你的实际应用吗?
  • 从上面的例子假设,我有一个 Shape 接口和实现 shape 的具体类。但现在在我的控制器中,我只想将圆形注入到 Shape 对象中。我之前使用过完美的 @Qualifier("circle") 。但由于我不想保持硬编码,我想从属性文件中获取它。有什么方法可以从属性文件中获取值,然后将该值注入到 Shape 对象中?

标签: java spring spring-boot autowired spring-annotations


【解决方案1】:

Circle 不会实现所有在 Shape 中定义的方法吗? - 只要满足形状的合同,你应该没问题。现在,如果您有多个形状,比如三角形、矩形和圆形,并且由于某种原因您想要动态加载确切的子类,您可能想要使用 ApplicationContext.getBean("") 获取特定的 bean。

您可以通过覆盖 afterPropertiesSet() 来维护对各种可能形状的引用 - 查看 InitialingBean 并在运行时使用正确的 bean。

【讨论】:

  • 目前我使用的是 Circle 提供的服务。在某些时候,我可能会停止使用 Circle 提供的服务并订阅 Triangle 提供的服务。因此,作为修复,我想在我的属性文件中声明服务提供者,而不是在我的控制器中声明它。有没有办法使用注释来分配属性值?
  • 是的,最简单的方法是使用 spring 配置文件来激活一组基于 spring.profile.active 环境变量的 bean,下面给出了简单的教程spring.io/blog/2011/02/14/spring-3-1-m1-introducing-profilemkyong.com/spring/spring-profiles-example
猜你喜欢
  • 1970-01-01
  • 2019-03-10
  • 1970-01-01
  • 2015-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-08
  • 1970-01-01
相关资源
最近更新 更多