论坛首页 Java企业应用论坛

一劳永逸——让Spring自动加载Hibernate Annotated Classes

浏览 19980 次
精华帖 (5) :: 良好帖 (15) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2008-10-13  
import java.io.IOException;
import java.util.Iterator;

import org.hibernate.HibernateException;
import org.hibernate.cfg.Configuration;
import org.hibernate.mapping.PersistentClass;
import org.lc.bean.CustomClassEditor;
import org.lc.bean.CustomClassEditorManager;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.orm.hibernate3.LocalSessionFactoryBean;

/**
 * 自动寻找所有以.hbm.xml结尾的文件,加入到Hibernate配置中
 * 并为Hibernate中定义的每一个类添加HibernateClassEditor,保证对象保存时可以通过id直接建立对象关联
 */
@SuppressWarnings("unchecked")
public class SessionFactoryBean extends LocalSessionFactoryBean implements BeanFactoryAware,BeanFactoryPostProcessor{
	
	private DefaultListableBeanFactory beanFactory;
		
	/**
	 * Spring会自动进行注入
	 * 记录BeanFactory,以在postProcessConfiguration中自动加入所有的Hibernate映射
	 */
	public void setBeanFactory(BeanFactory beanFactory) throws BeansException{
		this.beanFactory = (DefaultListableBeanFactory) beanFactory;	
	}

	/** 
	 * @see org.springframework.orm.hibernate3.LocalSessionFactoryBean#postProcessConfiguration(org.hibernate.cfg.Configuration)
	 * 
	 * 自动加入类路径中所有匹配的Hibernate映射文件
	 */
	@Override
	protected void postProcessConfiguration(Configuration config) throws HibernateException {
		ResourcePatternResolver rp = new PathMatchingResourcePatternResolver(beanFactory.getBeanClassLoader());
		
		Resource[] resources;
		try {
			resources = rp.getResources("/**/*.hbm.xml");
			for(int i=0;i<resources.length;i++){
				Resource resource = resources[i];
				
				//将找到的配置文件加入
				if(resource.exists())
					config.addInputStream(resource.getInputStream());
				
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		super.postProcessConfiguration(config);		
	}

	
	
	/* 
	 * @see org.springframework.beans.factory.config.BeanFactoryPostProcessor#postProcessBeanFactory(org.springframework.beans.factory.config.ConfigurableListableBeanFactory)
	 * 在CustomClassEditorManager中加入Editor定义 
	 */
	
	
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		Iterator cIter = this.getConfiguration().getClassMappings();
		
		while(cIter.hasNext()){
			PersistentClass pc = (PersistentClass) cIter.next();
			
			String className = pc.getClassName();
			//为Hibernate中定义的每一个类加入自定义的编辑器
			try {				
				CustomClassEditorManager.registerCustomEditor(Class.forName(className), new CustomClassEditor(className));
			} catch (ClassNotFoundException e) {			
				e.printStackTrace();
			}			
		}
	}
}


0 请登录后投票
   发表时间:2008-10-29  
Else 写道
很棒的工作!
如果是原生的hibernate支持就好了,hibernate的配置文件也不用一个个写了

原生的本来就不用一个一个写,用mappingLocations就可以了。
0 请登录后投票
   发表时间:2008-11-05  
最新的spring2.5.6已经实现此功能:



<!-- 自动搜索注入实体Bean -->
<property name="packagesToScan" value="org.eline.entity*.*" />
0 请登录后投票
   发表时间:2008-11-06  
spring2.5.6终于发布,这个可以退役了
0 请登录后投票
   发表时间:2008-12-09   最后修改:2008-12-09
cats_tiger 写道
spring2.5.6终于发布,这个可以退役了

楼上不知道测试否?
我测试了一下,还是有BUG。
如果只是写JAVA文件单独测试,那么可以使用,如果放在server端启动,启动就会出错。我的配置如下:
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
		<property name="dataSource" ref="dataSource"/>
		<property name="hibernateProperties">
			<props>
				<!-- 省略 -->
			</props>
		</property>
		<property name="packagesToScan">
			<list>
				<value>com.test.*.model</value>
			</list>
		</property>
    </bean>

而网上有人说是少了个“.”号,也就是要写成com.test.*.model.
这种写法也是JAVA单元测试通过server端启动不通过,
如果采用com.test.*.model*.*
连单元测试都没办法通过,不知道是我的配置有问题还是BUG还没有解决!
异常主要是:
引用

Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property 'packagesToScan' of bean class [org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean]: Bean property 'packagesToScan' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
0 请登录后投票
   发表时间:2008-12-09   最后修改:2008-12-09
不要喷我,我记得这个方法以前有人写过的,不知道是不是你,而且代码很类似,在项目中我们也用了,你这个其实还是可以改造,如楼上的com.test.*.model*.*。
spring2.5已经支持正则包扫描了。
0 请登录后投票
   发表时间:2008-12-10  
TO:myyate
你配置成功了么,如果成功能不能把你的配置截图给我看看?
我在spring的官方论坛下也发了个帖子
http://forum.springframework.org/showthread.php?t=64612
按照他们说的加*还有更新包都没有办法解决。
0 请登录后投票
   发表时间:2008-12-12  
孤风浪客 写道
TO:myyate
你配置成功了么,如果成功能不能把你的配置截图给我看看?
我在spring的官方论坛下也发了个帖子
http://forum.springframework.org/showthread.php?t=64612
按照他们说的加*还有更新包都没有办法解决。


习惯不好,还是喜欢用点啊。

为什么不用/呢?

配置成:com/XX/model/不就好了。
0 请登录后投票
   发表时间:2008-12-12  
TO:downpour,谢谢提醒。
现在这个问题已经解决了,和eclipse工程默认的编译文件输入问题有关,默认是:"/build/classes"改为"WebContent/WEB-INF/classes"就可以了。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics