`
jiagou
  • 浏览: 2532785 次
文章分类
社区版块
存档分类
最新评论

在Spring环境中建立JPA

 
阅读更多

在Spring环境中建立JPA

12.6.1.在Spring环境中建立JPA

SpringJPA提供了三种方法创建JPAEntityManagerFactory:

12.6.1.1.LocalEntityManagerFactoryBean

LocalEntityManagerFactoryBean负责创建一个适合于仅使用JPA进行数据访问的环境的EntityManager。Factorybean将使用JPAPersistenceProvider类的自动检测机制(根据JPA的JavaSE启动),而在绝大多数情况下,只需要指定persistenceunit名称:

<beans>

<beanid="entityManagerFactory"class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<propertyname="persistenceUnitName"value="myPersistenceUnit"/>
</bean>

</beans>

这种JPA部署方式最为简单,但却最受限制。例如,不能连接到现有的JDBCDataSource,并且不支持全局事务。甚至,持久化类的织入(字节码转换)也是特定于提供者的,经常需要在启动时指定一个特定的JVM代理。总之,这种方法实际上只适用于独立的应用程序和测试环境(这正是JPA规范设计它的原因)。

仅在简单部署环境中只使用这种方式,比如独立的应用程序和集成测试。

12.6.1.2.从JNDI中获取EntityManagerFactory

从JNDI获取EntityManagerFactory(例如在JavaEE5环境中),仅通过修改XML配置即可实现:

<beans>

<jee:jndi-lookupid="entityManagerFactory"jndi-name="persistence/myPersistenceUnit"/>

</beans>

在标准的JavaEE5启动过程中,JavaEE服务器自动检测持久化单元(例如应用程序文件包中的META-INF/persistence.xml),以及JavaEE部署描述符中定义给那些持久化单元命名上下文位置的环境的persistence-unit-ref项(例如web.xml)。

在这种情况下,整个持久化单元部署,包括持久化类的织入(字码码转换)都取决于JavaEE服务器。JDBCDataSource通过在META-INF/persistence.xml文件中的JNDI位置进行定义;EntityManager事务与服务器的JTA子系统整合。Spring仅仅用获得的EntityManagerFactory,通过依赖注入将它传递给应用程序对象,并为它管理事务(一般通过JtaTransactionManager)。

注意,如果在同一个应用程序中使用了多个持久化单元,JNDI获取的这种持久化单元的bean名称应该与应用程序用来引用它们的持久化单元名称相符(例如@PersistenceUnit和@PersistenceContext注解)。

在部署到JavaEE5服务器时使用该方法。关于如何将自定义JPA提供者部署到服务器,以及允许使用服务器提供的缺省提供者之外的JPA提供者,请查看服务器文档的相关说明。

12.6.1.3.LocalContainerEntityManagerFactoryBean

LocalContainerEntityManagerFactoryBean提供了对JPAEntityManagerFactory的全面控制,非常适合那种需要细粒度定制的环境。LocalContainerEntityManagerFactoryBean将基于persistence.xml文件创建PersistenceUnitInfo类,并提供dataSourceLookup策略和loadTimeWeaver。因此它可以在JNDI之外的用户定义的数据源之上工作,并控制织入流程。

<beans>

<beanid="entityManagerFactory"class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<propertyname="dataSource"ref="someDataSource"/>
<propertyname="loadTimeWeaver">
<beanclass="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
</property>
</bean>

</beans>

这是最为强大的JPA配置方式,允许在应用程序中灵活进行本地配置。它支持连接现有JDBCDataSource,支持本地事务和全局事务等等。然而,它也将需求强加到了运行时环境中,例如,如果持久化提供者需要字节码转换,则必须有织入ClassLoader的能力。

注意,这个选项可能与JavaEE5服务器内建的JPA功能相冲突。因此,当运行在完全JavaEE5环境中时,要考虑从JNDI获取EntityManagerFactory。另一种可以替代的方法是,在LocalContainerEntityManagerFactoryBean定义中通过“persistenceXmlLocation”指定相关位置,例如“META-INF/my-persistence.xml”,并且只将包含该名称的描述符放在应用程序包文件中。因为JavaEE5服务器将只查找默认的META-INF/persistence.xml文件,它会忽略这种定制的持久化单元,因而避免与前面Spring驱动的JPA配置冲突。(例如,适用于Rdsin3.1)。

在基于Spring的应用程序环境中使用该方式可获得全部JPA功能。这包括web容器,如Tomcat,以及独立的应用程序和包含复杂持久化需求的集成测试。

何时需要加载时织入?

并非所有的JPA提供者都需要JVM代理(Hibernate就是一个例子)。如果你的提供者不需要代理(agent)或者你有其他选择(例如通过自定义编译器或者ant任务在构建时进行增强),那么就不应该使用加载时织入。

LoadTimeWeaver接口由Spring提供,允许JPAClassTransformer实例能够根据环境(web容器/应用服务器)以特定的方式插入。通过Java5代理挂钩ClassTransformers经常是无效的——代理通常在整个虚拟机环境下工作,并且监控每一个被加载的类——这在生产环境下一般是不提倡的。

Spring提供了大量用于不同环境的LoadTimeWeaver实现类,允许ClassTransformer实例能够仅用于每个classloader,而不是每个虚拟机。

接下来的一节将讨论在Tomcat以及使用Spring的VM代理情况下的典型JPA织入配置。关于设置常用加载时织入的详细内容,请参见AOP一章中的第6.8.4.5节“Spring配置”一节,它涵盖了Tomcat、VM代理以及WebLogic、OC4J、GlassFish和Resin。

12.6.1.3.1.Tomcat(5.0以上)加载时的织入配置

ApacheTomcat缺省的ClassLoader(类装载器)并不支持类的切换,但是它允许使用用户自定义的类装载器。Spring提供了TomcatInstrumentableClassLoader类(在org.springframework.instrument.classloading.tomcat包中),这个类继承自Tomcat的类装载器(WebappClassLoader)并且允许JPAClassTransformer的实例来“增强”所有由它加载的类。简单说,JPA转化器(JPAtransformer)仅仅在(使用TomcatInstrumentableClassLoader的)特定web应用程序中才能被使用。

为使用用户自定义的类装载器:

将spring-tomcat-weaver.jar复制到$CATALINA_HOME/server/lib下(其中$CATALINA_HOME表示Tomcat的安装路径)。

通过修改webapplicationcontext使Tomcat使用用户自定义的类装载器(而不是默认的类装载器):

<Contextpath="/myWebApp"docBase="/my/webApp/location">
<LoaderloaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"/>
</Context>

Tomcat5.0.x和5.5.x系列支持多个上下文路径(contextlocations):服务器配置文件($CATALINA_HOME/conf/server.xml),默认的上下文配置($CATALINA_HOME/conf/context.xml)会影响所有被部署的web应用程序、单独部署在Server端的web应用程序的配置($CATALINA_HOME/conf/[enginename]/[hostname]/my-webapp-context.xml)或者与web应用程序一起(your-webapp.war/META-INF/context.xml)。从效率的角度说,我们推荐在web-app的内部配置的方式,因为仅仅使用JPA的应用程序会使用用户自定义的类装载器。更多具体有关可用的上下文路径的内容请参见Tomcat5.x的文档

注意,5.5.20之前的版本有一个XML配置解析的bug,造成server.xml中无法使用Loader标签,无论是否指定了classloader,也不管这个classloader是官方的还是自定义的。

如果你正在使用的是Tomcat5.5.20以上的版本,就可以将useSystemClassLoaderAsParent设置成        false来解决这个问题:

<Contextpath="/myWebApp"docBase="/my/webApp/location">
<LoaderloaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"
useSystemClassLoaderAsParent="false"/>
</Context>

将spring-tomcat-weaver.jar复制到$CATALINA_HOME/lib(where$CATALINA_HOME表示Tomcat安装根目录的位置)。

通过编辑web应用程序上下文文件,使Tomcat使用自定义的ClassLoader(而不是默认的ClassLoader):

<Contextpath="/myWebApp"docBase="/my/webApp/location">
<LoaderloaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"/>
</Context>

Tomcat6.0.x(类似于5.0.x/5.5.x)系列支持几种上下文路径:(contextlocations):服务器配置文件($CATALINA_HOME/conf/server.xml),默认的上下文配置($CATALINA_HOME/conf/context.xml)会影响所有被部署的web应用程序、单独部署在Server端的web应用程序的配置($CATALINA_HOME/conf/[enginename]/[hostname]/my-webapp-context.xml)或者与web应用程序一起(your-webapp.war/META-INF/context.xml)。从效率的角度说,我们推荐在web-app的内部配置的方式,因为仅仅使用JPA的应用程序会使用用户自定义的类装载器。更多具体有关可用的上下文路径的内容请参见Tomcat5.xdocumentation

Tomcat5.0.x/5.5.x

Tomcat6.0.x

所有Tomcat版本所需的最后一步,是在配置LocalContainerEntityManagerFactoryBean的时,使用相应的LoadTimeWeaver:

<beanid="emf"class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<propertyname="loadTimeWeaver">
<beanclass="org.springframework.instrument.classloading.ReflectiveLoadTimeWeaver"/>
</property>
</bean>

利用这种方法,依赖工具的JPA应用程序无需代理就可以在Tomcat上运行。这在宿主应用程序依赖不同的JPA实现时尤为重要,因为JPA转化器只适用于ClassLoader级别,它们之间是彼此隔离的。

注意

如果Tomcat使用TopLink作为JPA提供者,请将核心的toplinkjar包放在$CATALINA_HOME/shared/lib文件夹中,而不再放到war中。

12.6.1.3.2.使用VM代理的全局加载时织入

对于需要类工具,同时现有的LoadTimeWeaver实现不提供这种支持的环境,JDK代理是唯一的解决方案。对于这种情况,Spring提供了需要特定于Spring(但非常常用)的VM代理(spring-agent.jar)的InstrumentationLoadTimeWeaver:

<beanid="emf"class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<propertyname="loadTimeWeaver">
<beanclass="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
</property>
</bean>

请注意在启动虚拟机时,同时启动Spring代理,方法是提供下列JVM选项:

-javaagent:/path/to/spring-agent.jar
12.6.1.3.3.上下文范围内的加载时织入配置

自Spring2.5,可以使用context:load-time-weaver元素来配置上下文范围的LoadTimeWeaver了。这种“全局”织入器由所有JPALocalContainerEntityManagerFactoryBeans自动拣选。

这是配置加载时织入器的推荐方法,提供平台(ebLogic,OC4J,GlassFish,Tomcat,Resin,VMagent)的自动检测,以及织入器到所有织入器知道的bean的自动传播。

<context:load-time-weaver/>

<beanid="emf"class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
...
</bean>

关于如何建立常用加载时织入的详细内容,请参见第6.8.4.5节“Spring配置”一节,它涵盖了Tomcat、VM代理,以及WebLogic,OC4J,GlassFish和Resin。

12.6.1.4.处理多持久化单元

对于那些依靠多个持久化单元位置(例如存放在classpath中的多个jar中)的应用程序,Spring提供了作为中央仓库的PersistenceUnitManager,避免了持久化单元查找过程(的潜在开销)。缺省实现允许指定多个位置(默认情况下classpath会搜索META-INF/persistence.xml文件),它们会被解析然后通过持久化单元名称被获取:

<beanid="pum"class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
<propertyname="persistenceXmlLocation">
<list>
<value>org/springframework/orm/jpa/domain/persistence-multi.xml</value>
<value>classpath:/my/package/**/custom-persistence.xml</value>
<value>classpath*:META-INF/persistence.xml</value>
</list>
</property>
<propertyname="dataSources">
<map>
<entrykey="localDataSource"value-ref="local-db"/>
<entrykey="remoteDataSource"value-ref="remote-db"/>
</map>
</property>
<!--ifnodatasourceisspecified,usethisone-->
<propertyname="defaultDataSource"ref="remoteDataSource"/>
</bean>

<beanid="emf"class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<propertyname="persistenceUnitManager"ref="pum"/>
</bean>

要注意的是,缺省实现允许在将持久化单元信息传入JPAprovider之前用PersistenceUnitPostProcessor(它允许选择持久化单元)修改它们,传入的过程可以是通过属性声明式地传入(影响其中所有的单元)或编程式地传入。如果没有指定persistenceUnitManager,LocalContainerEntityManagerFactoryBean会创建一个并在内部使用它。



文章转自:http://hi.baidu.com/zuodonglibra/blog/item/5fa947c1d53bcd58b319a8df.html
分享到:
评论

相关推荐

    Spring-Reference_zh_CN(Spring中文参考手册)

    12.6.1. 在Spring环境中建立JPA 12.6.1.1. LocalEntityManagerFactoryBean 12.6.1.2. LocalContainerEntityManagerFactoryBean 12.6.1.3. 处理多个持久化单元 12.6.2. JpaTemplate 和 JpaDaoSupport 12.6.3. 基于...

    Spring中文帮助文档

    12.6.1. 在Spring环境中建立JPA 12.6.2. JpaTemplate 和 JpaDaoSupport 12.6.3. 基于原生的JPA实现DAO 12.6.4. 异常转化 12.7. 事务管理 12.8. JpaDialect III. The Web 13. Web MVC framework Web框架 13.1...

    Spring 2.0 开发参考手册

    12.6.1. 在Spring环境中建立JPA 12.6.2. JpaTemplate 和 JpaDaoSupport 12.6.3. 基于原生的JPA实现DAO 12.6.4. 异常转化 12.6.5. 事务管理 12.6.6. JpaDialect III. Web 13. Web框架 13.1. 介绍 13.1.1. 与...

    spring chm文档

    12.6.1. 在Spring环境中建立JPA 12.6.2. JpaTemplate 和 JpaDaoSupport 12.6.3. 基于原生的JPA实现DAO 12.6.4. 异常转化 12.6.5. 事务管理 12.6.6. JpaDialect III. Web 13. Web框架 13.1. 介绍 13.1.1. 与...

    Spring API

    12.6.1. 在Spring环境中建立JPA 12.6.2. JpaTemplate 和 JpaDaoSupport 12.6.3. 基于原生的JPA实现DAO 12.6.4. 异常转化 12.7. 事务管理 12.8. JpaDialect III. The Web 13. Web MVC framework Web框架 13.1...

    JSF+Spring+JPA(Hibernate实现)的环境搭建

    JSF+Spring+JPA以我个人看来,应该说是Struts2+Spring+Hibernate的替代解决方案。 引入JPA去取代或者说包装或者说是升级Hibernate是为了符合JAVA EE的规范,达到ORM统一的结果。下次项目用EJB也好、用TOPLINK也好、...

    Spring攻略(第二版 中文高清版).part1

    6.2 在你的Servlet和过滤器中使用Spring 214 6.2.1 问题 214 6.2.2 解决方案 215 6.2.3 工作原理 215 6.3 将Spring与Struts 1.x集成 220 6.3.1 问题 220 6.3.2 解决方案 220 6.3.3 工作原理 220 6.4...

    Spring攻略(第二版 中文高清版).part2

    6.2 在你的Servlet和过滤器中使用Spring 214 6.2.1 问题 214 6.2.2 解决方案 215 6.2.3 工作原理 215 6.3 将Spring与Struts 1.x集成 220 6.3.1 问题 220 6.3.2 解决方案 220 6.3.3 工作原理 220 6.4...

    Spring in Action(第二版 中文高清版).part2

    第9章 在Spring中建立契约优先Web服务 9.1 介绍Spring-WS 9.2 定义契约(首先!) 9.3 使用服务端点处理消息 9.3.1 建立基于JDOM消息的端点 9.3.2 序列化消息载荷 9.4 合并在一起 9.4.1 Spring-WS:全景视图 ...

    Spring in Action(第二版 中文高清版).part1

    第9章 在Spring中建立契约优先Web服务 9.1 介绍Spring-WS 9.2 定义契约(首先!) 9.3 使用服务端点处理消息 9.3.1 建立基于JDOM消息的端点 9.3.2 序列化消息载荷 9.4 合并在一起 9.4.1 Spring-WS:全景视图 ...

    Spring in Action(第2版)中文版

    第9章在spring中建立契约优先web服务 9.1介绍spring-ws 9.2定义契约(首先!) 9.3使用服务端点处理消息 9.3.1建立基于jdom消息的端点 9.3.2序列化消息载荷 9.4合并在一起 9.4.1spring-ws:全景视图 9.4.2将...

    经典JAVA.EE企业应用实战.基于WEBLOGIC_JBOSS的JSF_EJB3_JPA整合开发.pdf

    10.2.2 在Java SE环境下使用 Hibernate JPA实现 370 10.2.3 在Java SE环境下使用 TopLink JPA实现 374 10.2.4 在Java SE环境下使用 EntityManager 377 10.2.5 使用orm.xml管理O/R映射 379 10.3 理解实体 382 10.3.1 ...

    BOS 技术整理

    在applicationContext添加一条 用来整合 Spring Data jpa &lt;jpa:repositories base-package="cn.itcast.bao.dao" /&gt; 注意: 这里的扫描包,必须指定到类的上级包 比如 一个类 com.itStone.bao.dao.test.java 那么它...

    Spring面试题

    Spring 框架的功能可以用在任何 J2EE 服务器中,大多数功能也适用于不受管理的环境。Spring 的核心要点是:支持不绑定到特定 J2EE 服务的可重用业务和数据访问对象。毫无疑问,这样的对象可以在不同 J2EE 环境 (Web...

    图文并茂详解Springboot快速入门篇.docx

    1.1 Springboot简介 SpringBoot是由Pivotal团队研发的,SpringBoot并不是一门新技术,只是将之前常用的Spring,SpringMVC,data- jpa等常用的...后期要学习的微服务框架SpringCloud需要建立在SpringBoot的基础上。

    基于Java springboot+Vue的图书管理系统(前端+后端+视频).zip

    前端使用Vue Elementui建立用户视图,使用Springboot springData Jpa mysql 提供接口。 前端通过使用axios调用接口获取数据,从而渲染页面。 ## 概述 1.前端可以将vue打包部署到nginx服务器 ,复制dist下面的文件...

    基于SpringBoot校园二手交易网站.zip

    信誉评价系统:用户可对交易进行评价,建立可靠的交易环境。 项目目标: 本项目的目标是创建一个高效、安全、用户友好的校园二手交易平台,促进校园内的资源共享和环保意识,同时为学生提供实践Spring Boot开发技能...

    Rays-Rentals

    生成的项目特征用于Servlet 3.0环境的No-xml Spring MVC 4 Web应用程序胸腺,引导JPA 2.0(Hibernate / HSQLDB / Spring Data JPA) MongoDB(Spring Data Mongo) JUnit的/ Mockito的Spring安全3.2安装要将原型安装...

Global site tag (gtag.js) - Google Analytics