问题描述
Java 9和11通常需要使用自定义类加载器。因此,我创建了一个BootstrapClassloader
来预加载我的类路径,然后使用Thread.currentThread().setContextClassLoader(classloader)
将其设置为默认值。
在使用new ClasspathXmlApplicationContext()
加载上下文时,我很快发现Spring恢复到原始应用程序类加载器。
我认为没问题,并写了一个名为BootstrapClassLoader
的变体,试图迫使Spring使用我的类加载器。但是Spring仍然忽略了我的类加载器。
例如,我验证了aopalliance-1.0.jar在类加载器的类路径中,并且可以手动加载MethodInterceptor
。但是,如果我有一个使用标准DBCP2数据源bean(取决于aopalliance)的上下文,并且它为ClassNotFoundException
抛出了org.aopalliance.intercept.MethodInterceptor
。
任何人都可以看到下面的代码中的缺陷,或者也许有一些特殊的方法来注册类加载器,以便Spring始终在应用程序中使用它吗?
数据源代码段:
<bean id="mssqlDataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.microsoft.sqlserver.jdbc.sqlServerDriver"/>
<property name="validationQuery" value="select 1" />
</bean>
<bean id="dbEmailDataSource" parent="mssqlDataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close" lazy-init="true">
<property name="url" value="" />
<property name="username" value="" />
<property name="password" value="" />
</bean>
测试应用程序代码:
public static void main(String[] args) {
try {
Bootstrap.init();
for(String urlName : Bootstrap.getClasspathUrlNames()) {
if(StringUtils.containsIgnoreCase(urlName,"aopalliance")) {
System.out.println(urlName);
}
}
ConfigurableApplicationContext ctx = new BootstrappedApplicationContext("DbEmailContext.xml");
ctx.close();
}catch(Throwable t) {
t.printstacktrace();
}
try {
Class clazz = Bootstrap.getClassLoader().loadClass("org.aopalliance.intercept.MethodInterceptor");
System.out.println("manually loaded: "+clazz.getName());
}catch(Throwable t) {
t.printstacktrace();
}
}
BootstrappedApplicationContext(类似于ClasspathXmlApplicationContext):
public class BootstrappedApplicationContext extends AbstractXmlApplicationContext {
private urlclassloader classloader;
private Resource[] configResources;
public BootstrappedApplicationContext() {
super();
this.classloader = Bootstrap.getClassLoader();
super.setClassLoader(this.classloader);
}
public BootstrappedApplicationContext(ApplicationContext parent) {
this();
setParent(parent);
}
public BootstrappedApplicationContext(String configLocation)
throws BeansException {
this(new String[] {configLocation},true,null);
}
public BootstrappedApplicationContext(String... configLocations)
throws BeansException {
this(configLocations,null);
}
public BootstrappedApplicationContext(String[] configLocations,ApplicationContext parent)
throws BeansException {
this(configLocations,parent);
}
public BootstrappedApplicationContext(String[] configLocations,boolean refresh)
throws BeansException {
this(configLocations,refresh,boolean refresh,ApplicationContext parent)
throws BeansException {
this(parent);
setConfigLocations(configLocations);
if(refresh) {
refresh();
}
}
public BootstrappedApplicationContext(String path,Class<?>clazz)
throws BeansException {
this(new String[] {path},clazz);
}
public BootstrappedApplicationContext(String[] paths,Class<?> clazz) throws BeansException {
this(paths,clazz,null);
}
public BootstrappedApplicationContext(String[] paths,Class<?> clazz,ApplicationContext parent)
throws BeansException {
this(parent);
Assert.notNull(paths,"Path array must not be null");
Assert.notNull(clazz,"Class argument must not be null");
this.configResources = new Resource[paths.length];
for (int i = 0; i < paths.length; i++) {
this.configResources[i] = new ClassPathResource(paths[i],clazz);
}
refresh();
}
@Override
public ClassLoader getClassLoader() {
if(classloader == null) {
classloader = Bootstrap.getClassLoader();
}
super.setClassLoader(classloader);
return classloader;
}
public void setClassLoader(urlclassloader classloader) {
this.classloader = classloader;
super.setClassLoader(classloader);
}
@Override
protected Resource[] getConfigResources() {
return this.configResources;
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)