一、本节重点:
1、ioc控制反转
2、di依赖注入
1、spring的介绍
1)spring理解:
spring是一个对象的容器,专门来管理对象。
spring是一站式轻量级的框架,一站式具体表现在spring自己可以实现表现层、业务层、持久层分层功能。
2)spring有三大经典的思想,分别是"IOC"、"DI"、"AOP"(面试笔试必问)
2、IOC(inversion of controller)控制反转
1)IOC的理解
Student st=new Student("",18);
现在,一个对象的创建和整个生命周期的维护都交给了spring,
通过配置文件或者注解的方式来解决对象的产生
2)IOC入门案例体会
(1)ioc底层实现原理(反射+工厂模式)
(2)ioc实现的步骤
第一步:导入基本的jar(beans,context,core,expression,日志包)
第二步:在src目录下创建spring创建bean的配置文件(引入约束,配置bean)
第三步:使用ClassPathXmlApplicationContext测试,从spring中获取bean
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
User user=(User)context.getBean("user");
3)spring创建bean的三种方式(重点掌握无参构造来实例化对象)
(1)无参构造(默认,实际开发中使用该方法)
(2)静态工厂类,静态工厂方法
(3)普通工厂类,普通实例工厂方法
<bean id="该bean取个名字等同于name属性" class="类的完整路径" scope="singleton/prototype...."></bean>
3、DI(dependency injection)依赖注入
1)DI的理解(对象的成员变量初始化)
给bean的成员变量初始化,该成员变量可以是一个普通的类型,也可以是一个引用类型变量。
2)DI实现的3种方式
(1)set方法注入(最常用)
在Bean所在类中提供成员变量的set方法
在Spring的配置文件中使用<property name="" value=""/>
(2)有参构造注入
在Bean所在类中提供成员变量的有参构造
在spring的配置文件中使用<constructor-arg name="" value=""/>
<bean id="person" class="cn.itheima.di.Person">
<property name="name" value="朱俊" />
<constructor-arg ref="car1"></constructor-arg>
</bean>
(3)使用set方法注入对象、集合、数组、properties数据
a.<property name="" ref=""></property> 将已经声明的对象可以通过ref属性引入
b.<property><list name=""><value></value></list></property> 注入数组或者list
c.<property><map name=""><entry key="" value=""></entry></map></property> 注入map
d.<property><props name=""><prop></prop></props></property> 注入properties属性
数组:在CollectionDemo里面private Object[] objectArray; 提供get/set方法
在applicationContext.xml中配置与list一样
取值:objectArray[2]
3)使用场景:如果该类中成员变量需要通过配置文件静态设置参数可以,使用注入的方法进行初始化
如:配置jdbc中的数据源可以设置数据库连接账号密码等属性;(在开发中非常常见)
如:一些类"关联"了其他对象,可以通过依赖注入的set方法,ref=""(在开发中非常常见)
注意:ref=""往往需要将已经交给spring管理的bean进行引用
4)spel:spring的表达式
#{person.age}
#{person.getAge()}
====================================================================================================================================
1、注解开发实现ioc以及DI注入(重点掌握)
1)注解实现ioc
需要导入aop的包,并在xml中将context的命名空间加入
<context:component-scan base-package="cn.itheima"/> (每一个人必须会说)扫描包下所有带有组件注解的类
@Component后面衍生为@Controller(web) @Service(service) @Repository(dao) 表明当前类是组件类
2)注解实现di
@Value("张三") 直接给普通类型去赋值,掌握,后面会结合properties文件来使用
@Autowired 首先是按照类型去寻找 (可以放在成员变量,也可以放在方法)
@Autowired+@Qualifier= @Resource
@Autowired 首先按照类型去找,没有找到就按照名称
@Resource 首先按照名称去找,没有找到就按照类型
注意:使用注解实现di的时候,引用类型也要交给spring管理
3)其他注解(了解)
@Scope("singleton/prototype...")等价于<bean id class scope=""/>
@PostConstruct等价于<bean init-method=""/> 定义的init-method方法 (要求掌握,因为该注解在做一些初始化数据的时候有用,一些项目中用到了)
@PreDestroy销毁,注意bean的scope=singleton
4)spring和junit4集成的测试(掌握,企业中开发写的controller+service+dao层代码都需要自己单独写测试,才能提交代码)
@RunWith(SpringJUnit4ClassRunner.class)// spring整合junit4
@ContextConfiguration(locations = "classpath:applicationContext.xml")
5)在web.xml配置了(ssh整合的时候,我们需要再次回顾体会,现在讲解该知识点只是做铺垫)
<listener>ContextLoaderListener</listener> <context-param>spring的配置文件的地址</context-param>
在容器启动的时候,就加载spring的配置文件
创建所有声明的bean,并完成bean的初始化
将所有创建完的bean放到ServletContext
controller/service/dao,去取bean的时候,就是从spring容器中去取
注意:记住这里的ContextLoaderListener翻译成中文就是上下文加载监听器
6)通过xml和注解能不能混合使用?是可以的
1、aop面向切面编程介绍
增强类 目标类
A {
a(公共的逻辑)
b(业务逻辑)
c(公共的逻辑)
}
当一个方法中执行需要先后执行a,b,c逻辑的时候,我们能不能把a,c逻辑放在一个类中,
给其他类共用?能不能动态组合a+b+c逻辑,这就是面向切面编程思想的来源
底层使用动态代理:jdk和cglib,目标对象有接口,优先采用jdk,没有接口则采用cglib
1)jdk实现动态代理(基于接口实现代理对象)
2)cglib实现动态代理(基于继承父类而实现代理对象,代理对象继承目标对象)
一个类,有接口,优先jdk,无接口,cglib
2、aop各种概念介绍
1)核心概念:(掌握)
(1)目标类(target): 要被增强的类
(2)代理类(proxy): 使用动态代理产生目标类的代理
(3)切入点(pointcut):目标类中需要增强的方法,这些方法都称为切入点
(4)通知(advice): 增强类中定义的方法,这些方法用于增强目标方法
(5)切面(aspect): 切入点+通知
2)其他概念:(理解)
(1)连接点(joinpoint):目标类中的所有方法
(2)织入(weaving): 将通知方法加到目标方法中的过程 spring aop整个过程就是织入
(3)引入(introduction): 在目标类引入新的属性或者新的方法 了解一下就行
3、aop之aspectj各种通知(理解)
前置通知 before 目标方法被调用之前,就执行该前置通知方法
后置(最终)通知 after 目标方法被调用完之后,不关心返回结果,就执行该后置通知方法,也叫最终通知
返回通知 after-returning 目标方法return返回之后,就执行该返回通知方法
环绕通知 around 包裹了目标方法,在目标方法之前和在目标方法之后整个过程,经常使用ProceedJoinPoint.proceed()来执行目标方法
异常通知 after-throwing 当目标方法在执行异常的时候,就会执行该异常通知方法
4、通过xml实现spring aop
1)spring传统方式实现aop编程(<aop:advisor>还沿用了传统的方式,这里只做了解)
<aop:config>
<aop:pointcut expression="execution(* cn.itheima.aop.IOrderService.*(..))"
id="orderServicePointCut" />
<aop:advisor advice-ref="orderServiceAdvice" pointcut-ref="orderServicePointCut" />
</aop:config>
2)spring基于aspectj实现aop编程(重点掌握,今天晚上需要敲代码做实验)
<aop:config>
<aop:aspect> //切面
<aop:pointcut></aop:pointcut> //切入点
<aop:after></aop:after> //后置通知
<aop:before></aop:before>//前置通知
<aop:around></aop:around>//环绕通知
<aop:after-throwing></aop:after-throwing> //异常通知
<aop:after-returning></aop:after-returning>//返回通知
</aop:aspect>
</aop:config>
3)切入点表达式,execution(表达式)
表达式完整格式:访问修饰符 返回类型 包.类.方法(方法参数) 注意这里的访问修饰符可省略
* *.*(..) 匹配所有类所有方法 (第一个*代表返回类型)
* *(..) 匹配所有类所有方法
* cn.itcast.User.*(..) 匹配User类下面的所有方法
* cn.itcast..*.*(..) 匹配itcast包下所有子包下的所有方法
实际开发中,根据情况改变切入点表达式的包和方法
4)补充说明applicationContext.xml中<import>标签使用(掌握,实际开发过程中会将配置分门别类进行配置,然后通过import标签引入)
<import resource=""/> 引入到唯一的一个配置文件中
分模块开发配置,这样好处就是分门别类,减少耦合性,如下面的配置文件
applicationContext-jdbc.xml 定义jdbc连接信息
applicationContext-beans.xml 定义申明的bean
applicationContext-redis.xml 定义声明redis连接信息
====================================================================================================================================
本节重点:
1、AOP注解编程
2、使用jdbcTemplate实现crud
1、通过注解实现spring aop(重点掌握)
1)打开aop注解开关
<context:component-scan base-package="cn.itheima" />
<aop:aspectj-autoproxy /> aop切面自动代理
2)声明切面类、各种通知
@Component
@Aspect 声明切面类,注意该切面类需要被spring当成component来管理
@Pointcut("execution(* .s(..))") 声明切入点,可以在一个空的方法上声明切入点,然后在其他通知中直接写入空的方法
public void aa(){}
@Before("aa()") 前置通知
@After("aa()") 后置通知,无论出现异常是否,都会调用该通知
@AfterReturning("aa()") 返回通知(企业开发中用的比较多)
@AfterThrowing("aa()") 异常通知
@Around("aa()") 环绕通知(企业开发中用的比较多)
3)2个代表目标方法对象
JoinPoint :获取当前目标类目标方法的所有信息(当前目标类,方法名,方法中的参数)
Object[] objs = joinPoint.getArgs();
ProceedingJoinPoint:只是在环绕通知中使用,它代表了正在执行的目标方法
关于讨论:环绕通知和前置通知以及最终通知的执行顺序,没有价值
2、spring配置连接池(会配)
1)spring内置连接池配置org.springframework.jdbc.datasource.DriverManagerDataSource(了解)
2)spring和c3p0的ComboPooledDataSource配置(掌握)
企业开发中,一般都是把连接数据库的配置放在一个属性文件上,然后引入
两种引入方式:
<context:property-placeholder location="classpath:db.properties"/>
或者
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>classpath:db.properties</value>
</property>
</bean>
<!-- 配置c3p0连接池 --> 通过${}读取属性文件上的配置
<bean id="c3p0DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClass}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
3、jdbcTemplate crud操作(重点,要求掌握)
1)需要配置数据源(dataSource)
无论是从C3P0中获取数据源还是从DHCP获取数据源,一般采取的做法是:让spring当成component来管理
2)使用jdbcTemplate核心对象操作数据库
由于JdbcTemplate在实际开发中,经常会使用,所以我们一般会让spring 去管理JdbcTemplate
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
所以,在dao层,我们可以直接从成员变量中拿到JdbcTemplate对象,然后做crud操作
jdbcTemplate.execute()
添加:jdbcTemplate.update("insert into .. values...")
修改:jdbcTemplate.update("update xx set ")
删除:jdbcTemplate.update("delete from..")
查询:jdbcTemplate.query()/queryForObject()
注意:一些接口如RowMapper(需要重点研究一下),如:
BeanPropertyRowMapper,
PreparedStatementSetter,PreparedStatementCreator等可以课下自己扩展一下,
实际开发中RowMapper用得更多。(启发大家培养自学能力)
4、转账案例的一些问题
注意:JdbcTemplate需要对内部的datasource成员变量进行初始化,
所以JdbcTemplate在交给spring管理时需要首先得提供datasource实现类
转账案例中涉及到几个问题:
1)JdbcDaoSupport
该类就是辅助类,帮助我们的dao层类来完成数据的访问,例如可以获取JdbcTemplate
2)我们能够直接向JdbcDaoSupport中直接注入datasource吗?
org.springframework.jdbc.core.support.JdbcDaoSupport 是一个抽象类,是不能直接被spring利用无参构造来实例化
解决该问题的思路:
如果不能直接,我们通过继承该抽象类来完成实例化工作,通过向子类初始化达到向父类初始化。
向子类初始化成员DriverManagerDataSource或者ComboPooledDataSource
=======================================================================================================================
回顾:
aop编程4种方式:
第一种:最传统的spring aop编程
applicationContext.xml配置目标对象 普通类,里面有方法 连接点,有可能称为切入点
配置通知 实现接口
配置切点 写方法、正则 ".*Order"
配置切面 advice-ref="" pointcut-ref=""
代理类:目标类、切面、指定接口决定用哪种代理方式 jdk、cglib
第二种:传统的spring aop+aspectj的execution表达式写法
applicationContext.xml配置目标对象
配置通知 实现接口 def
<aop:config> //自动生成代理对象
//切入点
<aop:pointcut id="abc" expression="execution(* cn.itcast.service.OrderServiceImpl.*(..))">
//切面
<aop:advisor advice-ref="def" pointcut-ref="abc">
</aop:config>
第三种:整合aspectj框架完成aop编程(重要)
applicationContext.xml配置目标对象
配置通知,不需要实现任何接口
<aop:config> //自动生成代理对象
<aop:aspect ref="通知"> //配置切面
//切点
<aop:pointcut id="" expression="" />
//通知
<aop:before></aop:before>
<aop:after></aop:after>
<aop:around></aop:around>
<aop:after-returning></aop:after-returning>
<aop:after-throwing></aop:after-throwing>
</aop:aspect>
</aop:config>
第四种:注解完成aop编程(重要)
目标对象A
@Service
public class A {
public E a(C c,D d,F f) {
...
return new E();
}
}
切面类
@Component
@Aspect
public class B{
@Before //前置通知
public void a(JoinPoint jp) {
}
@AfterReturning //返回通知
public void b(JoinPoint jp,Object obj) {
Object[] objs = jp.getArgs(); //可以拿到目标类方法的参数
obj是目标类方法的返回值
}
@Around //环绕通知
public void c() {
}
@AfterThrowing //异常通知
public void d() {
}
@After //后置通知/最终通知
public void e() {
}
}
applicationContext.xml配置
//扫描类上的注解 @Controller @Service @Repository @Component
<context:component-scan base-package="cn.itcast" />
//开启自动代理
<aop:aspectj-autoproxy />
jdbcTemplate开发环境
导包 c3p0 mysql驱动包 spring-tx spring-jdbc...
applicationContext.xml上c3p0连接池ComboPooledDataSource、jdbcTemplate需要注入dataSource
代码中使用
jdbcTemplate.execute();
jdbcTemplate.update();
jdbcTemplate.query(); /jdbcTemplate.queryForObject(); RowMapper
本节重点:
1、声明式事务的配置
2、ssh框架整合
1.spring事务管理机制(声明式事务,理解)
(1)事务管理器,可以选择相关的平台(jdbc、hibernate、jpa)
org.springframework.transaction.PlatformTransactionManager
包括下面这些:
org.springframework.jdbc.datasource.DataSourceTransactionManager 主要针对于JdbcTemplate、Mybatis开发
org.springframework.orm.jpa.JpaTransactionManager主要针对于JPA开发
HibernateTransactionManager主要针对于Hibernate开发
(2)定义事务的一些特性:隔离、传播、超时、只读
org.springframework.transaction.TransactionDefinition(可通过docs\javadoc-api/index.html查看)
隔离:
ISOLATION_DEFAULT (spring默认采用)
ISOLATION_READ_COMMITTED
ISOLATION_REPEATABLE_READ
与hibernate讲到的事务隔离级别类似
2 Read Committed 是oracle默认的隔离级别
4 Repeatable Read 是mysql默认的隔离级别
传播:
两个被事务管理的方法互相调用问题,它与数据库无关,是程序内部维护的问题
PROPAGATION_REQUIRED(spring默认值) 两个操作处于同一个事务,如果之前没有事务,新建一个事务
PROPAGATION_REQUIRES_NEW 两个操作处于不同的事务
PROPAGATION_NESTED 它是一种嵌套事务,只对DataSourceTransactionManager起作用
a方法和b方法都在事务的管理当中,a方法调用b方法
a设置为propagation="REQUIRED",b设置为propagation="REQUIRED",a和b在同一个事务里面
a和b要么同时成功,要么同时失败
a设置为propagation="REQUIRED",b设置为propagation="REQUIRES_NEW",a和b不在同一个事务里面
a和b互不影响
a设置为propagation="REQUIRED",b设置为propagation="NESTED",a所在事务嵌套了b事务,用到了保存点机制
a可以影响b,但b不能影响a
保存点:记录出错的方法,便于回滚该方法,默认不开启
(3)事务的状态
org.springframework.transaction.TransactionStatus
2.spring事务管理(2种方式来配置事务,重点掌握)
xml方式:
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 第二步: 配置事务通知 -->
<tx:advice id="txadvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 匹配增强的方法匹配规则 -->
<tx:method name="delete*"/>
<tx:method name="save*"/>
<tx:method name="create*"/>
<tx:method name="update*"/>
</tx:attributes>// propagation、read-only,isolation等属性都是事务默认属性值,可以不用花时间在上面
</tx:advice>
<!-- 第三步: 配置切入点和切面 -->
<aop:config>
<!-- 切入点 -->
<aop:pointcut expression="execution(* cn.itcast.tx.BookService.*(..))" id="pointcut1"/>
<!-- 通知引入 -->
<aop:advisor advice-ref="txadvice" pointcut-ref="pointcut1"/>
</aop:config>
注解方式:
<!-- 第一步: 配置事务管理器:主要要注入数据源 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 第二步: 开启事务注解开关:主要是声明事务管理器-->
<tx:annotation-driven transaction-manager="transactionManager"/>
第三步: 在service层类或方法上@Transactional
实际开发中,经常要改变可能就是切入点表达式,或者通知属性加上指定的方法
3.依赖注入的总结
(1)xml注入
<bean id="b" class="cn.itheima.test.di2.B"/>
<bean id="a" class="cn.itheima.test.di2.A">
<property name="b" ref="b"></property>
</bean>
private B b; 并且提供对应的set方法
(2)注解注入
<bean id="b" class="cn.itheima.test.di2.B"/>
<bean id="a" class="cn.itheima.test.di2.A"></bean>
@Autowired
private B b; //此时无需set方法
xml配置同上,不在属性上加注解,在方法上加
private B b;
@Autowired
public void setB(B b) { //方法名可以随便写
this.b = b;
}
总结:不管是在xml中配置,还是注解,A对象要注入B对象,底层都是调用set方法,给B设置值
我们自己提供了set方法,就用我们的;如果用注解,不用提供set方法,框架会帮我们生成set方法
<bean id="accountDao" class="cn.itheima.dao.AccountDAOImpl">
<!-- 当注入dataSource后,底层会自动创建一个JdbcTemplate -->
<property name="dataSource" ref="c3p0DataSource" />
</bean>
<bean id="userDao" class="cn.itheima.dao.UserDAOImpl">
<!-- 当注入sessionFactory后,底层会自动创建一个HibernateTemplate -->
<property name="sessionFactory" ref="sessionFactory" />
</bean>
-----------------------------ssh框架整合过程(xml方式)--------------------------------
ssh框架整合的准备工作:
导入struts2、hibernate、spring及相关jar包
web.xml、struts.xml、applicationContext.xml、db.properties、log4j.properties
hibernate.cfg.xml不需要了
1.spring整合hibernate原理+事务配置
第一步:配置数据源ComboPooledDataSource,引入外部属性文件db.properties
第二步:创建LocalSessionFactoryBean来管理hibernate中的SessionFactory
<bean id="sessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
注入连接池
注入hibernate的属性
加载hibernate映射文件XXX.hbm.xml
</bean>
第三步:编写dao层并配置
UserDAOImpl extends HibernateDaoSupport implements IUserDAO
<bean id="userDao" class="cn.itheima.dao.UserDAOImpl">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
第四步:编写service层并配置,以及事务配置
<bean id="userService" class="cn.itheima.service.UserServiceImpl">
<property name="userDao" ref="userDao" />
</bean>
<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="find" read-only="true"/>
<tx:method name="add"/>
<tx:method name="update"/>
<tx:method name="del"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut expression="execution( cn.itheima.service...(..))" id="mypointcut"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="mypointcut"/>
</aop:config>
2.spring整合struts2原理及其配置
第一步:Action类的编写
第二步:struts.xml配置
第三步:jsp页面编写
第四步:web.xml上配置spring的上下文加载监听,struts的核心过滤器
需要注意的问题:
(1)spring管理action,是通过这个jar包:struts2-spring-plugin-2.3.24.jar
(2)把Action配置在applicationContext.xml上<bean id="userAction" class="cn.itheima.action.UserAction" scope="prototype">
需要注意两个问题:
第一:scope="prototype",因为Action是多例的,每请求一次就创建一次
第二:struts.xml上的class与id对应<action name="user_*" class="userAction">
(3)不管在不在applicationContext.xml上配置Action,都是由spring来管理Action对象
(4)Action对象需要注入service层对象,可以持有service层对象的引用,并提供set方法
private IUserService userService;
public void setUserService(IUserService userService) {
this.userService = userService;
}
===============================================================================================================================
回顾:
ssh整合xml配置方式:
1.spring整合hibernate
第一步:数据库相关:db.properties c3p0数据源连接池 id="c3p0DataSource"
第二步:spring管理了hibernate的sessionFactory对象
<bean id="sessionFactory1" class="xxx.LocalSessionFactoryBean">
// 1.数据源连接池
<property name="dataSource" ref="c3p0DataSource" />
// 2.hibernate.cfg.xml相关属性
<property name="hibernateProperties" >
<value>
hibernate.show_sql=true
方言...
</value>
</property>
// 3.实体类映射文件
<property name="mappingResources">
<list>
<value>cn/itcast/domain/User.hbm.xml</value>
</list>
</property>
</bean>
2.spring声明式事务(xml配置实现,注解实现)
//1.平台事务管理器
<bean id="transactionManager" class="xxx.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory1" />
</bean>
//2.事务通知,本质是一种环绕通知
<tx:advice id="txAdvice" transaction-manager="transactionManager" >
<tx:attributes>
<tx:method name="add*" />
<tx:method name="delete*" />
<tx:method name="update*" />
<tx:method name="select*" /> //这里的方法名字与下面的切入点的方法名要对应
</tx:attributes>
</tx:advice>
//3.切面
<aop:config>
<aop:pointcut id="myPointcut" expression="execution(* cn.itcast.service.UserServiceImpl.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="myPointcut" />
</aop:config>
注解配置声明式事务,只需要把这里的通知和切面去掉,换成如下:
<tx:annotation-driven transaction-manager="transactionManager">
service层的类上面加上@Transactional
为什么要有事务?
因为dao层针对数据库做操作,只能是一个一个做。增/删/改/查
实际开发经常要做一组操作,一组操作,就叫做事务,这样的事务都是加在业务层,
就算不是一组操作,有时候也需要回滚,也需要事务。
3.spring整合struts2
有一个包非常重要:struts2-spring-plugin...jar
web.xml配置struts2的核心过滤器,spring的上下文加载监听
创建Action类
struts.xml
页面addUser.jsp
注意:Action类持有service层的引用,提供set方法
private IUserService userService;
public void setUserService() {
}
Action类不需要配置在applicationContext.xml上
-----------------------------ssh框架整合过程(注解方式 重点掌握)-----------------------------
注解方式实现ssh整合
第一步:建web项目,导jar包
在xml方式的基础上,多加一个包:struts2-convention-plugin-2.3.24.jar
hibernate.cfg.xml不需要了,struts.xml可要可不要
第二步:web.xml配置spring的上下文监听,struts的核心过滤器
第三步:配置applicationContext.xml(web.xml需要加载applicationContext.xml)
整合hibernate
1.数据库相关 db.properties c3p0数据源
2.sessionFactory交给spring管理,配置LocalSessionFactoryBean
(1)关联dataSource
(2)hibernate属性 hibernate.show_sql=true
(3)加载实体类 PO 与数据库表对应
声明式事务
1.事务管理器
<bean id="transactionManager" class="xxx.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
2.开启注解驱动
<tx:annotation-driven transaction-manager="transactionManager">
// 开启注解扫描 @Controller @Service @Repository @Component
<context:component-scan base-package="cn.itcast" />
第四步:包结构,写代码
cn.itcast.dao 面向接口编程,有接口,有实现类
cn.itcast.service 面向接口编程,有接口,有实现类
cn.itcast.action
cn.itcast.domain 实体类上使用JPA注解,实体类映射文件也不需要
cn.itcast.utils
@Repository("userDao")
public class UserDAOImpl extends HibernateDaoSupport implements IUserDAO {
// 注入sessionFactory
@Autowired
@Qualifier("sessionFactory")
public void setSuperSessionFactory(SessionFactory factory) {
super.setSessionFactory(factory);
}
}
@Service
@Transactional
class UserServiceImpl implements IUserServcie {
@Autowired
private IUserDao userDao;
}
@Controller
@Scope("prototype")
@Namespace("/")
@ParentPackage("struts-default") json-default
public class UserAction {
@Autowired
private IUserService userService;
<package>
<action name="" class="'>
</package>
@Action(value = "user_add", results = { @Result(name = "success", location = "/success.jsp") })
public String add() {
return "success";
}
}
Action编写注意点:
action类所在包中包含action/actions/struts/struts2之一
action的类命名上必须以Action后缀或者该Action类上实现 com.opensymphony.xwork2.Action接口
在struts2-convention-plugin-xxx.jar可以找到
<constant name="struts.convention.package.locators" value="action,actions,struts,struts2"/>
<constant name="struts.convention.action.suffix" value="Action"/>
配置jsp页面
ssh学习需要把握
1.思路理清楚
2.每一步需要哪几个东西需要知道
3.互相的依赖关系