spring的使用-ssh整合

ssh整合-xml方式:

1.需要记住的三个jar包:

spring-web-4.2.4.RELEASE.jar           ---保证项目启动时就实例化spring配置的对象(通过一个servletContext监听器ContextLoaderListener实现),保证整个项目只有一个工厂。

struts2-spring-plugin-2.3.24.jar ---解决了struts2和spring的整合问题,将struts2中的action交给spring创建

spring-orm-4.2.4.RELEASE .jar          ---解决hibernate和spring的整合,将sessionfactory交给spring创建(通过一个FactoryBean接口实现类实现),并且hibernate的事务也由spring事务管理器管理

2.FactoryBean接口      //对象工厂,可以存入对象。这个接口中的方法有getObject(); getObjectType(); ...这两个方法获取对象和对象class

如果让一个类实现这个接口,然后将这个类交给spring管理(在applicationContext.xml中配置这个bean),如:

<bean id="car" class="...CarFactoryBean"></bean>

那么在获取bean对象时:

a. 如果通过applicationContext对象调用getBean();获取:

ac.getBean("car");

此时,底层发现CarFactoryBean实现了FactoryBean接口,就会调用其中getObject();方法获取到这个类中的对象

b. 如果通过ac.getBean(Car.class);这种方式获取bean:

那么,会调用CarFactoryBean中的getObjectType();如果发现这个方法返回的是Car.class,则会接下来调用getObject()获取对象;

注意:

@autowire           //这种方式是在spring容器中找到Car或其实现类实现注入的,相当于调用ac.getBean(Car.class);获取,因此使用FactoryBean获取时要重写getObjectType();

private Car car;

3.spring的hibernate整合,配置文件             //原理:通过factoryBean方式让spring来管理sessionFactory

方式一:LocalSessionFactoryBean注入configLocation方式        //LocalSessionFactoryBean实现了FactoryBean和initialize

<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">

<property name="configLocation" value="classpath:hibernate.cfg.xml"></property>         //这个属性传入的是hibernate配置文件类路径

</bean>

原理:   1. 实例化LocalSessionFactoryBean时会注入configLocation,

2. 由于LocalSessionFactoryBean底层实现了initialize,会调用初始化方法,根据配置文件路径加载和解析hibernate.cfg.xml配置文件,并创建SessionFactory对象

3. 在获取sessionFactory时会调用getObject();方法获取

缺点:依然需要hibernate.cfg.xml文件

方式二:配置LocalSessionFactoryBean,注入hibernate.cfg.xml中的连接池、属性等           //不再需要hibernate.cfg.xml文件

<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">    //配置LocalSessionFactoryBean

<property name="dataSource" ref="dataSource"></property>   //需要注入连接池

<property name="hibernateProperties">                                    //注入其他属性,hibernateProperties底层为properties集合

<value>

hibernate.show_sql=true

hibernate.format_sql=true

hibernate.dialect=org.hibernate.dialect.MySQLDialect

hibernate.hbm2ddl.auto=update

</value>

</property>

<property name="hibernateProperties">        //也可通过这种方式注入其他属性

<props>

<prop key="hibernate.show_sql">true</prop>

</props>

<property>

<property name="mappingDirectoryLocations" value="classpath:cn/itheima/domain"></property>      //配置映射文件(xxx.hbm.xml)路径,四种方式

<property name="mappingLocations" value="classpath:cn/itheima/domain/User.hbm.xml"></property>

<property name="mappingResources" value="cn/itheima/domain/User.hbm.xml"></property>

<property name="mappingJarLocations"></property>

</bean>

4.spring的hibernate整合,Dao的操作:

让Dao继承HibernateDaoSupport,只需要注入SessionFactory就可以获得HibernateTemplate      //这里的HibernateDaoSupport类似于JdbcDaoSurport,封装了HibernateTemplate

<bean id="userDao" class="cn.itheima.dao.UserDaoImpl">

<property name="sessionFactory" ref="sessionFactory"/>    //dao中注入sessionFactory

</bean>

使用hibernateTemplate实现增删改查    //底层通过session实现,得到的是getCurrentSession();    事务默认为只读

this.getHibernateTemplate().save(user)                                 //底层调用session.save(user)

this.getHibernateTemplate().update(user)                      //底层调用session.update(user)

this.getHibernateTemplate().del(user)                            //底层调用session.del(user)

this.getHibernateTemplate().get(User.class,id)                //底层调用session.get(User.class,id)

this.getHibernateTemplate().find("hql",arg1,arg2...) //底层调用session.createQrery("hql").serParameter(...).list();

原理:

配置文件加载时创建userDao,同时注入sessionFactory,sessionFactory注入时,会直接创建HibernateTemplate对象

因此,userDao可以直接调用父类的getHibernateTemplate()来获取HibernateTemplate实现增删改查

增删改查的实现在底层均通过hibernate中的session对象实现。为getCurrentSession();得到与线程绑定的session

注意:未添加事务时有默认事务,且事务的默认为readonly,即默认只能查,不能增删改。

总结:spring整合hibernate主要包括两个方面:

1)将sessionFactory交给spring管理 //两种方式,均由spring来加载配置文件,创建sessionFactoryBean

2)dao层使用hibernateTemplate实现增删改查    //dao继承HibernateDaoSupport,注入sessionFactory实现

5.spring的hibernate整合,事务管理:

采用HibernateTransactionManager事务管理器,注入sessionFactory,其他操作(配置通知切面,<tx:advice> <aop:config>)同day3中的spring自身事务的操作:

<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">

<property name="sessionFactory" ref="sessionFactory"></property>

</bean>

总结:基于spring自身提供的事务管理模式,只是采用的事务管理器不同

6.Spring整合struts2框架  //必须导入jar包struts2-spring-plugin-2.3.24.jar,这个jar包改变了创建Action的方式

原理:

struts2框架配置文件加载顺序

a.    default.properties

b.    struts-default.xml

c.     struts -plugin.xm

在导入的jar包中有一个plugin的配置文件,加载时会覆盖struts2中的一个常量struts.objectFactory为spring

struts2框架默认通过ObjectFactory创建对象,由于上述常量值的改变。bean的创建由spring对象工厂SpringObjectFactory来管理

SpringObjectFactory创建对象主要方法:

public Object buildBean(String beanName, Map<String, Object> extraContext, boolean injectInternal) throws Exception {

Object o;

//这个beanName是struts2框架传入的,对应struts.xml中的class属性

//把beanName作为id判断Spring容器是否有这个id对应的bean

if (appContext.containsBean(beanName)) {

//如果找到了就直接从Spring容器获取

o = appContext.getBean(beanName);

} else {

//如果没有从Spring容器找到该id对应bean,

//就把beanName作为全类名通过反射创建对象并且注入属性

Class beanClazz = getClassInstance(beanName);

o = buildBean(beanClazz, extraContext);

}

return o;

}

总结:struts2-spring-plugin-2.3.24.jar改变了struts中action的创建方式,将action创建交给spring管理

方式一:基于spring管理action :伪类名     //在applicationContext.xml文件中来声明action

1. 在applicationContext中配置action:

<bean id="userAction" class="cn.itheima.action.UserAction" scope="prototype">       //此处必须设置scope的属性为prototype,否则每次请求获取到的是同一个action

<property name="userService" ref="userService"/> //service的注入,必须在action中提供对应的set方法

</bean>

2. 在struts.xml中配置,将class 值修改为伪类名

<package name="default" extends="struts-default">

<action name="user_add" class="userAction" method="add">    //此处class不再是全类名,而是对应了applicationContext中的id

<result name="...">...</result>

</action>

</package>

原理:

当请求发出时,spring会根据class 的值,在applicationContext.xml中查找是否有对应的id,有则直接从applicationContext容器中获取对象

方式二:自动注入service

struts.xml中的class 直接用全类名,只需要在action中提供service的set方法

<action name="user_add" class="cn.itheima.action.UserAction" method="add">   //此处class是全类名

<result name="...">...</result>

</action>

public void UserAction extends ActionSupport{

private IUserService userService;

public void setUserService(IUserService us){     //会根据set方法的名称在applicationContext.xml中查找对应的id(userService),并注入bean

this.userService=us;

}

}

struts.objectFactory.spring.autoWire常量的配置:

<constant name="struts.objectFactory.spring.autoWire" value="type"/>    //默认值为name

默认情况下,根据action中的set方法名称,查找applicationContext.xml对应id并实现属性注入,

常量值修改为type后,会根据set方法的参数类型,在applicationContext.xml中根据这个类型查找其实现类对象并注入属性

原理:

与伪类名方式执行流程相同,会根据class属性的值,在applicationContext.xml中查找是否有对应的id,此时,找不到对应的id,会根据这个全类名创建对象,并将对象放入spring容器,

同时,根据类中的set方法注入对应的属性

