Struts2+Spring+Hibernate配置文件形式整合

596 阅读5分钟

Struts2+Spring+Hibernate配置文件形式整合

@新手学习

一. 导入jar包

  • 1.1 struts2的包,po图:
  • 1.2 spring的jar包,po图:
  • 1.3 hibernate的jar包(使用的hibernate5的版本),po图:

PS:未使用注解的方式,所以没有将注解整合的jar包。

2. 在web.xml中的配置

  • 2.1 struts2的核心过滤器配置
<!-- struts2的核心过滤器 -->
  <filter>
  	<filter-name>struts2</filter-name>
  	<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter>
  <filter-mapping>
  	<filter-name>struts2</filter-name>
  	<url-pattern>/*</url-pattern>
  </filter-mapping>
  • 2.2 在web.xml中spring的配置文件加载方式
    原因:当请求进入到对应action中时,需要通过new ClassPathXmlApplicationContext这个对象来加载spring的配置文件,每次都会耗费很多资源,所以spring给出了一个解决方案,通过在web.xml配置ContextLoaderListener这个监听器类,一次性将xml加载到内存中,这样可以避免多次的加载配置文件。
    web.xml代码:
 <listener>
  	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <!-- 因为这个类是默认加载的WEB-INF目录下的配置文件,所以需要更改加载路径 .才能拿到注入的对象-->
  <context-param>
  	<param-name>contextConfigLocation</param-name>
  	<param-value>classpath:spring.xml</param-value>
  </context-param>

具体action代码:

/* 每次进入action都会去加载配置文件 */
ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
	CustomerService customerService = (CustomerService) ac.getBean("customerService");
	customerService.save(customer);

优化过后的重构代码:

/* 使用spring提供的类,简化获取对象的过程,提高效率 */
	WebApplicationContext web = WebApplicationContextUtils.getWebApplicationContext(ServletActionContext.getServletContext());
	    CustomerService customerService = (CustomerService) web.getBean("customerService");
	    customerService.save(customer);

2. 配置文件的编写

  • Struts2的配置文件:
    PS:这种方式是由struts来管理action对象。
<struts>
	<constant name="struts.devMode" value="true" />
	<constant name="struts.enable.DynamicMethodInvocation" value="true" />
        <package name="base" namespace="/customer" extends="struts-default">
        <!-- 通配符练习 -->
        <action name="save" class="cn.eudask.web.action">
            <result>/success.jsp</result>
        </action>
    </package>
</struts>
  • spring的配置文件(完全抛弃掉hibernate.cfg.xml文件,但是映射文件还需要):
  1. 配置c3p0连接池(数据源)
<!-- 将hibernate的环境交给spring管理 -->
	<!-- 配置一个数据源 -->
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
		<property name="jdbcUrl" value="jdbc:mysql:///spring?characterEncoding=utf-8"></property>
		<property name="user" value="root"></property>
		<property name="password" value="root"></property>
	</bean>
  1. 配置hibernate的相关属性:
<!-- 给sessionFactory 注入一个hibernate的配置文件 -->
	<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
		<property name="dataSource" ref="dataSource"></property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
				<prop key="hibernate.show_sql">true</prop>
				<prop key="hibernate.format_sql">true</prop>
				<prop key="hibernate.hbm2ddl.auto">update</prop>
			</props>
		</property>
		<!-- 配置文件映射的方式 -->
		<property name="mappingResources">
			<list>
				<value>cn/eduask/domain/customer.hbm.xml</value>
			</list>
		</property>
	</bean>
  • PS:如果是mysql 5.0的数据库版本,需要将方言配置为MySQL5InnoDBDialect,指定版本是5的。
  • LocalSessionFactoryBean:这个类是spring提供的在web包中的用于整合hibernate的类,里面包含了SessionFactory的属性。
  1. HibernateTemplate需要一个LocalSessionFactoryBean对象,通过源码可以看出,HibernateTemplate是可以通过setter方法注入SessionFactory对象,使对象拥有这个实例的。所以,在DAO层需要提供HibernateTemplate的setter方法,便可以获得HibernateTemplate对象。
  • HibernateTemplate源码:
//源码中定义的一个SessionFactory类型变量
private SessionFactory sessionFactory;

       /**
	 * Set the Hibernate SessionFactory that should be used to create
	 * Hibernate Sessions.
	 * 通过setter方法给sessionFactory变量注入的对象。
	 */
	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}
  1. 还需要将事务交给spring处理,使用spring提供的HibernateTransactionManager,针对于hibernate的事务管理器。配置了事务后才能拥有读写权限。
<!-- 配置事务管理器 -->
	<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory"></property>
	</bean>
	<!-- 配置事务通知 -->
	<!-- <tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="*" isolation="DEFAULT" propagation="REQUIRED"/>
		</tx:attributes>
	</tx:advice> -->
	<!-- 配置事务切面 -->
	<!-- <aop:config>
		<aop:pointcut expression="execution(* cn.eduask.service.impl.CustomerServiceImpl.*(..))" id="pt"/>
		<aop:advisor advice-ref="txAdvice" pointcut-ref="pt"/>
	</aop:config> -->
  1. DAO层中的java测试代码
        private HibernateTemplate backHibernateTemplate;
	public void setBackHibernateTemplate(HibernateTemplate backHibernateTemplate) {
		this.backHibernateTemplate = backHibernateTemplate;
	}
	
	@Override
	public void save(Customer cust) {
		backHibernateTemplate.save(cust);
	}
  1. web层中的action的java测试代码
/* 由struts2管理action對象注入service层对象的方式 */
	/*private CustomerService customerService;
	public void setCustomerService(CustomerService customerService) {
		this.customerService = customerService;
	}*/
	//对象还是由struts管理

这样就基本完成了SSH的配置。
缺陷:虽然这样可以跑通,但是action的对象还是由struts在管理,这样只是完成了单向的整合,所以经过优化,将action的对象也交由spring管理

将Action对象的管理交给spring管理的方式

导入spring提供的整合struts的插件jar包

  1. spring.xml的更改。将Action的对象放进SpringIOC中。然后将service对象注入到action中。
<bean id="customerAction" class="cn.eduask.web.action.CustomerAction" scope="prototype">
		<property name="custService" ref="customerService"></property>
	</bean>

PS:scope:由于一个用户的请求是多种的,所以action的对象也不可以是单例的,默认是single单例的,需要修改为多例的prototype多例属性。

2. struts.xml的更改。

<struts>
	<constant name="struts.devMode" value="true" />
	<constant name="struts.enable.DynamicMethodInvocation" value="true" />
        <package name="base" namespace="/customer" extends="struts-default">
        <!-- class就需要对应bean的ID -->
        <action name="save" class="customerAction">
            <result>/success.jsp</result>
        </action>
    </package>
</struts>
  1. java测试代码:
/* 开发中推荐使用。使用spring來管理action對象 */
private CustomerService custService;
	public void setCustService(CustomerService custService) {
		this.custService = custService;
	}

这样action的对象也完成了优化。