存档

2012年12月 的存档

在动态加载的JAR中使用Spring

2012年12月28日 没有评论

  目的是在动态加载的JAR中使用Spring的功能,即动态把JAR中的Class加载到Spring中管理,目前设计为使用Annation来管理配置Spring,动态加入的代码如下:

//加载jar
JARClassLoader loader = new JARClassLoader();
loader.loadJar("c:/x3.jar");
 
//设置当前线程的classLoader
Thread.currentThread().setContextClassLoader(loader);
 
//注册bean
ApplicationContext context = SystemCore.getApplicationContext();
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner((DefaultListableBeanFactory)
context.getAutowireCapableBeanFactory());//使用Spring的注解自动扫描
//扫描jar中的包路径,使用通配符,另外在导出jar时必须选择add directory entries(即把目录也加入到jar中)
//否则spring扫描时将无法找到class
scanner.scan("com.test.moduleA.*");
 
//手动拿jar包里的bean的实例时因为存在ClassLoader的隔离虽然在开始设置了ContextClassLoader
//但是Spring默认getBean的时候并没有每次都去拿最新的ContextClassLoader使用,所以需要手动设置Bean的ClassLoader
//因为是手动设置的这里存在线程安全的问题...不知道有没有其他方法.
DefaultListableBeanFactory factory = (DefaultListableBeanFactory)context.getAutowireCapableBeanFactory();
		factory.setBeanClassLoader(loader);
 
System.out.println(context.getBean("questionDaoImpl"));
分类: 高级民工 标签: ,

Hibernate动态加载时class的加入

2012年12月27日 没有评论

  最近在搞一个模块化的功能,自己写着玩的,最终目的是整合osgi,Hibernate,Spring,Struts等常用框架,并能在模块中动态加入到这些框架中。今天遇到一个Hibernate动态加入时找不到实体类的问题,翻看源码在ReflectHelper中找到答案:

	public static Class classForName(String name) throws ClassNotFoundException {
		try {
			ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
			if ( contextClassLoader != null ) {
				return contextClassLoader.loadClass(name);
			}
		}
		catch ( Throwable t ) {
		}
		return Class.forName( name );
	}

在加载类时是通过在当前线程的classLoader中查找类(ClassLoader有隔离机制),所以在动态加载ClassLoader之前需要把当前线程的contextClassLoader设置为我们自己定义的ClassLoader.代码如下:

	Thread.currentThread().setContextClassLoader(loader);//设置当前线程的ContextClassLoader
	ModuleSupporter.hibernateMapping(new File("c:/x3.jar"));

后记:
由于Hibernate本身用了大量反射并且对多个ClassLoade的情况考虑不是很充分,另外动态加入只是加入到Configuration所以需要要单独创建SessionFactory,感觉会浪费资源还有就是多个模块的时候SessionFactory的不同必然会有事务不好控制的问题。

分类: 高级民工 标签: ,