春天忽略了类加载器

问题描述

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 (将#修改为@)