总结:   本质上是将action交给spring管理,两种方式

  补充:

    <context:component-scan>和<context:annotation-config>的区别:

    <context:component-scan>      //注解扫描,做了两件事,扫描注解,创建对象放入spring容器中,让注解生效

    <context:annotation-config>    //使注解生效,与注解扫描的区别?

ssh整合,注解的使用

1.实体类的注解:

1)实体类注解配置:

@Entity

@Table(name="t_user")

public class User {

@Id

@GeneratedValue(strategy=GenerationType.IDENTITY)

private int id;

private String name;

private int age;

2)applicationContext.xml中实体类的引入:

<property name="packagesToScan" value="cn.itheima.domain"></property> //与之前引入hbm.xml文件不同,在sessionFactory中注入packagesToScan,指定实体类所在的包

2.dao的注解配置:

applicationContext.xml中开启注解扫描:

<context:component-scan base-package="cn.itheima"></context:component-scan>

dao的注解配置:

@Repository

public class UserDaoImpl extends HibernateDaoSupport implements IUserDAO {

@Autowired

public void setSf(SessionFactory sf){          //将sessionFactory注入父类,前提:applicationContext.xml中配置LocalSessionFactoryBean

super.setSessionFactory(sf);

}

3.service的注解配置,事务的添加

1)service注解配置:

@Service              //注解方式配置UserServiceImpl

public class UserServiceImpl implements IUserService{

@Autowired         //注入dao

private IUserDAO userDao;

2)事务管理的实现:

A.applicationContext.xml:

<bean id="tm" class="org.springframework.orm.hibernate5.HibernateTransactionManager">   //配置事务管理器

<property name="sessionFactory" ref="sessionFactory"></property> //要注入sessionFactory

</bean>

<tx:annotation-driven transaction-manager="tm"/>            //配置注解驱动,需要传入事务管理器

B.类上或方法上加事务管理注解:

@Transactional

public class UserServiceImpl implements IUserService{

4.action的注解配置: //采用的是全类名方式完成整合

只需要在配置好struts中的配置的基础上,在private IUserService userService;加上@Autowired即可

@ParentPackage("struts-default")

public class UserAction extends ActionSupport implements ModelDriven<User>{

private User user=new User();

@Autowired         //只需要添加这个注解即可

private IUserService userService;

@Override

public User getModel() {

return user;

}

@Action(value="user_add",results={@Result(name="success",location="/success.jsp")})         //在此处其实有一个className属性,相当于配置文件中的class,默认为UserAction全类名

public String add(){

userService.add(user);

return SUCCESS;

}

}

原理:   请求发出时,spring会代替struts2创建action对象(根据xml中的class属性值或者注解中@Action中的className属性),有一下两种方式

A.默认的全类名方式: //className属性取默认值

由于@Action中的className默认值为UserAction全类名,因此spring会根据这个全类名,创建UserAction对象并交给spring容器管理,同时根据类型注入userService。

因此在spring容器中必须有userService对象存在,即在applicationContext中必须配置这个对象

B.让程序以伪类名方式创建: //麻烦,不建议使用    //设置className属性

1)设置@Action中的className属性为userAction。此时,会根据这个名称,在applicationContext中获取对象,因此需手动将userAction交给spring容器管理:

2)在UserAction类上配置注解,实现action由spring创建并管理:

@Component      //默认的id为userAction

@Scope("prototype")          //必须配置这个属性

