2

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 を拡張するすべてのクラスを検出し、それらを 1 つずつ初期化して、各クラス内の自動配線された 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());
        }
    }
}

これは最善の方法ではないかもしれませんが、実際に実行する前に機能し、考えられるすべての自動配線の問題を検出するので、今のところ満足しています。

4

3 に答える 3

2

public class CustomerService が PeopleService を実装する前に @Service を追加してみてください {}

于 2012-11-28T03:06:36.837 に答える
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 ベースのアプローチを使用することをお勧めします。

于 2012-11-28T02:42:56.180 に答える
0

最後に、BasicService を拡張するすべてのクラスを検索し、それらを 1 つずつ初期化して、各クラス内の自動配線された 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());
        }
    }
}

これは最善の方法ではないかもしれませんが、実際に実行する前に機能し、考えられるすべての自動配線の問題を検出するので、今のところ満足しています。

于 2012-11-29T05:43:41.977 に答える