可以@Autowire @Service bean但不是用“new”关键字实例化的类的成员 - 即使配置了上下文扫描

时间:2011-08-22 17:56:48

标签: java spring spring-mvc

我有一个适用于@Autowired @Service bean的应用。

现在我正在添加一个Validator类,它在Controller中实例化:

BlueValidator validator = new BlueValidator(colors);
validator.validate(colorBlend, bindResult);

BlueValidator课程中,我试图@Autowire blendService在应用程序的其他地方作为@Autowired字段工作:

public class BlueValidator implements Validator {
@Autowired
private BlendService blendService;
private Colors colors;

但由于某些原因,在实例化BlueValidator后,我不断为NullPointerException获取blendService

当然我已经添加了必要的上下文扫描:

<context:component-scan 
base-package="com.myapp.controllers, com.myapp.services, com.myapp.validators" />

我还尝试将@Autowired注释添加到构造函数中,但这没有帮助:

@Autowired
public BlueValidator(Colors colors) {
    this.colors = colors;
}

我是否应该将blendService传递给BlueValidator并忘记自动装配,或者这里是否有明显缺失的东西?

4 个答案:

答案 0 :(得分:1)

如果您只是使用new实例化一个对象,则不会涉及Spring,因此自动装配不会启动。组件扫描会查看类并从中创建对象 - 它不会查看您创建的对象自己。

可以使用Spring's AspectJ support,但需要付出一些努力。

否则,如果你要自动装配工作,你需要让Spring实例化你的对象。

  

我应该将blendService传递给BlueValidator并忘记自动装配

在你的情况下,我会说是的,这是最省力的解决方案。

答案 1 :(得分:1)

当您实例化对象时,spring无法为它们执行任何操作,因此它不会注入依赖项(article)。

在您的情况下,您有几个选择:

  • 将依赖关系从控制器传递给验证器(您可以在其中注入它们)
  • 使验证器成为一个spring bean并将其注入,而不是实例化它
  • 使用@Configurable,通过AspectJ,即使在使用new创建的对象中启用弹簧注入

答案 2 :(得分:0)

Spring的@Autowired正在使用

ApplicationContext来填充这些字段。由于ApplicationContext不是创建这些bean的人(因为关键字'new'),因此它们不是自动装配的。如果你正在创建它,你需要自己传递它。

答案 3 :(得分:0)

不要手动创建验证器 - 允许Spring为您执行此操作:

@Controller
class Controller {

    @Autowired
    BlueValidator validator;

    void doSomething() {
        ...
        validator.validate(colorBlend, bindResult);
        ...
    }

}

另外注意将com.myapp.validators包添加到context:scan-packages还不够,还应该使用@Component注释对您的验证器类进行注释:

@Component
public class BlueValidator implements Validator {
@Autowired
private BlendService blendService;

(BTW此解决方案适用于我的项目。)