简体   繁体   中英

Spring IOC GenericXmlApplicationContext does not work component scanning

All!

I have this snippet:

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

Where I'm trying to create new application context with custom classloader. Context file looks like:

<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>

Question: why I can get the TestService if only it is explicitly declared in context file, if this service has @Service annotation it is not created. How to enable component scanning. What is wrong in my code?

Thanks.

I think the problem is here https://jira.springsource.org/browse/SPR-3815 .

The solution after debugging the Spring Core could look like:

If we see into class GenericXmlApplicationContext we will see that is has field (xml reader)

private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);

which will be called thought the chain of invocations to ask for BeanDefinitionRegistry

which will be asked for getting resources during scanning for classes process where parameters will be like this one: classpath*:some/package/name/**/*.class

org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider#findCandidateComponents

That means GenericXmlApplicationContext could have overridden methods responsible for this:

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);
    }
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM