- 浏览: 3434302 次
- 性别:
- 来自: 珠海
文章分类
- 全部博客 (1633)
- Java (250)
- Android&HTML5 (111)
- Struts (10)
- Spring (236)
- Hibernate&MyBatis (115)
- SSH (49)
- jQuery插件收集 (55)
- Javascript (145)
- PHP (77)
- REST&WebService (18)
- BIRT (27)
- .NET (7)
- Database (105)
- 设计模式 (16)
- 自动化和测试 (19)
- Maven&Ant (43)
- 工作流 (36)
- 开源应用 (156)
- 其他 (16)
- 前台&美工 (119)
- 工作积累 (0)
- OS&Docker (83)
- Python&爬虫 (28)
- 工具软件 (157)
- 问题收集 (61)
- OFbiz (6)
- noSQL (12)
最新评论
-
HEZR曾嶸:
你好博主,这个不是很理解,能解释一下嘛//左边+1,上边+1, ...
java 两字符串相似度计算算法 -
天使建站:
写得不错,可以看这里,和这里的这篇文章一起看,有 ...
jquery 遍历对象、数组、集合 -
xue88ming:
很有用,谢谢
@PathVariable映射出现错误: Name for argument type -
jnjeC:
厉害,困扰了我很久
MyBatis排序时使用order by 动态参数时需要注意,用$而不是# -
TopLongMan:
非常好,很实用啊。。
PostgreSQL递归查询实现树状结构查询
http://blog.csdn.net/lucom11/article/details/5805500
本文同时发表在我在google Appengine 上的搭建的博客:http://blogfor11lu.appspot.com/articleaction_view.action?article.id=agtibG9nZm9yMTFsdXIPCxIHQXJ0aWNsZRjBtQMM
之前用JDO 和 Struts2 在google Appengine 上试着写了一个简单的blog程序,但我还是希望使用Spring的依赖注入和事务管理等方面的功能,于是着手搭建环境。
这里,我使用了GAE1.3.5 Spring2.5.6 Struts2.1.8
首先是测试了一下JPA,在Eclipse开发环境下,GAE已经把相应的包都放到了Lib目录下了,只要在src/META-INF下建立persistence.xml文件就可以了,具体内容从GAE文档中复制过来就OK了。写一个简单的的类,测试一下,这个比较简单,GAE文档中都有。很快就成功了。
接下来,我把spring和struts的相关jar包拷到lib目录下,并配置好相关xml,总会出现或这或那的错误,这都是由于jar包不完整或者是jar包之间的版本不配比造成的,还再次出现了上一次集成struts和gae时提示xalan这个jar包没有的错误。后来发现是struts和spring-struts-plugin的版本不一致造成的(这个错误的出现有两种,一个是ongl没处理,一个就是版本不配比)。
经过一大堆错误,最后还是决定一个一个来集成。先集成struts,把前次的jar包拷贝过来,简单做一个action,测试一下,OK。
复制spring的jar包,根据网上的提示,不用all in on的那个,主要是因为GAE在file.io方面不能写文件,使用modules下面的jar包,凭感觉挑了一些,然后,再复制lib目录下需要使用的一些jar包,这个基本参考网上和以前SSH整合时用的jar包。不断测试,根据提示把jar包补齐。一般的,提示没找到指定的类错误,是没有相应jar包,提示没有指定的方法,是jar包的版本不一致。最后要把spring-struts-plugin2.1.8.jar复制到lib目录下。
集成测试了,在集成测试时,测试了@Controller、@Resource、@Transaction等几个注解,首先测的是@Controller,这个测试比较顺利。接着用@Resource 注入一个DAO操作的类。问题出来了:错误信息如下:
Error creating bean with name 'personAction': Injection of resource fields failed; nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'personService' must be of type [com_11lu.GAE.PersonService], but was actually of type [$Proxy17]
最开始,我并没有PersonService,而是直接使用DaoSupport,这是一个抽象类实现Dao接口,DaoSupport是从网上拷来的,当我注意到是抽象类时,把它的abstract去掉,错误依旧,再次,把PersonService继承DaoSupport,还是一样的错误。从这个错误信息我们可以看出,大致的意思的bean的type不对。于是在google上找,说到这个找,关键词很重要,最先是找Injection of resource fields failed这个,没有得到合适的内容。后来找must be of type but was actually of type,在一个外国论坛上看到了答案。问题出在@Transaction注解,在spring的文档中,实际上有说明,对@Transaction的类,要设置proxy-target-class="true" ,否则就不能将这个类注入。也就是会出现上面的信息。具体设置是:<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>。
由于我的英文实在是差,没搞明白proxy-target-class="true"设置在哪,也搞不懂注解方式这个如何设,最终是试着放在这的。我想,如果不是用注解方式,可以放在<bean/>里。
再次运行,提试CGLIB要复制到CLASSPAH下,在spring的Lib目录中找到,复制好就OK了。
下面我把用到的Jar包列出,另外我把我测试用的project也上传到http://download.csdn.net/source/2613955,大家可以下载看看。
我写的记录了我的整个过程,这个过程,我用了好几个晚上的功夫,文字有点哆嗦。
解释一下为什么@Transaction的类,会出现上述错误,在spring中@Transaction是通过AOP实现的,而spring对AOP有两种实现方式,一种是动态代理,它是通过接口方式实现的,要求所代理的类一定是实现了某一个接口,对一般的类就无法代理,spring默认是这种;通过设置proxy-target-class="true",则是使用CGLIB实现AOP,CGLIB直接生成二进制码,使得普通类也可以实现AOP。在没有设置proxy-target-class="true"时,使用动态代理,是一个临时生成的类,如proxy17,它不是@Resource指定的类,因此出现了上述错误。
问题:
1.在一个service连对一个实例两次保存
引起:TransactionOptions.Builder.withXGfound both Element
解决:在persistence.xml增加
antlr-2.7.6.jar
aopalliance.jar
appengine-api-1.0-sdk-1.3.5.jar
appengine-api-labs-1.3.5.jar
appengine-jsr107cache-1.3.5.jar
cglib-nodep-2.1_3.jar
commons-beanutils.jar
commons-collections.jar
commons-fileupload-1.2.1.jar
commons-io-1.3.2.jar
commons-lang.jar
commons-logging-1.0.4.jar
commons-logging.jar
datanucleus-appengine-1.0.7.final.jar
datanucleus-core-1.1.5.jar
datanucleus-jpa-1.1.5.jar
freemarker-2.3.13.jar
geronimo-jpa_3.0_spec-1.1.1.jar
geronimo-jta_1.1_spec-1.1.1.jar
jdo2-api-2.3-eb.jar
jsr107cache-1.1.jar
ognl-2.6.11.jar
slf4j-api-1.5.8.jar
slf4j-simple-1.5.8.jar
spring-aop.jar
spring-beans.jar
spring-context.jar
spring-core.jar
spring-jdbc.jar
spring-orm.jar
spring-tx.jar
spring-web.jar
struts2-core-2.1.8.1.jar
struts2-gae-0.1.jar
struts2-spring-plugin-2.1.8.1.jar
xwork-core-2.1.6.jar
本文同时发表在我在google Appengine 上的搭建的博客:http://blogfor11lu.appspot.com/articleaction_view.action?article.id=agtibG9nZm9yMTFsdXIPCxIHQXJ0aWNsZRjBtQMM
之前用JDO 和 Struts2 在google Appengine 上试着写了一个简单的blog程序,但我还是希望使用Spring的依赖注入和事务管理等方面的功能,于是着手搭建环境。
这里,我使用了GAE1.3.5 Spring2.5.6 Struts2.1.8
首先是测试了一下JPA,在Eclipse开发环境下,GAE已经把相应的包都放到了Lib目录下了,只要在src/META-INF下建立persistence.xml文件就可以了,具体内容从GAE文档中复制过来就OK了。写一个简单的的类,测试一下,这个比较简单,GAE文档中都有。很快就成功了。
接下来,我把spring和struts的相关jar包拷到lib目录下,并配置好相关xml,总会出现或这或那的错误,这都是由于jar包不完整或者是jar包之间的版本不配比造成的,还再次出现了上一次集成struts和gae时提示xalan这个jar包没有的错误。后来发现是struts和spring-struts-plugin的版本不一致造成的(这个错误的出现有两种,一个是ongl没处理,一个就是版本不配比)。
经过一大堆错误,最后还是决定一个一个来集成。先集成struts,把前次的jar包拷贝过来,简单做一个action,测试一下,OK。
复制spring的jar包,根据网上的提示,不用all in on的那个,主要是因为GAE在file.io方面不能写文件,使用modules下面的jar包,凭感觉挑了一些,然后,再复制lib目录下需要使用的一些jar包,这个基本参考网上和以前SSH整合时用的jar包。不断测试,根据提示把jar包补齐。一般的,提示没找到指定的类错误,是没有相应jar包,提示没有指定的方法,是jar包的版本不一致。最后要把spring-struts-plugin2.1.8.jar复制到lib目录下。
集成测试了,在集成测试时,测试了@Controller、@Resource、@Transaction等几个注解,首先测的是@Controller,这个测试比较顺利。接着用@Resource 注入一个DAO操作的类。问题出来了:错误信息如下:
Error creating bean with name 'personAction': Injection of resource fields failed; nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'personService' must be of type [com_11lu.GAE.PersonService], but was actually of type [$Proxy17]
最开始,我并没有PersonService,而是直接使用DaoSupport,这是一个抽象类实现Dao接口,DaoSupport是从网上拷来的,当我注意到是抽象类时,把它的abstract去掉,错误依旧,再次,把PersonService继承DaoSupport,还是一样的错误。从这个错误信息我们可以看出,大致的意思的bean的type不对。于是在google上找,说到这个找,关键词很重要,最先是找Injection of resource fields failed这个,没有得到合适的内容。后来找must be of type but was actually of type,在一个外国论坛上看到了答案。问题出在@Transaction注解,在spring的文档中,实际上有说明,对@Transaction的类,要设置proxy-target-class="true" ,否则就不能将这个类注入。也就是会出现上面的信息。具体设置是:<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>。
由于我的英文实在是差,没搞明白proxy-target-class="true"设置在哪,也搞不懂注解方式这个如何设,最终是试着放在这的。我想,如果不是用注解方式,可以放在<bean/>里。
再次运行,提试CGLIB要复制到CLASSPAH下,在spring的Lib目录中找到,复制好就OK了。
下面我把用到的Jar包列出,另外我把我测试用的project也上传到http://download.csdn.net/source/2613955,大家可以下载看看。
我写的记录了我的整个过程,这个过程,我用了好几个晚上的功夫,文字有点哆嗦。
解释一下为什么@Transaction的类,会出现上述错误,在spring中@Transaction是通过AOP实现的,而spring对AOP有两种实现方式,一种是动态代理,它是通过接口方式实现的,要求所代理的类一定是实现了某一个接口,对一般的类就无法代理,spring默认是这种;通过设置proxy-target-class="true",则是使用CGLIB实现AOP,CGLIB直接生成二进制码,使得普通类也可以实现AOP。在没有设置proxy-target-class="true"时,使用动态代理,是一个临时生成的类,如proxy17,它不是@Resource指定的类,因此出现了上述错误。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <context:component-scan base-package="com_11lu.GAE" /> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean" lazy-init="true"> <property name="persistenceUnitName" value="transactions-optional" /> </bean> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory" /> </bean> <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" /> <!-- Activates @Transactional for DefaultImageDatabase --> <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/> </beans>
package com_11lu.GAE; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.Method; import java.util.LinkedHashMap; import javax.persistence.EmbeddedId; import javax.persistence.Entity; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.Query; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; @Transactional public abstract class DaoSupport<T> implements DAO{ @PersistenceContext protected EntityManager em; public void clear(){ em.clear(); } public <T> void delete(Class<T> entityClass,Object entityid) { delete(entityClass, new Object[]{entityid}); } public <T> void delete(Class<T> entityClass,Object[] entityids) { for(Object id : entityids){ em.remove(em.getReference(entityClass, id)); } } @Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED) public <T> T find(Class<T> entityClass, Object entityId) { return em.find(entityClass, entityId); } public void save(Object entity) { em.persist(entity); } @Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED) public <T> long getCount(Class<T> entityClass) { return (Long)em.createQuery("select count("+ getCountField(entityClass) +") from "+ getEntityName(entityClass)+ " o").getSingleResult(); } public void update(Object entity) { em.merge(entity); } @Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED) public <T> QueryResult<T> getScrollData(Class<T> entityClass, int firstindex, int maxresult, LinkedHashMap<String, String> orderby) { return getScrollData(entityClass,firstindex,maxresult,null,null,orderby); } @Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED) public <T> QueryResult<T> getScrollData(Class<T> entityClass, int firstindex, int maxresult, String wherejpql, Object[] queryParams) { return getScrollData(entityClass,firstindex,maxresult,wherejpql,queryParams,null); } @Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED) public <T> QueryResult<T> getScrollData(Class<T> entityClass, int firstindex, int maxresult) { return getScrollData(entityClass,firstindex,maxresult,null,null,null); } @Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED) public <T> QueryResult<T> getScrollData(Class<T> entityClass) { return getScrollData(entityClass, -1, -1); } @SuppressWarnings("unchecked") @Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED) public <T> QueryResult<T> getScrollData(Class<T> entityClass, int firstindex, int maxresult , String wherejpql, Object[] queryParams,LinkedHashMap<String, String> orderby) { QueryResult qr = new QueryResult<T>(); String entityname = getEntityName(entityClass); Query query = em.createQuery("select o from "+ entityname+ " o "+(wherejpql==null? "": "where "+ wherejpql)+ buildOrderby(orderby)); setQueryParams(query, queryParams); if(firstindex!=-1 && maxresult!=-1) query.setFirstResult(firstindex).setMaxResults(maxresult); qr.setResultlist(query.getResultList()); query = em.createQuery("select count("+ getCountField(entityClass)+ ") from "+ entityname+ " o "+(wherejpql==null? "": "where "+ wherejpql)); setQueryParams(query, queryParams); qr.setTotalrecord((Long)query.getSingleResult()); return qr; } protected void setQueryParams(Query query, Object[] queryParams){ if(queryParams!=null && queryParams.length>0){ for(int i=0; i<queryParams.length; i++){ query.setParameter(i+1, queryParams[i]); } } } /** * 组装order by语句 * @param orderby * @return */ protected String buildOrderby(LinkedHashMap<String, String> orderby){ StringBuffer orderbyql = new StringBuffer(""); if(orderby!=null && orderby.size()>0){ orderbyql.append(" order by "); for(String key : orderby.keySet()){ orderbyql.append("o.").append(key).append(" ").append(orderby.get(key)).append(","); } orderbyql.deleteCharAt(orderbyql.length()-1); } return orderbyql.toString(); } /** * 获取实体的名称 * @param <T> * @param entityClass 实体类 * @return */ protected <T> String getEntityName(Class<T> entityClass){ String entityname = entityClass.getSimpleName(); Entity entity = entityClass.getAnnotation(Entity.class); if(entity.name()!=null && !"".equals(entity.name())){ entityname = entity.name(); } return entityname; } protected <T> String getCountField(Class<T> clazz){ String out = "o"; try { PropertyDescriptor[] propertyDescriptors = Introspector.getBeanInfo(clazz).getPropertyDescriptors(); for(PropertyDescriptor propertydesc : propertyDescriptors){ Method method = propertydesc.getReadMethod(); if(method!=null && method.isAnnotationPresent(EmbeddedId.class)){ PropertyDescriptor[] ps = Introspector.getBeanInfo(propertydesc.getPropertyType()).getPropertyDescriptors(); out = "o."+ propertydesc.getName()+ "." + (!ps[1].getName().equals("class")? ps[1].getName(): ps[0].getName()); break; } } } catch (Exception e) { e.printStackTrace(); } return out; } }
问题:
1.在一个service连对一个实例两次保存
SystemUser user = (SystemUser) getSystemUser(); initSystemDao.save(user); initSystemDao.save(user);
引起:TransactionOptions.Builder.withXGfound both Element
解决:在persistence.xml增加
<property name="datanucleus.appengine.datastoreEnableXGTransactions" value="true"/>
antlr-2.7.6.jar
aopalliance.jar
appengine-api-1.0-sdk-1.3.5.jar
appengine-api-labs-1.3.5.jar
appengine-jsr107cache-1.3.5.jar
cglib-nodep-2.1_3.jar
commons-beanutils.jar
commons-collections.jar
commons-fileupload-1.2.1.jar
commons-io-1.3.2.jar
commons-lang.jar
commons-logging-1.0.4.jar
commons-logging.jar
datanucleus-appengine-1.0.7.final.jar
datanucleus-core-1.1.5.jar
datanucleus-jpa-1.1.5.jar
freemarker-2.3.13.jar
geronimo-jpa_3.0_spec-1.1.1.jar
geronimo-jta_1.1_spec-1.1.1.jar
jdo2-api-2.3-eb.jar
jsr107cache-1.1.jar
ognl-2.6.11.jar
slf4j-api-1.5.8.jar
slf4j-simple-1.5.8.jar
spring-aop.jar
spring-beans.jar
spring-context.jar
spring-core.jar
spring-jdbc.jar
spring-orm.jar
spring-tx.jar
spring-web.jar
struts2-core-2.1.8.1.jar
struts2-gae-0.1.jar
struts2-spring-plugin-2.1.8.1.jar
xwork-core-2.1.6.jar
- GAEWithSpringAndStruAndJpa.part3.rar (1005.2 KB)
- 下载次数: 20
- GAEWithSpringAndStruAndJpa.part2.rar (5 MB)
- 下载次数: 25
- GAEWithSpringAndStruAndJpa.part1.rar (5 MB)
- 下载次数: 22
发表评论
-
FFmpeg常用基本命令
2016-07-15 11:52 0http://www.cnblogs.com/dwdxdy/p ... -
iF.SVNAdmin安装
2016-06-27 17:13 1428http://blog.linhere.com/archive ... -
Spring Boot 属性配置
2016-06-24 11:04 1191Spring Boot 属性配置和使用 http://blog ... -
Spring Boot 集成MyBatis
2016-06-24 10:55 2036Spring Boot 集成MyBatis http://bl ... -
Spring MVC防重复提交
2016-06-17 15:47 1654http://my.oschina.net/zyqjustin ... -
Spring容器加载完之后执行特定任务
2016-06-17 15:36 2297http://my.oschina.net/simpleton ... -
使用spring-session和shiro来代理session的配置
2016-06-16 11:21 12069使用spring-session和redis来代理sessio ... -
JSTL 的 if else : 有 c:if 没有 else 的处理
2016-06-14 09:52 1344http://blog.csdn.net/xiyuan1999 ... -
spring mvc 请求转发和重定向
2016-06-14 09:48 1410http://blog.csdn.net/jackpk/art ... -
apache调优
2016-05-21 10:10 1146http://my.oschina.net/renqingsh ... -
mvc:view-controller
2016-05-18 10:26 1090http://blog.csdn.net/lzwglory/a ... -
spring配置事物的方式:注解和aop配置
2016-05-14 00:26 4114参考: Spring AOP中pointcut express ... -
分布式任务调度组件 Uncode-Schedule
2016-05-13 14:47 2294http://www.oschina.net/p/uncode ... -
Mybatis分库分表扩展插件
2016-05-12 15:47 1633http://fangjialong.iteye.com/bl ... -
spring+mybatis+atomikos 实现JTA事务
2016-05-11 22:00 5533sping配置多个数据源 不同用户操作不同数据库 http:/ ... -
Spring中使用注解 @Scheduled执行定时任务
2016-05-10 09:39 1575原文:http://dwf07223.blog.51cto.c ... -
Spring中配置Websocket
2016-05-05 16:55 1286spring+websocket整合(springMVC+sp ... -
redis 集群中Session解决方案之Spring Session
2016-05-04 08:54 1325集群中Session解决方案之Spring Session h ... -
使用Spring-data进行Redis操作
2016-05-04 08:54 4810使用Spring-data进行Redis操作 http://z ... -
Spring4新特性——集成Bean Validation 1.1(JSR-349)到SpringMVC
2016-05-03 13:35 1070Spring4新特性——集成Bean Validation 1 ...
相关推荐
一个使用Struts2 + Spring 在 google Appengine 上开发的一个例子,非常简单,主要是帮助有这方面需求的朋友快速的整合!运行后,测试访问用两个网址 http://localhost:8888/person_add.action?person.name=*** ...
分布式宠物商店(EJB3+JPA+Struts2) 宠物商店(petstore)是个比较经典的demo案例, 以宠物商店充分演示EJB3与Java Web程序,Java图形界面程序的结合 主要模块:会员模块 宠物类别模块 宠物模块 购物模块
5. **整合与协调**:研究Struts2、Spring、Hibernate和JPA如何集成在一起,以及如何通过Spring管理其他两个框架的生命周期。 通过深入研究这个项目,开发者可以学习到如何构建一个完整的、基于Java的Web应用,并...
标题 "Spring+Hibernate+Jpa+Struts2整合实例" 描述的是一个综合性的Web开发教程,它将四个关键的Java技术框架集成在一起,用于构建高效的企业级应用程序。这个实例涵盖了Spring作为整体应用的管理框架,Hibernate...
Spring是Java企业级应用开发的核心框架,它提供了一个全面的编程和配置模型,用于简化企业级应用的开发。Spring的核心特性包括依赖注入(DI)、面向切面编程(AOP)、事务管理以及大量的可扩展性组件,如Spring JDBC...
spring+hibernate+jpa+struts1+struts2+springmvc+jquery+freemaker 学习笔记 Compass将lucene、Spring、Hibernate三者结合
在Java Web开发中,Spring、Struts2和JPA是三个非常重要的框架。Spring作为一个全面的轻量级框架,提供了依赖注入(DI)和面向切面编程(AOP)等功能;Struts2是一个强大的MVC框架,用于处理用户请求和业务逻辑;JPA...
第9篇为实战篇,内容为两个典型的应用系统:论坛系统(Spring+Struts+Hibernate)、宠物商店(EJB 3+JPA+Struts 2)。 《Java Web整合开发王者归来(JSP+Servlet+Struts+Hibernate+Spring)》附1张DVD光盘,内容为《Java ...
在Java企业级应用开发中,`JPA (Java Persistence API)`、`Struts1` 和 `Spring` 是三个非常关键的框架。它们分别扮演着不同的角色,共同构建了一个功能强大的后端架构。以下是对这三个技术及其整合的详细解析: 1....
在Java Web开发中,Spring、Struts2和JPA(Java Persistence API)是三个非常重要的框架。它们分别负责不同的职责:Spring作为全面的轻量级应用框架,Struts2是MVC(Model-View-Controller)设计模式的实现,而JPA则...
Spring 框架的核心特性包括依赖注入(DI)和面向切面编程(AOP),此外,它还支持数据访问、事务管理、Web 应用开发等多个领域。 2. **JPA (Java Persistence API)**:JPA 是Java EE中的一个标准API,用于对象关系...
在企业级Java开发中,Struts2、JPA(Java Persistence API)和Spring框架的整合是常见的技术栈选择,它们各自扮演着不同的角色,共同构建出强大的MVC(Model-View-Controller)架构应用。Struts2作为表现层框架,...
Spring框架是Java应用开发的核心组件,它提供了一个全面的基础设施,支持创建可测试、松耦合的Java应用程序。在Spring 2.5版本中,增强了对AOP(面向切面编程)、依赖注入和资源管理的支持,同时引入了Spring MVC,...
在Java企业级应用开发中,Spring、Struts和JPA(Java Persistence API)是三个非常重要的框架。它们分别负责不同的职责:Spring作为一个全能型框架,提供了依赖注入(DI)和面向切面编程(AOP),以及对其他框架的...