Spring 4 @Autowire 绑定不正确?

Spring 4 @Autowire not binding correctly?

我正在尝试将一个 bean 自动装配到一个实现,但它 returns 一个空指针异常。

package org.com.api;

public interface Multiply {
    public int multipler(int a, int b);
}

package org.com.core;
import org.com.api.Multiply;

public class MultiplyImpA implements Multiply {
    public int multipler(int a, int b){
        return a*b;
    }
}

package org.com.core;
import org.com.api.Multiply;
public class MultiplyImpB implements Multiply {
    public int multipler(int a, int b){
        int total = 0;
        for(int i = 1; i <=b; i++){
            total += a;
        }
        return total;
    }
}

package org.com.Service;
import org.com.api.Multiply;
public Calculator {
    @Autowire
    private Multiply multiply;
    public int calcMultiply(int a, int b){
        return multiply.multipler(a,b);
    }
}

在我的 applicationContext.xml 中添加了以下内容

<bean id="multiply" class="org.com.core.MultiplyImpA" scope="prototype"/>

现在在运行时我得到一个 NullPointerExpection。乘法为空。

出于测试目的,我尝试了这个。它有效,我明白这里我明确地得到了 Bean。所以这意味着自动接线不起作用?有什么我想念的吗?

Multiply m = (Multiply)factory.getBean("multiply");
System.out.println(m.multiplier(2,4);

自动装配按类型解析,因为有两种不同的实现,你需要使用限定符来缩小范围。所以试试下面的。

public Calculator {
@Autowire
@Qualifier("multiply")
private Multiply multiply ;
public int calcMultiply(int a, int b){
    return multiply.multipler(a,b);
}
}

您的 bean 中似乎有错字 xml。

而不是

<bean id="multiply" class="package org.com.core.MultiplyImpA" scope="prototype"/>

应该是(仅使用完全限定的 class名称)

<bean id="multiply" class="org.com.core.MultiplyImpA" scope="prototype"/>

编辑:

可能的错误是 Calculator class 不受 spring 管理。使用 new 运算符实例化 class 会失败,因为 spring 无法获得引用以注入协作者:

Calculator calculator = new Calculator();
calculator.calcMultiply(1, 2); // would throw a NPE because the `Multiply` instance (in your case `MultiplyImpA`) has not been injected.

因此,改为使用 spring:

实例化 Calculator class
<bean id="calculator" class="org.com.service.Calculator"/>
<bean id="multiply" class="org.com.core.MultiplyImpA"/> 

通过应用程序上下文检索它:

ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("application-context.xml");
Calculator calculator = ctx.getBean(Calculator.class);

Spring 然后将通过扫描 @Autowired 注释、查看字段类型并尝试从应用程序上下文中找到合格的 bean 来管理依赖关系。