使用Spring注解将Bean注入构造函数参数并使用Property占位符

问题描述:

我无法将Bean类型注入属性文件的构造函数参数中。 我可以通过直接将值传递给@Qualifier(“beanName”)来注入它,如下所示。使用Spring注解将Bean注入构造函数参数并使用Property占位符

@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。

​​

到位@Qualifier使用@Resource(NAME = “$ {}形”)这里提到( Spring: Using @Qualifier with Property Placeholder) 但让编译器错误 “ '@资源' 并不适用于参数” 尝试

@Resource( “$ {}形”)给出了错误 “找不到方法 '价值'”

这并不工作过:

@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}”)并将值注入到变量中。但因为它是一个类,我不知道如何完成它。
有人可以告诉我,如果我配置不正确或我应该做什么?

+0

所以你想在运行时选择不同的形状?一般来说,你会使用像这样的配置文件。你能对你的实际应用更具体吗? – chrylis

+0

从上面的例子中可以看出,我有一个Shape接口和具体类实现形状。但现在在我的控制器中,我只想将圆形状注入到Shape对象中。我之前使用的@Qualifier(“circle”)完美运作。但由于我不想保留硬编码,我想从属性文件中获取它。有什么办法可以从属性文件中获取值,然后将该值插入到Shape对象中? – Arthas

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

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

+0

现在我正在使用Circle提供的服务。在某些时候,我可能会停止使用_Circle_提供的服务,并订阅_Triangle_提供的服务。因此,为了解决问题,我想在我的属性文件中声明服务提供者,而不是在我的Controller中声明它。有没有办法使用注释分配属性值? – Arthas

+0

是的,最简单的方法是使用spring配置文件根据spring.profile.active env变量激活一组bean。简单教程在 https:// spring下面给出。io/blog/2011/02/14/spring-3-1-m1-introduction-profile/ http://www.mkyong.com/spring/spring-profiles-example/ – JVXR