目前java开源框架真可以说是琳琅满目,最近一个多星期一直在接触spring、hibernate、tapestry。将最近一个多星期以来的学习汇总一下,以便日后查阅,也方便大家学习。
简单的介绍到处都是,对于spring、hibernate、tapestry是干什么用的,我就不多介绍了。大致能够知道spring的IOC/DI概念(AOP方面我也理解不好,暂时)、hibernate的基本概念,如对象持久,ORM,POJO这些概念,tapestry重在组件。我想懂这些并且做个简单小例子,理解本文应该就没什么大问题了。
我的开发环境是eclipse3.1+tomcat 5.0.18 +jdk1.4.2/jdk1.5 +mysql+这些相关jar包
注:spring1.2+hibernate2.1+tapestry 3.0.3
对于eclipse的操作这里不做详细介绍,下面会给出整合代码。
建立项目如together,引入需要的包,方便起见就把spring.jar引入,因为它比较全,它没有包含mock(主要是测试用的)。总之是把这些都导进到你的project里来。别import时候找不到就可以了。
Spring和hibernate结合部分:
数据库准备工作:如mysql,建库为learn,建表为customer,包含字段(aid,username,password)分别为int,varchar型。
相关代码(代码存放位置):
spring-hibernate.xml(与src保持同级)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<description>test spring and hibernate</description>
<!-- datasource -->
<bean id="datasource"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost/learn</value>
</property>
<property name="username">
<value>root</value>
</property>
<property name="password">
<value></value>
</property>
</bean>
<!-- hibernate support -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
<property name="dataSource">
<ref local="datasource" />
</property>
<property name="mappingResources">
<list>
<value>yunguang/learn/springandhibernate/Customer.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
net.sf.hibernate.dialect.MySQLDialect
</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<!-- hibernate dao -->
<bean id="hibernatedao" class="yunguang.spring.dao.TestDao">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>
</beans>
customer.hbm.xml(yunguang.learn.springandhibernate包下)
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class name="yunguang.learn.springandhibernate.Customer" table="customer">
<id name="id" column="aid">
<generator class="increment" />
</id>
<property name="username" column="username" />
<property name="password" column="password" />
</class>
</hibernate-mapping>
/*
* Created on 2005-7-6
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/
package yunguang.learn.springandhibernate;
/**
* @author Administrator
*
* TODO To change the template for this generated type comment go to Window -
* Preferences - Java - Code Style - Code Templates
*/
public class Customer {
private int id;
private String username;
private String password;
public int getId() {
return id;
}
public String getPassword() {
return password;
}
public String getUsername() {
return username;
}
public void setId(int id) {
this.id = id;
}
public void setPassword(String password) {
this.password = password;
}
public void setUsername(String username) {
this.username = username;
}
}
单元测试类
package test.junit;
import junit.framework.TestCase;
import junit.textui.TestRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import yunguang.learn.springandhibernate.Customer;
import yunguang.spring.dao.ITestDao;
public class TestDaoTest extends TestCase {
public void testInsertTest(){
ApplicationContext beans = new FileSystemXmlApplicationContext("spring-hibernate.xml");
// XmlBeanFactory beans = new XmlBeanFactory(new FileInputStream(
// "spring-hibernate.xml"));
ITestDao tests = (ITestDao) beans.getBean("hibernatedao");
Customer customer = new Customer();
customer.setId(55);
customer.setUsername("yunguangtest==================");
customer.setPassword("passwordsdlkjfklsd");
tests.insertTest(customer);
}
public static void main(String[] args) {
TestRunner.run(TestDaoTest.class);
}
}
以eclipse中的junite运行这一单元测试。即可一路跑绿,查看数据库完成插入操作。
小结:
核心为spring-hibernate.xml,利用spring的依赖注入的特性。不用单独配置hibernate的配置文件(hibernate.cfg.xml和hibernate.properties)。其他部分见代码吧!如果单独都能各自都能理解,则看上面代码不会有什么太大障碍。
spring和tapestry结合部分:
相关代码(代码存放位置):
前提当然是建立web project,才能使tapestry发挥其作用,才能完整此例子的练习。这里我只是在tomcat下建立deploy并且简单测试了一下:
Web.xml:(这个文件我想大家都知道放在哪里吧。呵呵)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<!-- generated by Spindle, http://spindle.sourceforge.net -->
<web-app>
<display-name>together</display-name>
<!-- Redirect it to the servlet mapping address /h-->
<!--
<filter>
<filter-name>redirect</filter-name>
<filter-class>org.apache.tapestry.RedirectFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>redirect</filter-name>
<url-pattern>/</url-pattern>
</filter-mapping>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/springandtapestry.xml</param-value>
</context-param>
<servlet>
<servlet-name>context</servlet-name>
<servlet-class>
org.springframework.web.context.ContextLoaderServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>together</servlet-name>
<servlet-class>
org.apache.tapestry.ApplicationServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>together</servlet-name>
<url-pattern>/app</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>15</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>Home.html</welcome-file>
</welcome-file-list>
</web-app>
Springandtapestry.xml(这个和web.xml 放在同个目录下,即web-inf目录下)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="aBean" class="yunguang.learn.springandtapestry.Bean"></bean>
</beans>
Together. application(与project同名的xml文件。这是tapestry的要求)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE application PUBLIC
"-//Apache Software Foundation//Tapestry Specification 3.0//EN"
"http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
<!-- generated by Spindle, http://spindle.sourceforge.net -->
<application name="together" engine-class="yunguang.learn.springandtapestry.MyEngine">
<description>
add a description
</description>
<page name="Home" specification-path="Home.page"/>
</application>
Home.html(在你的tapestry能够访问到的默认目录)
<span jwcid="$Content$">
<table width="337" border="1">
<tr align="center">
<td><span jwcid="@Insert" value="ognl:aBean.amethod" /></td>
</tr>
</table>
</span>
Home.page(与home.html同级)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE page-specification PUBLIC
"-//Apache Software Foundation//Tapestry Specification 3.0//EN"
"http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
<page-specification class="yunguang.learn.springandtapestry.Home">
<property-specification name="aBean" type="yunguang.learn.springandtapestry.IBean">
global.appContext.getBean("aBean")
</property-specification>
</page-specification>
相关类文件:
package yunguang.learn.springandtapestry;
public interface IBean {
public String getAmethod();
}
package yunguang.learn.springandtapestry;
public class Bean implements IBean {
public String getAmethod() {
// do something;
System.out
.println("================================================test a amethod=============================================");
return "===================test===========================";
}
}
package yunguang.learn.springandtapestry;
public class Global {
}
package yunguang.learn.springandtapestry;
import java.util.Map;
import org.apache.tapestry.engine.BaseEngine;
import org.apache.tapestry.request.RequestContext;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
public class MyEngine extends BaseEngine {
public static final String APPLICATION_CONTEXT_KEY = "appContext";
protected void setupForRequest(RequestContext context) {
super.setupForRequest(context);
Map global = (Map) getGlobal();
ApplicationContext ac = (ApplicationContext) global
.get(APPLICATION_CONTEXT_KEY);
if (ac == null) {
ac = WebApplicationContextUtils.getWebApplicationContext(context
.getServlet().getServletContext());
System.out.println("测试" + ac); global.put(APPLICATION_CONTEXT_KEY, ac);
}
}
}
package yunguang.learn.springandtapestry;
import org.apache.tapestry.event.PageEvent;
import org.apache.tapestry.event.PageRenderListener;
import org.apache.tapestry.html.BasePage;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
public abstract class Home extends BasePage implements PageRenderListener {
public abstract IBean getABean();
/** 当页面表现之前,首先运行这个方法 */
public void pageBeginRender(PageEvent event) {
WebApplicationContext appContext = WebApplicationContextUtils
.getWebApplicationContext(getRequestCycle().getRequestContext()
.getServlet().getServletContext());
IBean bean = (IBean) appContext.getBean("aBean");
//bean.getAmethod();
}
}
小结:
核心在于利用engine部分,通过定义map的global。然后在home.page中可以进行通过global.appContext.getBean("aBean")对home.java中abstract属性进行赋值。
另外:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/springandtapestry.xml</param-value>
</context-param>
这部分是个小小重点!如果把此xml文件改成spring默认的xml文件,则不需要此配置参数过程。
一个小疑惑是:在home.html中"ognl:aBean.Amethod"中的amethod中的a大小写都可以。我觉得应该小写a是正确的,但是错误的写成大写A了居然也可以正常显示。还是看看tapestry源代码吧。以后再写了!
希望本文对你有所帮助。至于其中原理,我想可以通过breakpoint方式一步一步跟下去就明白了。
当然完成本文例子需要有基本的spring、hibernate、tapestry知识。而高手们就不要见笑了。就当看看笑话吧!
其实距离真正结合还差一步,因为并没有通过tapestry作为view,而spring作为主体框架,实现hibernate的对象持久。逻辑清了,下面也就不难了。GOOD LUCK!
欢迎讨论!yun15291li@hotmail.com