`
wansong
  • 浏览: 20656 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

主题:在Spring环境中建立JPA

阅读更多
Spring JPA 提供了三种方法创建JPA EntityManagerFactory:

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

<beans>

   <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
      <property name="persistenceUnitName" value="myPersistenceUnit"/>
   </bean>

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

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

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

<beans>

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

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

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

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

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

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

<beans>
       
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="someDataSource"/>
<property name="loadTimeWeaver">
    <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
</property>
</bean>

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

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

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

何时需要加载时织入?

并非所有的JPA提供者都需要JVM代理(Hibernate就是一个例子)。 如果你的提供者不需要代理(agent)或者你有其他选择(例如通过自定义编译器或者ant任务在构建时进行增强),那么就不应该使用加载时织入。
LoadTimeWeaver 接口由Spring提供,允许JPA ClassTransformer 实例 能够根据环境(web容器/应用服务器)以特定的方式插入。 通过Java 5 代理挂钩 ClassTransformers经常是无效的 —— 代理通常在 整个虚拟机 环境下工作,并且监控 每一个 被加载的类 —— 这在生产环境下一般是不提倡的。

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

接下来将讨论在Tomcat以及使用Spring的VM代理情况下的典型JPA织入配置。

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

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

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

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

<Context path="/myWebApp" docBase="/my/webApp/location">
    <Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"/>
</Context>
Tomcat 5.0.x 和 5.5.x 系列支持多个上下文路径(context locations): 服务器配置文件($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的应用程序会使用用户自定义的类装载器。 更多具体有关可用的上下文路径的内容请参见Tomcat 5.x的文档。

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

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

<Context path="/myWebApp" docBase="/my/webApp/location">
    <Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"
            useSystemClassLoaderAsParent="false"/>
</Context>
将spring-tomcat-weaver.jar复制到$CATALINA_HOME/lib (where $CATALINA_HOME表示Tomcat安装根目录的位置)。

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

<Context path="/myWebApp" docBase="/my/webApp/location">
    <Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"/>
</Context>
Tomcat 6.0.x (类似于5.0.x/5.5.x)系列支持几种上下文路径:(context locations): 服务器配置文件($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的应用程序会使用用户自定义的类装载器。 更多具体有关可用的上下文路径的内容请参见Tomcat 5.x documentation。

Tomcat 5.0.x/5.5.x

Tomcat 6.0.x

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

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="loadTimeWeaver">
    <bean class="org.springframework.instrument.classloading.ReflectiveLoadTimeWeaver"/>
</property>
</bean>
利用这种方法,依赖工具的JPA应用程序无需代理就可以在Tomcat上运行。这在宿主应用程序依赖不同的JPA实现时尤为重要, 因为JPA转化器只适用于ClassLoader级别,它们之间是彼此隔离的。

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

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

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="loadTimeWeaver">
    <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
</property>
</bean>
请注意在启动虚拟机时,同时启动Spring代理,方法是提供下列JVM选项:

-javaagent:/path/to/spring-agent.jar

上下文范围内的加载时织入配置
自Spring 2.5,可以使用context:load-time-weaver元素来配置 上下文范围的LoadTimeWeaver了。这种“全局”织入器由所有JPA LocalContainerEntityManagerFactoryBeans自动拣选。

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

<context:load-time-weaver/>

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

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

<bean id="pum" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
<property name="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>
<property name="dataSources">
   <map>
    <entry key="localDataSource" value-ref="local-db"/>
    <entry key="remoteDataSource" value-ref="remote-db"/>
   </map>
</property>
<!-- if no datasource is specified, use this one -->
<property name="defaultDataSource" ref="remoteDataSource"/>
</bean>

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitManager" ref="pum"/>
</bean>
要注意的是,缺省实现允许在将持久化单元信息传入JPA provider之前用 PersistenceUnitPostProcessor(它允许选择持久化单元)修改它们, 传入的过程可以是通过属性声明式地传入(影响其中所有的单元)或编程式地传入。 如果没有指定persistenceUnitManager,LocalContainerEntityManagerFactoryBean 会创建一个并在内部使用它。
分享到:
评论

相关推荐

    xfire spring jpa搭建环境

    "xfire spring jpa搭建环境"这个主题聚焦于如何利用XFire、Spring和JPA这三个关键组件来建立一个高效的开发环境。下面将详细介绍这三个技术以及如何将它们整合在一起。 首先,让我们理解每个组件的核心功能: 1. *...

    springboot2-jpa-demo-ccccc

    在这个简单的示例中,项目能够正常运行,展示如何在Spring Boot环境中配置和使用JPA来操作MySQL数据库。 描述中提到,这个项目与网络上其他类似的教程基本相同,包含两个类,分别映射到数据库中的两张独立的表,这...

    Pro Spring 3(带目录版)

    第10章:讲解了如何在Spring中使用Java持久化API(JPA),并且演示了在Spring中配置和使用JPA来简化实体管理。 第11章:介绍了如何在Spring中整合MyBatis持久层框架,以及如何配置和使用MyBatis的映射文件。 第12...

    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. 基于...

    入门eclipse+springboot+Mysql+jpa操作CRUD实例

    在本文中,我们将深入探讨如何使用Eclipse IDE、Spring Boot、MySQL数据库以及Java Persistence API (JPA) 来实现一个完整的CRUD(创建、读取、更新和删除)操作实例。这对于初学者来说是一个很好的起点,它将帮助你...

    Spring Boot入门培训(带完整源码)

    在入门培训中,可能会涵盖以下主题: 1. **环境准备**:讲解如何安装JDK、设置环境变量、以及选择合适的集成开发环境(IDE),如IntelliJ IDEA或Eclipse。 2. **创建第一个Spring Boot应用**:演示如何使用Spring ...

    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...

    spring-boot-playground:Java环境和SpringBoot环境

    总之,"spring-boot-playground:Java环境和SpringBoot环境"涵盖了Java开发环境的建立和Spring Boot应用的创建、运行和调试。通过学习和实践,你可以熟练掌握Spring Boot,提高开发效率,实现快速开发高质量的Java...

    struts2-spring-hibernate正和所需要的包

    这个压缩包"struts2-spring-hibernate正和所需要的包"包含了在整合这三个框架时必要的库文件,确保开发者可以快速搭建起一个完整的开发环境。 1. **Struts2**: Struts2是一个基于MVC设计模式的Web应用框架,它提供...

    b2b-manage.zip

    在当前的互联网开发环境中,Spring Boot 和 LayUI 是两个非常受欢迎的技术框架,它们各自在不同的领域发挥着重要作用。Spring Boot 作为一款基于 Spring Framework 的简化启动器,极大地简化了Java Web 应用的开发...

    java与不同数据库的连接

    5. JDBC-ODBC Bridge:在没有对应数据库驱动的情况下,可以使用JDBC-ODBC Bridge,但这种方式性能较差,不推荐在生产环境中使用。 了解以上知识点,你就能更好地理解和实践Java与不同数据库的连接,无论是简单的...

    Eclipse.Web.Tools.Platform.Developing.Java.Web.Applications examples

    《Eclipse.Web.Tools.Platform.Developing.Java.Web.Applications》这本书提供了丰富的示例,旨在帮助开发者在Eclipse环境中高效地开发Java Web应用程序。书中的每个章节都对应着一系列的实例,涵盖了从基础到高级的...

    NetBeans可视化Web开发之数据库应用开发

    在IT行业中,Web开发是一项核心技能,而使用像NetBeans这样的集成开发环境(IDE)能够极大地提高开发效率。本文将深入探讨"NetBeans可视化Web开发之数据库应用开发"这一主题,帮助开发者理解如何利用NetBeans进行高效...

    基于Java的附加数据库.zip

    本压缩包“基于Java的附加数据库.zip”很可能包含了一些关于如何在Java环境中连接、操作和管理数据库的资源。下面将详细介绍Java与数据库交互的相关知识点。 1. JDBC(Java Database Connectivity):JDBC是Java...

    JavaDatabaseProgrammingBible

    学习如何在Java EE环境中配置和使用JPA,以及如何与EJB和Spring框架集成,将大大提升大型企业级应用的开发效率。 6. **数据源与连接池**:在大型系统中,有效管理数据库连接至关重要。书中可能会介绍如何配置和使用...

    java数据库系统开发实例导航源码

    在Java编程语言中,数据库系统开发是至关重要的领域,它涉及到如何使用Java与各种数据库进行交互,例如MySQL、Oracle、PostgreSQL等。本实例导航源码可能是为了帮助开发者理解如何在实际项目中应用Java数据库连接...

    news_SQL.rar_news_SQL

    标题中的"news_SQL.rar_news_SQL"暗示了这是一个与SQL相关的新闻或教程集合,可能是关于如何在Java环境中连接MySQL数据库的资料。描述中的“java连接mysql数据库”进一步确认了这一点,表明我们将探讨的话题是使用...

Global site tag (gtag.js) - Google Analytics