所有!
我有这个片段:
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 注释,则不会创建它。如何启用组件扫描。我的代码出了什么问题?
感谢。
答案 0 :(得分: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);
}
};