我正在使用Java + Spring进行一些编码。像,
public interface PeopleService {}
public class CustomerService implemented PeopleService {}
public class EmployeeService implemented PeopleService {}
如果我在这样的代码中使用@Autowired,
@Autowired
protected PeopleService peopleService;
应用程序抛出异常“没有定义类型为[xxxxxxxx]的唯一bean:预期的单个匹配bean但找到了2.”在运行时。通过添加@Qualifier(“xxxxxx”)可以轻松解决问题。但是,此问题的烦人部分是异常仅在运行时弹出。通过这种方式,如果我不事先手动检查注释。一旦应用程序达到自动装配点,它就会抛出异常。
我不是手动检查的粉丝。只是想知道,在运行应用程序之前是否存在测试/检测此类异常的智能方法(例如在应用程序初始化期间或编译期间)?
非常感谢。
修改
最后,我刚刚提出了一个测试解决方案,该测试将找到扩展BasicService的所有类,并逐个初始化它们以测试每个类中自动装配bean的唯一性。
@Test
public void autowireValidationForAllSubclassOfBaseService() {
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
provider.addIncludeFilter(new AssignableTypeFilter(BasicService.class));
Set<BeanDefinition> serverResources = provider.findCandidateComponents("path/class");
AutowireCapableBeanFactory beanFactory = applicationContext.getAutowireCapableBeanFactory();
for (BeanDefinition serverResource : serverResources) {
try {
Class<? extends BasicService> serverResourceClass =
(Class<? extends BasicService>) Class.forName(serverResource.getBeanClassName());
Object bean = beanFactory.createBean(serverResourceClass, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, false);
beanFactory.initializeBean(bean, serverResourceClass.getSimpleName());
} catch (Exception e) {
Assert.assertTrue(false, "Autowired might not be handled properly " + e.getMessage());
}
}
}
这可能不是最好的方法,但我现在很满意,因为它可以正常运行并检测所有可能的自动装配问题。
答案 0 :(得分:2)
尝试先添加@Service 公共类CustomerService实现了PeopleService {}
答案 1 :(得分:0)
好吧,您不需要使用@Autowired
。您始终可以通过xml或java进行显式连接。
要连接以下课程,您可以:
public class MyBean {
private PeopleService peopleService;
public MyBean(PeopleService peopleService) {
this.peopleService = peopleService;
}
}
XML:
<bean id="customerService" class="the.package.containing.customerservice.CustomerService"/>
<bean id="employeeService" class="the.package.containing.employeeService.EmployeeService"/>
<bean id="myBean" class="the.package.containing.mybean.MyBean">
<constructor-arg ref="employeeService"/>
</bean>
爪哇:
@Configuration
public class AppConfig {
@Bean
public PeopleService customerService() {
return new CustomerService();
}
@Bean
public PeopleService employeeService() {
return new EmployeeService();
}
@Bean
public MyBean myBean() {
return new MyBean(customerService());
}
}
由于您似乎是在编译时类型安全之后,我建议使用基于Java的方法,因为它为您提供了编译时保证。
答案 2 :(得分:0)
最后,我刚刚提出了一个测试解决方案,该测试将找到扩展BasicService的所有类,并逐个初始化它们以测试每个类中自动装配bean的唯一性。
@Test
public void autowireValidationForAllSubclassOfBaseService() {
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
provider.addIncludeFilter(new AssignableTypeFilter(BasicService.class));
Set<BeanDefinition> serverResources = provider.findCandidateComponents("path/class");
AutowireCapableBeanFactory beanFactory = applicationContext.getAutowireCapableBeanFactory();
for (BeanDefinition serverResource : serverResources) {
try {
Class<? extends BasicService> serverResourceClass =
(Class<? extends BasicService>) Class.forName(serverResource.getBeanClassName());
Object bean = beanFactory.createBean(serverResourceClass, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, false);
beanFactory.initializeBean(bean, serverResourceClass.getSimpleName());
} catch (Exception e) {
Assert.assertTrue(false, "Autowired might not be handled properly " + e.getMessage());
}
}
}
这可能不是最好的方法,但我现在很满意,因为它可以正常运行并检测所有可能的自动装配问题。