- 浏览: 298544 次
- 性别:
- 来自: 东京
文章分类
最新评论
-
80后的童年2:
企业级分布式搜索平台Solr视频教程网盘地址:https:// ...
企业级搜索引擎Solr使用入门指南 -
springdata_spring:
apache lucene开源框架demo使用实例教程源代码下 ...
Lucene / Solr 开发经验 -
springdata-jpa:
java web开发分页demo源代码下载:http://ww ...
简易java分页标签 -
zjf_sdnu:
兄弟,script写错了
jqGrid初学备注 -
85600367:
你好,请教一个问题。当进行分布式查询时solr无法查询到Luc ...
Lucene / Solr 开发经验
翻译:SpringSide团队 转载请注明出处。
本文提供了一个简单的 Spring 框架 standalone 环境下,如何 step-by-step 去开发 JPA 的向导。 JPA 的规范最开始时是由 EJB 3.0 的持久性机制产生的, 它被公认为是把简单的 POJOs 持久化的机制。你只需少量 JAR 在 classpath 中,配置一点 Spring 的 bean, 就能在你喜爱的IDE中去开始感受 JPA 的强大威力了。我们在这里使用的是 Glassfish JPA - 一个基于 Oracle’s TopLink ORM framework 的开源项目
初始化设置
1. 保证你使用的是Java 5 (EJB 3.0 中 JPA 的先决条件).
2. 从 https://glassfish.dev.java.net/downloads/persistence/JavaPersistence.html 下载 glassfish JPA jar (注意: 我使用的是 “V2_build_02″ jar, 但该版本后的版本也应回往前兼容的.)
3. 从“installer” jar 中解压,并运行: java -jar glassfish-persistence-installer-v2-b02.jar
4. 把 toplink-essentials.jar 加入你的 classpath
5. 把数据库的驱动 JAR 也加入( 我用的是 version 1.8.0.1 的 hsqldb.jar 作为例子,但实际上你只需很少的改变就能适配到另外的数据库 )
6. 加入2.0 M5 以上版本的Spring JAR( http://sourceforge.net/project/showfiles.php?group_id=73357) - spring.jar - spring-jpa.jar - spring-mock.jar
7. 最后,把这些 JAR 也加入到你的classpath 中: - commons-logging.jar - log4j.jar - junit.jar
领域模型 (domain model)
这个例子中我们只是有目的地列举了3个简单的domain model. 要注意的是这例子中我们使用了annotation。 使用 JPA 时,一般会选择用annotation 或 XML 文件,又或者两者一起配合用,去指定ORM(object-relational mapping)元数据。在这里,我们只是选择了单独用annotation, 因为只需要在domain model 的代码中加入简短的描述就能马上办到。 首先, 看看餐厅 Restaurant class:
package blog.jpa.domain; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.OneToOne; @Entity public class Restaurant { @Id @GeneratedValue(strategy = GenerationType.AUTO) private long id; private String name; @OneToOne(cascade = CascadeType.ALL) private Address address; @ManyToMany @JoinTable(inverseJoinColumns = @JoinColumn(name = "ENTREE_ID")) private Set<Entree> entrees; public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } public Set<Entree> getEntrees() { return entrees; } public void setEntrees(Set<Entree> entrees) { this.entrees = entrees; } } Adderss class: package blog.jpa.domain; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @Entity public class Address { @Id @GeneratedValue(strategy = GenerationType.AUTO) private long id; @Column(name = "STREET_NUMBER") private int streetNumber; @Column(name = "STREET_NAME") private String streetName; public long getId() { return id; } public void setId(long id) { this.id = id; } public int getStreetNumber() { return streetNumber; } public void setStreetNumber(int streetNumber) { this.streetNumber = streetNumber; } public String getStreetName() { return streetName; } public void setStreetName(String streetName) { this.streetName = streetName; } }
然后, Entree class:
package blog.jpa.domain; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @Entity public class Entree { @Id @GeneratedValue(strategy = GenerationType.AUTO) private long id; private String name; private boolean vegetarian; public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public boolean isVegetarian() { return vegetarian; } public void setVegetarian(boolean vegetarian) { this.vegetarian = vegetarian; } }
如你看到的那样,并不是所有的 field 都需要annotation。JAP 会使用默认值(例如用数据表中的列名来精确匹配属性名),所以在很多的情况下,你并不需要很明确的去指定元数据。需要注意的是,在 Entree 类中,我并没有为String 属性 “name” 或 boolean 属性 “vegetarian” 加入 annotation。
然而,在 Address 类中,我使用了annotation, 因为我不想用数据库表中的列名作为默认名(例如,我用 “STREET_NAME”而默认的是 “STREETNAME”)。在ORM机制中最重要的当然是指定Objects和database间的对应关系。在 Restaurant 类中,我们用 @OneToOne 去描述它与 Address 的关系,同时我们用 @ManyToMany 去描述它与 Entree 类中的成员关系。因为其它类的实例也是由 EntityManager 所管理的, 所以可以指定“cascade”规则,如当一个 Restaurant 被删除,所有相关联的 Address 也会同时被删除。在下面,你将会看到这个场景的测试用例。 最后,看看 @Id 和指定“strategy”给ID的 @GeneratedValue 。 这元数据是用来描述数据库中唯一键 primary key 的生成方式的。想知道更多关于JPA annotation 的资料,查看 JPA 的说明文档,JSR-220. 数据访问层 (Data Access Layer) 最好的方式是建立通用的接口去隐藏持久层所有的实现细节,这样就算由JPA换到其它的实现方式也不会影响到系统架构。
同时,这也为业务逻辑层提供了方便,可以更容易地实现 stub 或 mock 测试。 RestaurantDao 是一个接口,注意它没有对任何 JPA 或 Spring 的类有依赖。实际上,它只对自身的domain model 有依赖(在这个简单的例子中,只有一个,那就是 Restaurant):
package blog.jpa.dao; import java.util.List; import blog.jpa.domain.Restaurant; public interface RestaurantDao { public Restaurant findById(long id); public List<Restaurant> findByName(String name); public List<Restaurant> findByStreetName(String streetName); public List<Restaurant> findByEntreeNameLike(String entreeName); public List<Restaurant> findRestaurantsWithVegetarianEntrees(); public void save(Restaurant restaurant); public Restaurant update(Restaurant restaurant); public void delete(Restaurant restaurant); }
对于接口的实现,我使用了 Spring 的 JpaDaoSupport 类,它提供了方便的方法去获取 JpaTemplate。如果你已经比较熟悉 Spring 的 JDBC 或者起其它 ORM 技术,则很容易上手。 JpaDaoSupport 是可选的,它只是提供了通过 EntityManagerFactory 更直接使用 JpaTemplate 的方法。JpaTemplate 也是可选的,如果你不希望 Spring 的自动处理 JPA exception 的事务方式,你完全可以避免使用 JpaTemplate 。即使这样,Spring 的 EntityManagerFactoryUtils 类还是会对你有比较大的帮助,它提供了方便的静态方法去获取共享的EntityManager。下面是具体实现代码:
package blog.jpa.dao; import java.util.List; import org.springframework.orm.jpa.support.JpaDaoSupport; import blog.jpa.domain.Restaurant; public class JpaRestaurantDao extends JpaDaoSupport implements RestaurantDao { public Restaurant findById(long id) { return getJpaTemplate().find(Restaurant.class, id); } public List<Restaurant> findByName(String name) { return getJpaTemplate().find("select r from Restaurant r where r.name = ?1", name); } public List<Restaurant> findByStreetName(String streetName) { return getJpaTemplate().find("select r from Restaurant r where r.address.streetName = ?1", streetName); } public List<Restaurant> findByEntreeNameLike(String entreeName) { return getJpaTemplate().find("select r from Restaurant r where r.entrees.name like ?1", entreeName); } public List<Restaurant> findRestaurantsWithVegetarianEntrees() { return getJpaTemplate().find("select r from Restaurant r where r.entrees.vegetarian = 'true'"); } public void save(Restaurant restaurant) { getJpaTemplate().persist(restaurant); } public Restaurant update(Restaurant restaurant) { return getJpaTemplate().merge(restaurant); } public void delete(Restaurant restaurant) { getJpaTemplate().remove(restaurant); } }
业务逻辑层 (Service Layer)
由于我们的主要目的是集中在数据访问层 JPA 的实现,所以业务逻辑层基本上忽略不讲。在实际项目中,业务逻辑层对于整个系统的架构至关重要。它是分离事务(transaction)的重点。一般情况下,我们都会通过 Spring 来配置事务。在下面的步骤中,当你看配置时,你会注意到我已提供了一个“transactionManager” 的 bean。 它可以为测试用例中的每个测试方法提供事务回滚,同时它也让使用同一个 “transactionManager”的业务逻辑层的方法提供事务处理。数据库访问层的代码与则不负责事务处理,事务传播的发生是自动的,最终由业务逻辑层来处理。Spring 框架中的所有持久层类的配置都是相同的,使用 Spring JpaTemplate 时要注意保证所有 DAO 都共享同一个EntityManager 。
配置
因为我选择了使用基于 annotation 的映射关系,你或许已经看过许多 JPA 的配置说明,如我上面说提到的,它同样可以通过 XML( 在‘orm.xml’文件里 )来配置映射关系。另一种则只要求配置‘META-INF/persistence.xml’。这样的话,就能更为容易,因为database相关的属性可以通过EntityManagerFactory 来获得。在‘persistence.xml’中需要的信息只是需要 local 的还是global(JTA) 的事务。下面是 ‘persistence.xml’ 的具体内容:
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0"> <persistence-unit name="SpringJpaGettingStarted" transaction-type="RESOURCE_LOCAL"/> </persistence>
有4个bean在这 Spring 配置中是要注意的。
首先,看看“restaurantDao” (我没有在bean名前的"jpa"也加上去的原因是所有的业务逻辑层都必须只与接口相关),其唯一需要的 property 就是 “entityManagerFactory” ,用于产生JpaTemplate。 “entityManagerFactory” 需要“dataSource”, 这个在 JPA 说明文档里并没有提到。在这里,我们使用了DriverManagerDataSource,但是在实际操作中,你需要用你自己数据库的连接池,或者是用 JndiObjectFactoryBean来得到Jndi。最后的 “transactionManager” bean是测试和逻辑层处理事务需要到的。如果你已经熟悉 Spring 下 JDBC, Hibernate, JDO, TopLink, 或 iBATIS 的配置,这几个bean对于你来说是再简单不过了。然我们来看看完整的‘applicationContext.xml’ 文件。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="restaurantDao" class="blog.jpa.dao.JpaRestaurantDao"> <property name="entityManagerFactory" ref="entityManagerFactory"/> </bean> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.ContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.TopLinkJpaVendorAdapter"> <property name="showSql" value="true"/> <property name="generateDdl" value="true"/> <property name="databasePlatform" value="oracle.toplink.essentials.platform.database.HSQLPlatform"/> </bean> </property> <property name="loadTimeWeaver"> <bean class="org.springframework.instrument.classloading.SimpleLoadTimeWeaver"/> </property> </bean> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="org.hsqldb.jdbcDriver"/> <property name="url" value="jdbc:hsqldb:hsql://localhost/"/> <property name="username" value="sa"/> <property name="password" value=""/> </bean> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory"/> <property name="dataSource" ref="dataSource"/> </bean> </beans>
“entityManagerFactory” bean需要 “jpaVendorAdapter” ,对于 “jpaVendorAdapter”有多种多样的JPA实现方式。在这个例子里,我用了 TopLinkJpaVendorAdapter 作为 inner bean,它也需要自己的一些property ,它有两个属性分别指明是否现实SQL和是否生成DDL.在这里我们都设为 “true” ,所以当测试的时候数据库表会每次都自动生成,这对于早期的开发带来不少方便。还有就是“databasePlatformClass” 提供了必要的数据库库使用的详细信息。“entityManagerFactory”还有一个“loadTimeWeaver” 属性,以配合某些特性,如延迟加载(lazy-loading)。
集成测试(Integration Testing)
JpaRestaurantDaoTests 提供了一些基础的测试。你可以自己尝试动手修改一下配置文件和测试代码,来掌握更多关于JPA的知识,如尝试不同的设置cascade 。值得注意的是 JpaRestaurantDaoTests 继承了 Spring 的 AbstractJpaTests。也许你已经比较熟悉 Spring 的 AbstractTransactionalDataSourceSpringContextTests, 这个类可以让在测试中的所有数据库改变都回滚。AbstractJpaTests 实际上的作用不仅于此,但已经超出了我们该讲的范围了。如果感兴趣,你可以深入看看AbstractJpaTests的源代码。这里是 JpaRestaurantDaoTests 的实现代码:
package blog.jpa.dao; import java.util.List; import org.springframework.test.jpa.AbstractJpaTests; import blog.jpa.dao.RestaurantDao; import blog.jpa.domain.Restaurant; public class JpaRestaurantDaoTests extends AbstractJpaTests { private RestaurantDao restaurantDao; public void setRestaurantDao(RestaurantDao restaurantDao) { this.restaurantDao = restaurantDao; } protected String[] getConfigLocations() { return new String[] {"classpath:/blog/jpa/dao/applicationContext.xml"}; } protected void onSetUpInTransaction() throws Exception { jdbcTemplate.execute("insert into address (id, street_number, street_name) values (1, 10, 'Main Street')"); jdbcTemplate.execute("insert into address (id, street_number, street_name) values (2, 20, 'Main Street')"); jdbcTemplate.execute("insert into address (id, street_number, street_name) values (3, 123, 'Dover Street')"); jdbcTemplate.execute("insert into restaurant (id, name, address_id) values (1, 'Burger Barn', 1)"); jdbcTemplate.execute("insert into restaurant (id, name, address_id) values (2, 'Veggie Village', 2)"); jdbcTemplate.execute("insert into restaurant (id, name, address_id) values (3, 'Dover Diner', 3)"); jdbcTemplate.execute("insert into entree (id, name, vegetarian) values (1, 'Hamburger', 0)"); jdbcTemplate.execute("insert into entree (id, name, vegetarian) values (2, 'Cheeseburger', 0)"); jdbcTemplate.execute("insert into entree (id, name, vegetarian) values (3, 'Tofu Stir Fry', 1)"); jdbcTemplate.execute("insert into entree (id, name, vegetarian) values (4, 'Vegetable Soup', 1)"); jdbcTemplate.execute("insert into restaurant_entree (restaurant_id, entree_id) values (1, 1)"); jdbcTemplate.execute("insert into restaurant_entree (restaurant_id, entree_id) values (1, 2)"); jdbcTemplate.execute("insert into restaurant_entree (restaurant_id, entree_id) values (2, 3)"); jdbcTemplate.execute("insert into restaurant_entree (restaurant_id, entree_id) values (2, 4)"); jdbcTemplate.execute("insert into restaurant_entree (restaurant_id, entree_id) values (3, 1)"); jdbcTemplate.execute("insert into restaurant_entree (restaurant_id, entree_id) values (3, 2)"); jdbcTemplate.execute("insert into restaurant_entree (restaurant_id, entree_id) values (3, 4)"); } public void testFindByIdWhereRestaurantExists() { Restaurant restaurant = restaurantDao.findById(1); assertNotNull(restaurant); assertEquals("Burger Barn", restaurant.getName()); } public void testFindByIdWhereRestaurantDoesNotExist() { Restaurant restaurant = restaurantDao.findById(99); assertNull(restaurant); } public void testFindByNameWhereRestaurantExists() { List<Restaurant> restaurants = restaurantDao.findByName("Veggie Village"); assertEquals(1, restaurants.size()); Restaurant restaurant = restaurants.get(0); assertEquals("Veggie Village", restaurant.getName()); assertEquals("Main Street", restaurant.getAddress().getStreetName()); assertEquals(2, restaurant.getEntrees().size()); } public void testFindByNameWhereRestaurantDoesNotExist() { List<Restaurant> restaurants = restaurantDao.findByName("No Such Restaurant"); assertEquals(0, restaurants.size()); } public void testFindByStreetName() { List<Restaurant> restaurants = restaurantDao.findByStreetName("Main Street"); assertEquals(2, restaurants.size()); Restaurant r1 = restaurantDao.findByName("Burger Barn").get(0); Restaurant r2 = restaurantDao.findByName("Veggie Village").get(0); assertTrue(restaurants.contains(r1)); assertTrue(restaurants.contains(r2)); } public void testFindByEntreeNameLike() { List<Restaurant> restaurants = restaurantDao.findByEntreeNameLike("%burger"); assertEquals(2, restaurants.size()); } public void testFindRestaurantsWithVegetarianOptions() { List<Restaurant> restaurants = restaurantDao.findRestaurantsWithVegetarianEntrees(); assertEquals(2, restaurants.size()); } public void testModifyRestaurant() { String oldName = "Burger Barn"; String newName = "Hamburger Hut"; Restaurant restaurant = restaurantDao.findByName(oldName).get(0); restaurant.setName(newName); restaurantDao.update(restaurant); List<Restaurant> results = restaurantDao.findByName(oldName); assertEquals(0, results.size()); results = restaurantDao.findByName(newName); assertEquals(1, results.size()); } public void testDeleteRestaurantAlsoDeletesAddress() { String restaurantName = "Dover Diner"; int preRestaurantCount = jdbcTemplate.queryForInt("select count(*) from restaurant"); int preAddressCount = jdbcTemplate.queryForInt("select count(*) from address where street_name = 'Dover Street'"); Restaurant restaurant = restaurantDao.findByName(restaurantName).get(0); restaurantDao.delete(restaurant); List<Restaurant> results = restaurantDao.findByName(restaurantName); assertEquals(0, results.size()); int postRestaurantCount = jdbcTemplate.queryForInt("select count(*) from restaurant"); assertEquals(preRestaurantCount - 1, postRestaurantCount); int postAddressCount = jdbcTemplate.queryForInt("select count(*) from address where street_name = 'Dover Street'"); assertEquals(preAddressCount - 1, postAddressCount); } public void testDeleteRestaurantDoesNotDeleteEntrees() { String restaurantName = "Dover Diner"; int preRestaurantCount = jdbcTemplate.queryForInt("select count(*) from restaurant"); int preEntreeCount = jdbcTemplate.queryForInt("select count(*) from entree"); Restaurant restaurant = restaurantDao.findByName(restaurantName).get(0); restaurantDao.delete(restaurant); List<Restaurant> results = restaurantDao.findByName(restaurantName); assertEquals(0, results.size()); int postRestaurantCount = jdbcTemplate.queryForInt("select count(*) from restaurant"); assertEquals(preRestaurantCount - 1, postRestaurantCount); int postEntreeCount = jdbcTemplate.queryForInt("select count(*) from entree"); assertEquals(preEntreeCount, postEntreeCount); } }
进一步阅读
JPA是一个很大的话题,这篇日志只是讲述了如何在 Spring 框架中配置 JPA.
只要你弄懂了配置如何运作,你就能很好的运用 JPA提供的ORM功能。我非常建议你去看看 JPA的官方文档还有 Spring reference 文档。在Spring 2.0 RC1 文档中就有加入了 JPA 的 ORM部分内容。以下是比较有用的一些连接:
JSR-220 (包含了 JPA 说明文档)
http://www.jcp.org/en/jsr/detail?id=220
Glassfish JPA (相关的实现说明)
https://glassfish.dev.java.net/javaee5/persistence/
Kodo 4.0 (BEA的基于Kodo的JPA实现)
http://commerce.bea.com/showproduct.jsp?family=KODO&major=4.0&minor=0
Hibernate JPA Migration Guide
http://www.hibernate.org/371.html
(自 http://blog.interface21.com/main/2006/05/30/getting-started-with-jpa-in-spring-20/ , cac 翻译)
注:因无法拷贝原的连接地址。因此,此处略有改动。
发表评论
-
Struts2 Jsonplugin 详解
2009-07-08 21:41 7107本文转自: http://www.blogjava.net/f ... -
一点struts json备注
2009-07-05 00:30 1538下载struts json插件:jsonplugin-0.33 ... -
Hibernate annotation简单配置
2009-06-29 00:04 1683<?xml version="1.0" ... -
Liferay下整合Spring和Hibernate开发Plugin初试
2009-05-26 00:41 4904简单的说,完全不知道Liferay下应该如何做开发。所以完全凭 ... -
Liferay plugin开发入门
2009-05-19 00:10 2736本篇部分引用以下文章: http://daoger.itey ... -
Hibernate通用DAO
2009-01-02 17:46 3630/** * @author Clay Zhong, zjcl ... -
Acegi获取用户信息
2008-12-04 23:38 2865import org.acegisecurity.Authen ... -
Acegi详解
2008-11-16 21:15 1790本文转自:http://www.yuanma.org/data ... -
velocity.properties source code
2008-11-04 22:37 3011# Licensed to the Apache Softwa ... -
DetachedCriteria,Hibernate模糊查询
2008-09-21 10:59 42051,假设存在Thesis对象: package org.cms ... -
lucene常用搜索排序摘录
2008-09-16 23:38 3165一,查询 一个关键字,对一个字段进行查询 Query ... -
Solr中SimplePostTool的修改
2008-09-15 22:38 3004将源代码修改为传递字符串,去掉files以及stdin模式。 ... -
Struts2,Spring2,Hibernate3整合
2008-09-15 11:44 33971. web.xml <?xml version=&qu ... -
企业级搜索引擎Solr使用入门指南
2008-09-10 22:43 16696本文转自 http://chuanliang2 ... -
Lucene / Solr 开发经验
2008-09-10 22:12 20064转自 Lucene/Solr开发经验[原] 作者 张驰有道 ... -
Lucene初学备注
2008-09-07 19:51 12711,检索文件目录,创建index import java.io ... -
JR各Ajax框架基础教程收集
2008-08-24 12:19 1226JQuery: http://www.javaresearch ... -
Hibernate延迟加载
2008-02-09 16:22 2739延迟初始化错误是运用Hibernate开发项目时最常见的错误。 ... -
Properties资源文件编码
2008-01-26 17:26 15251、展开Eclipse的Help菜单,将鼠标移到Softwar ... -
struts+hibernate分页
2007-12-17 20:53 1748新建表 sql 代码 DROP DATABAS ...
相关推荐
Spring 2.0 和 JPA(Java Persistence API)是企业级Java开发中的两个核心组件,它们在构建现代、高效、可扩展的应用程序方面发挥着关键作用。本教程结合了这两个强大的技术,为开发者提供了一个全面的学习平台,以...
本手册和使用指南提供了全面的Spring 2.0相关知识,包括其核心特性、配置方式以及如何在实际项目中应用。 首先,让我们深入了解一下Spring框架的核心概念。Spring的依赖注入(Dependency Injection,简称DI)是一种...
在Spring 2.0中,除了XML配置之外,还引入了基于注解的配置,使得代码更加简洁且易于维护。 三、AOP Spring的AOP模块提供了面向切面编程的能力,可以用于实现如日志记录、事务管理等跨切面关注点。Spring 2.0的AOP...
Spring 2.0是Spring框架的一个重要版本,它在Java企业级应用开发中扮演着核心角色。本教程将深入探讨...文档`spring2.0-reference_final_zh_cn.chm`将详细阐述这些概念和技术,帮助你成为一名熟练的Spring开发者。
在Spring 2.0中,DI得到了增强,支持了基于注解的配置,这使得XML配置文件可以显著减少,代码更加简洁易读。 另一个重要特性是AOP(面向切面编程),Spring的AOP模块允许开发者定义横切关注点,如日志记录、事务...
手册中还会详细讲解Spring的安全、测试、邮件服务等模块,帮助开发者全方位理解和掌握Spring 2.0框架。通过阅读《Spring 2.0中文参考手册》,开发者不仅可以学习到Spring的基本用法,还能了解到如何将Spring应用于...
Spring 2.0在数据访问层也有显著改进,支持了更多数据库访问技术,如JPA(Java Persistence API)和Hibernate。它提供了统一的DAO支持,使得不同数据访问技术的使用变得一致,简化了开发工作。此外,Spring的JDBC...
通过《Spring2.0宝典》的源代码,学习者可以逐步探索上述功能的实际运用,了解每个特性在项目中的实现方式,从而提升对Spring框架的理解和使用能力。在阅读源代码的过程中,建议结合书中的讲解,按照章节顺序逐步...
Spring 2.0是Java开发中的一个里程碑,它在企业级应用开发中扮演着至关重要的角色,特别是对于依赖注入(IoC)和面向切面编程(AOP)的支持。本学习提纲旨在为初学者提供一份详尽的Spring 2.0学习指南,帮助他们系统...
### SPRING2.0开发详解 #### 一、Spring框架简介 Spring框架是一个开源的Java平台,用于构建企业级应用程序和服务。它最初由Rod Johnson在2004年创建,并随着时间的发展不断壮大和完善。Spring 2.0版本是Spring...
Spring提供了声明式事务管理,使得开发者无需在代码中处理事务边界,只需在配置中声明事务规则即可。 8. **MVC框架**: Spring MVC是Spring中的Web开发组件,用于构建RESTful服务和传统的表单驱动应用。它包含...
在"配置SPRING2.0"的文件中,可能包含的是Spring 2.0的应用上下文配置文件,用于定义Bean、数据源、事务管理器等组件的配置。学习如何正确配置这些元素是理解和使用Spring 2.0的关键步骤。配置文件通常使用XML格式,...
在Spring 2.0中,最重要的更新之一是AOP(面向切面编程)的增强。这一版本引入了基于注解的AOP支持,使得开发者可以更直观地定义切面,无需编写XML配置。例如,@Before、@After、@Around等注解可以直接应用于方法上...
4. **更好的 XML 配置支持**:Spring 2.0 提供了更强大、更灵活的 XML 配置选项,使得配置更加简洁。 5. **支持更多的 J2EE 技术**:除了传统的 J2EE 技术之外,Spring 2.0 还增加了对 EJB 3.0、JSF 等新标准的支持...
在Spring 2.0中,DI通过XML配置文件和注解两种方式进行,注解方式的引入使得代码更加简洁,减少了XML配置的工作量。 其次,Spring的AOP(面向切面编程)允许开发者定义“切面”,即关注点的模块化,如日志、事务...
4. **数据访问集成**:Spring 2.0加强了与各种数据存储的集成,包括JDBC、Hibernate、JPA等,提供了模板类和DAO支持,简化了数据访问层的开发。 5. **Web服务支持**:Spring 2.0引入了Spring-WS项目,提供了一种...
3. **IoC容器增强**:在Spring2.0中,IoC容器得到了显著的增强,支持了更多类型的bean定义,包括基于XML的配置和基于注解的配置。此外,还引入了Bean生命周期接口,使得开发者可以更精确地控制bean的创建、初始化、...
Spring作为Java开发中的核心框架,它的2.0版本带来了许多重要的改进和增强,使得它在企业级应用开发中更加成熟和强大。这份手册深入剖析了Spring 2.0的主要特性和用法,对于理解并掌握该版本的Spring框架至关重要。 ...
这个"Spring2.0中文帮助文档"是学习Spring 2.0的重要参考资料,可以帮助开发者深入理解框架的工作原理和最佳实践。 在Spring 2.0中,最重要的更新之一是引入了AOP(面向切面编程)的概念。AOP允许开发者将关注点...
在Spring 2.0中,数据访问层得到了显著增强,包括对JDBC、Hibernate、JPA等持久化技术的支持。Spring JDBC模块提供了一组模板类(如JdbcTemplate和SimpleJdbcInsert),简化了数据库操作。ORM(对象关系映射)支持让...