classloader读取配置文件_自定义ClassLoader,让spring加载外部的配置文件和类

e45dd7d7f2d3fd076fa1d4f445a1675c.png

其中net文件夹下面,放了要从外部加载的目标类

package net.kyfxbl.test;

public class User {

private String name;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public void sayName() {

System.out.println(getName());

}

}

配置文件spring-plugin.xml内容是:

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

现在目标,就是读取hehe.jar中的spring-plugin.xml文件,然后实例化一个User对象

示例代码如下,要说明的是,代码很简陋,仅供参考。主要是由于本人spring学艺不精,所以API调用那块,肯定不是最佳实践,绝对是可以优化的:

public class Main {

public static void main(String[] args) {

try {

ApplicationContext applicationContext = new ClassPathXmlApplicationContext(

"spring-config.xml");

DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext

.getAutowireCapableBeanFactory();

String configurationFilePath = "jar:file:/C:/hehe.jar!/spring-plugin.xml";

URL url = new URL(configurationFilePath);

UrlResource urlResource = new UrlResource(url);

XmlBeanFactory xbf = new XmlBeanFactory(urlResource);

String[] beanIds = xbf.getBeanDefinitionNames();

for (String beanId : beanIds) {

BeanDefinition bd = xbf.getMergedBeanDefinition(beanId);

beanFactory.registerBeanDefinition(beanId, bd);

}

// 以下这行设置BeanFactory的ClassLoader,以加载外部类

setBeanClassLoader(beanFactory);

Object pluginBean = applicationContext.getBean("myUser");

tryInvoke(pluginBean);

} catch (Exception exc) {

exc.printStackTrace();

}

}

private static void setBeanClassLoader(

DefaultListableBeanFactory beanFactory)

throws MalformedURLException {

String jarFilePath = "c://hehe.jar";

URL jarUrl = new File(jarFilePath).toURI().toURL();

URL[] urls = new URL[] { jarUrl };

URLClassLoader cl = new URLClassLoader(urls);

beanFactory.setBeanClassLoader(cl);

}

private static void tryInvoke(Object bean) throws SecurityException,

NoSuchMethodException, IllegalArgumentException,

IllegalAccessException, InvocationTargetException {

Class> paramTypes[] = new Class[0];

Method method = bean.getClass()

.getDeclaredMethod("sayName", paramTypes);

Object paramValues[] = new Object[0];

method.invoke(bean, paramValues);

}

}

如果注释掉

setBeanClassLoader(beanFactory);

则报异常:

Caused by: java.lang.ClassNotFoundException: net.kyfxbl.test.User

所以关键就是通过setBeanClassLoader()方法,修改beanFactory默认的ClassLoader

原理比较简单:如果不做特殊配置的话,spring将使用默认的ClassLoader(也就是App ClassLoader),那么就不会加载hehe.jar中的类。所以通过自定义URLClassLoader,并将其设置为BeanFactory的BeanClassLoader,就可以将hehe.jar加载进来了。有兴趣的朋友可以自行阅读源码,获得更多细节

附带的,为了证明spring默认的ClassLoader就是App ClassLoader,补充了几行测试代码

// 打印ClassLoader看看

printClassLoader(beanFactory);

// 以下这行设置BeanFactory的ClassLoader,以加载外部类

setBeanClassLoader(beanFactory);

private static void printClassLoader(DefaultListableBeanFactory beanFactory) {

ClassLoader defaultBeanClassLoader = beanFactory.getBeanClassLoader();

System.out.println(defaultBeanClassLoader);

ClassLoader currentClassLoader = Main.class.getClassLoader();

System.out.println(currentClassLoader);

}

运行结果:

sun.misc.Launcher$AppClassLoader@addbf1

sun.misc.Launcher$AppClassLoader@addbf1

72ba0ed15fd528ebc5bd009b28e89eb8.png

大小: 63.7 KB

hehe.jar (1.6 KB)

下载次数: 303

分享到:

18e900b8666ce6f233d25ec02f95ee59.png

72dd548719f0ace4d5f9bca64e1d7715.png

2012-11-20 20:50

浏览 9119

论坛回复 / 浏览 (7 / 12967)

评论

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值