Я пытаюсь Autowire bean к реализации, но он возвращает null-указатель Exception.
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. умножить - null.
для тестирования я пробовал это. Он работает, я понимаю, что я явно получаю Bean. Значит, это означает, что autwire не работает? есть что-то, что я не вижу?
Multiply m = (Multiply)factory.getBean("multiply");
System.out.println(m.multiplier(2,4);
Кажется, у вас есть опечатка в вашем bean файле.
Вместо
<bean id="multiply" class="package org.com.core.MultiplyImpA" scope="prototype"/>
он должен быть (используя только полное имя класса)
<bean id="multiply" class="org.com.core.MultiplyImpA" scope="prototype"/>
РЕДАКТИРОВАТЬ:
Возможная ошибка может заключаться в том, что класс Calculator
не управляется весной. Создание экземпляра класса с использованием new
оператора завершится неудачно, потому что нет никакой возможности, чтобы весна получала ссылку на инъекцию соавтора:
Calculator calculator = new Calculator();
calculator.calcMultiply(1, 2); // would throw a NPE because the 'Multiply' instance (in your case 'MultiplyImpA') has not been injected.
Поэтому вместо этого создайте экземпляр класса Calculator
используя весну:
<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
, глядя на тип поля и пытаясь найти квалифицированный компонент из контекста приложения.
Autowiring разрешается по типу, так как есть два разных имплантата, вам нужно использовать квалификатор, чтобы сузить его. Попробуйте ниже.
public Calculator {
@Autowire
@Qualifier("multiply")
private Multiply multiply ;
public int calcMultiply(int a, int b){
return multiply.multipler(a,b);
}
}
Calculator
?