0

全て!

私はこのスニペットを持っています:

SomeCustomClassLoader customClassLoader = new SomeCustomClassLoader();
GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();
ctx.setClassLoader(customClassLoader);
ctx.load(new ByteArrayResource(bytesData));
ctx.refresh();
Object testService = ctx.getBean("testService");

カスタムクラスローダーで新しいアプリケーションコンテキストを作成しようとしている場所。コンテキスト ファイルは次のようになります。

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-3.1.xsd
           ">

    <context:annotation-config />

    <context:component-scan base-package="some.base.package" />

    <bean name="testService" class="some.base.package.TestService"/>
</beans>

質問:コンテキスト ファイルで明示的に宣言されている場合のみTestServiceを取得できるのはなぜですか。このサービスに@Serviceアノテーションがある場合は作成されません。コンポーネントのスキャンを有効にする方法。私のコードで何が間違っていますか?

ありがとう。

4

1 に答える 1

0

問題はここにあると思いますhttps://jira.springsource.org/browse/SPR-3815

Spring Core をデバッグした後のソリューションは次のようになります。

クラスGenericXmlApplicationContextを見ると、フィールド (xml リーダー) があることがわかります。

private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);

これは、 BeanDefinitionRegistryを要求する一連の呼び出しを考えて呼び出されます

クラスプロセスのスキャン中にリソースを取得するように求められます。パラメータは次のようになります: classpath*:some/package/name/**/*.class

org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider#findCandidateComponents

これは、GenericXmlApplicationContext がこれを担当するオーバーライドされたメソッドを持っている可能性があることを意味します。

GenericXmlApplicationContext ctx = new GenericXmlApplicationContext() {
    @Override
    public Resource[] getResources(String locationPattern) throws IOException {
        if(locationPattern.endsWith(".class")) {
            List<byte[]> classes = customClassLoader.getAllClasses();
            Resource[] resources = new Resource[classes.size()];
            for (int i = 0; i < classes.size(); i++) {
                resources[i] = new ByteArrayResource(classes.get(i));
            }
            return resources;
        }

        return super.getResources(locationPattern);
    }
};
于 2013-03-10T10:00:11.470 に答える