public class UserAction extends ActionSupport implements ModelDriven<User>{

5.no session 的问题:配置一个filter

问题产生的原因:默认情况下,session是在dao层通过getCurrentSession();获取到,这个session在service层事务关闭时会自动关闭。

当在dao层进行延迟查询时,不会马上从数据库查询数据。当要使用这些数据时,会再action层获取,此时会使用到session,由于session在service已经关闭,会出现no session异常

<filter>         //必须放在struts2过滤器之前

<filter-name>openSessionInView</filter-name>

<filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class>

</filter>

<filter-mapping>

<filter-name>openSessionInView</filter-name>

<url-pattern> /* </url-pattern>              // */

</filter-mapping>

原理:

请求发出时,会先被这个过滤器拦截,在这个过滤器中,会从spring容器中获取到sessionFactory,并调用openSession()获取session这个session会被放到sessionHolder中,被dao拿到。

这个过滤器走完后会执行struts2过滤器,以及action。service,dao层的操作,此时在service层执行完,事务提交时不会再关闭session,而是再action执行完后由过滤器关闭session

如果请求为action请求,struts2过滤器不会放行,因此必须把openSessionInView过滤器放在struts2过滤器之前

//sturts 会拦截url,不会拦截uri(指定某个网络资源)

原文地址:https://www.cnblogs.com/liuxuelin/p/9973735.html

时间: 2024-08-08 20:25:22

spring的使用-ssh整合的相关文章

Spring(八)SSH整合简述

一.Spring与Struts2的整合 1.1.整合步骤 1.2.配置web.xml 1.3.配置spring配置文件applicationContext.xml 1.4.配置struts配置文件 1.5.Action继承ActionSupport类 二.spring与hibernate整合 2.1.步骤 2.2.注入sessionFactory <--数据源--> <bean id="dataSource" class="org.springframewo

SSH整合(二)——利用Spring来装配Action类

在上篇文章(SSH整合(一)--直接获取ApplicationContext)中,在Action类中通过获取ApplicationContext对象,调用getBean方法来实例化bean类,这种方法将Action类与Spring的绑定装配JavaBean绑定的过紧,大大增加了他们的耦合度.如果装配文件的内容有变化,很可能要修改Action类的代码. 所以我们将装配Action类及其属性的方法也放到Spring中. 一,由Spring创建Action对象 例如,action代码如下: packa

SSH整合 第四篇 Spring的IoC和AOP

这篇主要是在整合Hibernate后,测试IoC和AOP的应用. 1.工程目录(SRC) 2.IoC 1).一个Service测试类 1 /* 2 * 加入spring容器 3 */ 4 private ApplicationContext applicationContext = 5 6 new ClassPathXmlApplicationContext("classpath:spring/applicationContext.xml"); 7 public static void

Struts2 convention插件试用+ Spring+Hibernate SSH整合

第一步,引入struts2-convention-plugin-2.2.1.jar 然后,改动配置文件. 我是在struts.properties文件里改动的: struts.objectFactory = spring struts.devMode = true struts.i18n.encoding = UTF-8 struts.convention.result.path =/WEB-INF/jsp/ struts.convention.package.locators = action

【j2ee spring】12、整合SSH框架(终结版)

[j2ee spring]12.整合SSH框架(终结版) 最后,我们把整个项目的截图,代码发一下,大家不想下载那个项目的话,可以在这里看到所有的代码(因为那个项目需要一个下载积分,真不多= =,我觉得我搞了那么久,收点积分应该不过分吧...嘿嘿) 这里,我尽量用截图来搞,免得复制粘贴,怪烦的 一.项目整体截图 二.开始全部代码 Person.java Person.hbm.xml PersonService.java package cn.cutter_point.service; import

框架 day37 Spring事务管理,整合web,SSH整合,SSH整合注解

1     事务管理 1.1   回顾事务     事务:一组业务操作,要么全部成功,要么全部不成功.     事务特性:ACID 原子性:整体 一致性:数据(完整) 隔离性:并发(多个事务) 持久性:结果     隔离问题:脏读.不可重复读.幻读(虚读)     隔离级别:4个 readuncommitted 读未提交,存在3个问题. readcommitted 读已提交,解决:脏读:存在2个. repeatableread 可重复读,解决:脏读.不可重复读:存在1个 serializ

ssh整合思想初步 structs2 Spring Hibernate三大框架各自要点

Web层用Structs2的action Service层用Spring的IoC和aop以及JdbcTemplate或者Transaction事务(创建对象及维护对象间的关系) Dao层用Hibernate的crude操作 看上去是Structs2和Spring(把Structs2的action交给Spring整合,action处理表单,通常都是多实例用Spring <bean id="" class="" scope="prototype"

SSH整合基础

1.Spring整合Hibernate 整合步骤 导包 配置appliactionContext.xml 创建实体类和映射关系文件 创建DAO接口及实现类 声明DAO组件,注入SessionFactory 2.Spring整合Struts2 导包 配置web.xml 配置applicationContext.xml,开启注解扫描 创建并声明Action 配置Action 创建JSP 3.整合的基本原理 Struts原本使用StrutsObjectFactory来读取struts.xml,根据ac

ssh整合

1.三大框架的整合原理: spring与struts2整合就是将action对象交给spring容器负责创建 spring与hibernate整合就是将sessionFatory交给spring来维护 2.导包 hibernate 持久化规范 数据库驱动 struts2 struts2整合spring需要的插件包 这个插件包一旦导入,那么struts2在启动时就会自动寻找spring容器,找不到就抛出异常 spring的基本包: core|beans|context|expression|log