【问题标题】:Spring 4 - Object won't autowire variableSpring 4 - 对象不会自动装配变量
【发布时间】:2015-05-02 22:25:27
【问题描述】:

我有我的junit测试课:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { AppConfig.class })
@WebAppConfiguration
public class TelephoneNumberTest {

@Autowired //Test that bean exists in application context
private void setPhoneNumberValidator(PhoneNumberValidator phoneNumberValidator){
    this.phoneNumberValidator = phoneNumberValidator;
}

@Test
public void autoWireValidatorTest(){
    assertNotNull(phoneNumberValidator); //Test passes

}

@Test
public void validUSNumber(){
    PhoneNumber phoneNumber = null;
    ContactType expectedContactType = ContactType.PRIMARY;
    Country expectedCountry = Country.UNITED_STATES;
    String expectedAreaCode = "940";
    String expectedExchangeCode = "368";
    String expectedLocalNumber = "7410";

    try {
        phoneNumber = new TelephoneNumber(expectedContactType, expectedCountry, expectedAreaCode,
                expectedExchangeCode, expectedLocalNumber);
    } catch (InvalidPhoneNumberException e) {
        fail(e.getMessage());
    }

    assertNotNull(phoneNumber);
    assertThat(phoneNumber.getContactType(), is(expectedContactType));
    assertThat(phoneNumber.getCountry(), is(expectedCountry));
    assertThat(phoneNumber.getAreaCode(), is(expectedAreaCode));
    assertThat(phoneNumber.getExchangeCode(), is(expectedExchangeCode));
    assertThat(phoneNumber.getLocalNumber(), is(expectedLocalNumber));
}
}

我的应用配置

@Configuration
@EnableWebMvc
@ComponentScan("software.userprofile")
public class AppConfig {}

我的电话号码对象

package software.userprofile.models;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import software.userprofile.models.exceptions.InvalidPhoneNumberException;
import software.userprofile.models.validators.*;

import java.util.Comparator;

public class TelephoneNumber implements PhoneNumber{
private ContactType contactType;
private Country country;
private String areaCode;
private String exchangeCode;
private String localNumber;
private PhoneNumberValidator phoneNumberValidator;

public TelephoneNumber() {}

public TelephoneNumber(ContactType contactType, Country country, String areaCode, String exchangeCode, String localNumber) throws InvalidPhoneNumberException {
    this.contactType = contactType;
    this.country = country;
    this.areaCode = areaCode;
    this.exchangeCode = exchangeCode;
    this.localNumber = localNumber;
    validate();
}

public ContactType getType() {
    return contactType;
}

public Country getCountry() {
    return country;
}

public String getAreaCode() {
    return areaCode;
}

public String getExchangeCode(){return exchangeCode;}

public String getLocalNumber() {
    return localNumber;
}

public PhoneNumberValidator getPhoneNumberValidator(){
    return phoneNumberValidator;
}

@Autowired
private void setPhoneNumberValidator(PhoneNumberValidator phoneNumberValidator){
    this.phoneNumberValidator = phoneNumberValidator;
}

public void validate() throws InvalidPhoneNumberException {
    phoneNumberValidator.doValidation(country, this);
}

@Override
public String toString() {
    return "TelephoneNumber{" +
            "contactType=" + contactType +
            ", country='" + country + '\'' +
            ", areaCode='" + areaCode + '\'' +
            ", exchangeCode='" + exchangeCode + '\'' +
            ", localNumber='" + localNumber + '\'' +
            '}';
}

public static Comparator<TelephoneNumber> COMPARE_BY_TYPE = new Comparator<TelephoneNumber>() {
    public int compare(TelephoneNumber one, TelephoneNumber other) {
        return one.getType().compareTo(other.getType());
    }
};
}

最后是我的 PhoneNumberValidator 类

package software.userprofile.models.validators;

import org.springframework.stereotype.Component;
import software.userprofile.models.Country;
import software.userprofile.models.PhoneNumber;
import software.userprofile.models.exceptions.InvalidPhoneNumberException;

import java.util.*;

@Component
public class PhoneNumberValidator {
private Map<Country, PhoneNumberCountryValidator> phoneNumberValidators = new HashMap<Country, PhoneNumberCountryValidator>();
private Country defaultCountry;

public PhoneNumberValidator(){
    init();
}

private void init(){
    phoneNumberValidators.put(Country.UNITED_STATES, new USPhoneNumberCountryValidator());
    phoneNumberValidators.put(Country.UNITED_KINGDOM, new UKPhoneNumberValidator());
    phoneNumberValidators.put(Country.MEXICO, new MexicoPhoneNumberCountryValidator());
    phoneNumberValidators.put(Country.CANADA, new CanadaPhoneNumberValidator());
}

public void doValidation(Country country, PhoneNumber phoneNumber) throws InvalidPhoneNumberException {
    if(country == null){throw new InvalidPhoneNumberException("Country code is null");}
    phoneNumberValidators.get(country).validate(phoneNumber);

}

public void setPhoneNumberValidators(Map<Country, PhoneNumberCountryValidator> phoneNumberValidators) {
    this.phoneNumberValidators = phoneNumberValidators;
}

}

我的问题:TelephoneNumberClass 中的 PhoneNumberValidator 对象不是自动装配的,当我运行测试时,我在 PhoneNumberValidator 的 doValidation() 实例中遇到空指针异常。我唯一能想到的是,TelephoneNumber 类没有被 spring 识别,但我不知道如何解决这个问题。

我查看了网站上的几个帖子,但没有任何效果。

有什么想法吗?

【问题讨论】:

    标签: java junit autowired spring-4


    【解决方案1】:

    TelephoneNumber类不是spring管理的,需要通知spring作为bean来管理。例如

    @Component
    public class TelephoneNumber implements PhoneNumber {...}
    

    【讨论】:

    • 我刚试过,但没有运气:(,我得到了同样的错误
    • 在您的测试类中,您没有注入 spring bean,而是像这样手动创建 PhoneNumber 实例 phoneNumber = new TelephoneNumber ,因此只需调用 phoneNumber.setPhoneNumberValidator 或注入 phoneNumber bean
    【解决方案2】:

    您正在使用 new 创建 TelephoneNumber。你应该从 applicationContext 获取它(作为 prototype 所以它总是返回一个新的)。或者如果你需要使用new,那么你可以启用Spring aspect和一个agent。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-01
      • 2012-08-13
      • 2017-08-06
      • 2018-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多