课程内容
1. 面向接口(抽象)编程的概念与好处
2. IOC/DI的概念与好处
a) inversion of control
b) dependency injection
3. AOP的概念与好处
4. Spring简介
5. Spring应用IOC/DI(重要)
a) xml
b) annotation
6. Spring应用AOP(重要)
a) xml
b) annotation
7. Struts2.1.6 +Spring2.5.6 + Hibernate3.3.2整合(重要)
a) opensessionInviewfilter(记住,解决什么问题,怎么解决)
8. Spring JDBC
面向接口编程(面向抽象编程)
1. 场景:用户添加
2. Spring_0100_AbstractOrientedProgramming
a) 不是AOP:Aspect Oriented Programming
3. 好处:灵活
什么是IOC(DI),有什么好处
1. 把自己new的东西改为由容器提供
a) 初始化具体值
b) 装配
2. 好处:灵活装配
Spring简介
1. 项目名称:Spring_0200_IOC_Introduction
2. 环境搭建
a) 只用IOC
i.spring.jar , jarkata-commons/commons-loggin.jar
3. IOC容器
a) 实例化具体bean
b) 动态装配
4. AOP支持
a) 安全检查
b) 管理transaction
Spring IOC配置与应用
1. FAQ:不给提示:
a) window – preferences – myeclipse – xml – xml catalog
b) User Specified Entries – add
i.Location: D:\share\0900_Spring\soft\spring-framework-2.5.6\dist\resources\spring-beans-2.5.xsd
ii.URI: file:///D:/share/0900_Spring/soft/spring-framework-2.5.6/dist/resources/spring-beans-2.5.xsd
iii.KeyType: Schema Location
iv.Key: http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
2. 注入类型
a) Spring_0300_IOC_Injection_Type
b) setter(重要)
c) 构造方法(可以忘记)
d)接口注入(可以忘记)
3. id vs. name
a) Spring_0400_IOC_Id_Name
b) name可以用特殊字符
4. 简单属性的注入
a) Spring_0500_IOC_SimpleProperty
b)
5. a) Spring_0600_IOC_Bean_Scope b) singleton 单例 c) proptotype 每次创建新的对象 6. 集合注入 a) Spring_0700_IOC_Collections b) 很少用,不重要!参考程序 7. 自动装配 a) Spring_0800_IOC_AutoWire b) byName c) byType d) 如果所有的bean都用同一种,可以使用beans的属性:default-autowire 8. 生命周期 a) Spring_0900_IOC_Life_Cycle b) lazy-init (不重要) c) init-method destroy-methd 不要和prototype一起用(了解) 9. Annotation第一步: a) 修改xml文件,参考文档<context:annotation-config/> 10. @Autowired a) 默认按类型by type b) 如果想用byName,使用@Qulifier c) 写在private field(第三种注入形式)(不建议,破坏封装) d) 如果写在set上,@qualifier需要写在参数上 11. @Resource(重要) a) 加入:j2ee/common-annotations.jar b) 默认按名称,名称找不到,按类型 c) 可以指定特定名称 d) 推荐使用 e) 不足:如果没有源码,就无法运用annotation,只能使用xml 12. @Component @Service @Controller @Repository a) 初始化的名字默认为类名首字母小写 b) 可以指定初始化bean的名字 13. @Scope 14. @PostConstruct = init-method; @PreDestroy = destroy-method; 1. 面向切面编程Aspect-Oriented-Programming a) 是对面向对象的思维方式的有力补充 2. Spring_1400_AOP_Introduction 3. 好处:可以动态的添加和删除在切面上的逻辑而不影响原来的执行代码 a) Filter b) Struts2的interceptor 4. 概念: a)JoinPoint 释意:切面与原方法交接点 即 切入点 b) PointCut 释意:切入点集合 c) Aspect(切面)释意:可理解为代理类前说明 d) Advice 释意:可理解为代理方法前说明例如@Before e) Target 释意:被代理对象 被织入对象 f) Weave 释意:织入 1. 两种方式: a) 使用Annotation b) 使用xml 2. Annotation a) 加上对应的xsd文件spring-aop.xsd b) beans.xml <aop:aspectj-autoproxy/> c) 此时就可以解析对应的Annotation了 d) 建立我们的拦截类 e) 用@Aspect注解这个类 f) 建立处理方法 g) 用@Before来注解方法 h) 写明白切入点(execution …….) i) 让spring对我们的拦截器类进行管理@Component 3. 常见的Annotation: a) @Pointcut 切入点声明以供其他方法使用 , 例子如下: @Aspect @Component public class LogInterceptor { @Pointcut("execution(public * com.bjsxt.dao..*.*(..))") public void myMethod(){} @Around("myMethod()") public voidbefore(ProceedingJoinPoint pjp) throws Throwable{ System.out.println("method before"); pjp.proceed(); } @AfterReturning("myMethod()") public void afterReturning() throws Throwable{ System.out.println("method afterReturning"); } @After("myMethod()") public void afterFinily() throws Throwable{ System.out.println("method end"); } } b) @Before 发放执行之前织入 c) @AfterReturning 方法正常执行完返回之后织入(无异常) d) @AfterThrowing 方法抛出异常后织入 e) @After 类似异常的finally f) @Around 环绕 类似filter , 如需继续往下执行则需要像filter中执行FilterChain.doFilter(..)对象一样 执行 ProceedingJoinPoint.proceed()方可,例子如下: @Around("execution(* com.bjsxt.dao..*.*(..))") public voidbefore(ProceedingJoinPoint pjp) throws Throwable{ System.out.println("method start"); pjp.proceed();//类似FilterChain.doFilter(..)告诉jvm继续向下执行 } 4. 织入点语法 a) void !void b) 参考文档(* ..) 如果execution(* com.bjsxt.dao..*.*(..))中声明的方法不是接口实现则无法使用AOP实现动态代理,此时可引入包” cglib-nodep-2.1_3.jar” 后有spring自动将普通类在jvm中编译为接口实现类,从而打到可正常使用AOP的目的. 5. xml配置AOP a) 把interceptor对象初始化 b) i. 1. 2. 例子: <beanid="logInterceptor"class="com.bjsxt.aop.LogInterceptor">bean> <aop:config>
<aop:aspectid="point" ref="logInterceptor">
<aop:pointcut expression= "execution(public* com.bjsxt.service..*.*(..))" id="myMethod"/>
<aop:beforemethod="before"pointcut-ref="myMethod"/>
<aop:aroundmethod="around"pointcut-ref="myMethod"/>
<aop:after-returningmethod="afterReturning" pointcut-ref="myMethod"/>
<aop:after-throwingmethod="afterThrowing" pointcut-ref="myMethod"/>
<aop:aftermethod="afterFinily" pointcut="execution(public* om.bjsxt.service..*.*(..))"/> aop:aspect> aop:config> 1. Spring 指定datasource a) 参考文档,找dbcp.BasicDataSource i.c3p0 ii.dbcp iii.proxool b) 在DAO或者Service中注入dataSource c) 在Spring中可以使用PropertyPlaceHolderConfigure来读取Properties文件的内容 2. Spring整合Hibernate a) i. ii. b) 引入hibernate 系列jar包 c) User上加Annotation d) UserDAO或者UserServie 注入SessionFactory e) jar包问题一个一个解决 3. 声明式的事务管理 a) 事务加在DAO层还是Service层?Service层(多个dao操作时?) b) annotation i.加入annotation.xsd ii.加入txManager bean iii. 例如: 什么是AOP
Spring AOP配置与应用
Spring整合Hibernate
iv.在需要事务的方法上加:@Transactional
v.需要注意,Hibernate获得session时要使用SessionFactory.getCurrentSession不能使用OpenSession
c) @Transactional详解
i.什么时候rollback
1. 运行期异常,非运行期异常不会触发rollback
2. 必须uncheck (没有catch)
3. 不管什么异常,只要你catch了,spring就会放弃管理
4. 事务传播特性:propagation_required
例如:@Transactional(propagation=Propagation.REQUIRED)等同于(@Transactional)
作用,一个方法声明了@Transactional事务后,其内再调用的方法不需要再声明@Transactional.
5. read_only
例如:@Transactional(propagation=Propagation.REQUIRED,readOnly=true)
当方法声明readOnly=true时,该方法及其调用的方法内都不执行insert update等
d) xml(推荐,可以同时配置好多方法)
i. ii. 1. 2. iii. iv. 例如: class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
expression="execution(public* com.bjsxt.service..*.*(..))"
id="myServiceMethod"/>
e) HibernateTemplate、HibernateCallback、HibernateDaoSupport(不重要)介绍
i.设计模式:TemplateMethod(模板方法)
ii.Callback:回调/钩子函数
iii.第一种:(建议)
1. 在spring中初始化HibernateTemplate,注入sessionFactory
class="org.springframework.orm.hibernate3.HibernateTemplate">
2. DAO里注入HibernateTemplate
private HibernateTemplate hibernateTemplate;
@Resource
public void setHibernateTemplate(HibernateTemplatehibernateTemplate) {
this.hibernateTemplate= hibernateTemplate;
}
3. save写getHibernateTemplate.save();
public void save(TestUser testUser) {
hibernateTemplate.save(testUser);
}
iv.第二种:
1. 从HibernateDaoSupport继承(此方法不好用可忽略)
2. 必须写在xml文件中,无法使用Annotation,因为set方法在父类中,而且是final的
例如:
首先,新建SuperDAOImpl类(使用Annotation注入--@Component):
@Component
public class SuperDAOImpl {
privateHibernateTemplate hibernateTemplate; //此处定义由spring注入管理
publicHibernateTemplate getHibernateTemplate() {
returnhibernateTemplate;
}
@Resource
public voidsetHibernateTemplate(HibernateTemplate hibernateTemplate) {
this.hibernateTemplate= hibernateTemplate;
}
}
此时,xml中必须要有:
class="org.springframework.orm.hibernate3.HibernateTemplate">
或者,SuperDAOImpl类写成下面代码:
@Component
public class SuperDAOImpl extends HibernateDaoSupport {
@Resource(name="sessionFactory")
public voidsetSuperHibernateTemplate(SessionFactory sessionFactory) {
super.setSessionFactory(sessionFactory);
}
}
对应的xml中则可省略
只要包含
最后,其他类继承SuperDaoImpl类后便可直接使用HibernateTemplate
@Component("u")
public class UserDAOImpl extends SuperDAOImpl implementsUserDAO {
public voidsave(TestUser testUser) {
this.getHibernateTemplate().save(testUser);
}
}
第3种方法:就是用继承,所有的DAO extends superDAO ,而superDAO里面注入了HibernateTemplate .....用的时候注意的是,子类和父类都用同样的方法,xml或是annotataion
spring整合hibernate的时候使用packagesToScan属性,可以让spring自动扫描对应包下面的实体类
Struts2.1.6 +Spring2.5.6 + Hibernate3.3.2
1. 需要的jar包列表
jar包名称 |
所在位置 |
说明 |
antlr-2.7.6.jar |
hibernate/lib/required |
解析HQL |
aspectjrt |
spring/lib/aspectj |
AOP |
aspectjweaver |
.. |
AOP |
cglib-nodep-2.1_3.jar |
spring/lib/cglib |
代理,二进制增强 |
common-annotations.jar |
spring/lib/j2ee |
@Resource |
commons-collections-3.1.jar |
hibernate/lib/required |
集合框架 |
commons-fileupload-1.2.1.jar |
struts/lib |
struts |
commons-io-1.3.2 |
struts/lib |
struts |
commons-logging-1.1.1 |
单独下载,删除1.0.4(struts/lib) |
struts spring |
dom4j-1.6.1.jar |
hibernate/required |
解析xml |
ejb3-persistence |
hibernate-annotation/lib |
@Entity |
freemarker-2.3.13 |
struts/lib |
struts |
hibernate3.jar |
hibernate |
|
hibernate-annotations |
hibernate-annotation/ |
|
hibernate-common-annotations |
hibernate-annotation/lib |
|
javassist-3.9.0.GA.jar |
hiberante/lib/required |
hibernate |
jta-1.1.jar |
.. |
hibernate transaction |
junit4.5 |
||
mysql- |
||
ognl-2.6.11.jar |
struts/lib |
|
slf4j-api-1.5.8.jar |
hibernate/lib/required |
hibernate-log |
slf4j-nop-1.5.8.jar |
hibernate/lib/required |
|
spring.jar |
spring/dist |
|
struts2-core-2.1.6.jar |
struts/lib |
|
xwork-2.1.2.jar |
struts/lib |
struts2 |
commons-dbcp |
spring/lib/jarkata-commons |
|
commons-pool.jar |
.. |
|
struts2-spring-plugin-2.1.6.jar |
struts/lib |
2. BestPractice:
a) 将这些所有的jar包保存到一个位置,使用的时候直接copy
3. 步骤
a) 加入jar包
b) 首先整合Spring + Hibernate
i.建立对应的package
1. dao / dao.impl / model / service / service.impl/ test
ii.建立对应的接口与类框架
1. S2SH_01
iii.建立spring的配置文件(建议自己保留一份经常使用的配置文件,以后用到的时候直接copy改)
iv.建立数据库
v.加入Hibernate注解
1. 在实体类上加相应注解@Entity @Id等
在字段属性的get方法上加--@Column(name = "表字段名")
2. 在beans配置文件配置对应的实体类,使之受管
vi.写dao service的实现
vii.加入Spring注解
1. 在对应Service及DAO实现中加入@Component,让spring对其初始化
2. 在Service上加入@Transactional或者使用xml方式(此处建议后者,因为更简单)
3. 在DAO中注入sessionFactory
4. 在Service中注入DAO
5. 写DAO与Service的实现
viii.写测试
c) 整合Struts2
i.结合点:Struts2的Action由Spring产生
ii.步骤:
1. 修改web.xml加入 struts的filter
如下:
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
2. 再加入spring的listener,这样的话,webapp一旦启动,spring容器就初始化了
如下:
org.springframework.web.context.ContextLoaderListener
classpath*:spring/*applicationContext.xml
3. 规划struts的action和jsp展现
4. 加入struts.xml
a)修改配置,由spring替代struts产生Action对象
5. 修改action配置
a)把类名改为bean对象的名称,这个时候就可以使用首字母小写了
b)@Scope(“prototype”)不要忘记
iii.struts的读常量:
1. struts-default.xml
2. struts-plugin.xml
3. struts.xml
4. struts.properties
5. web.xml
iv.中文问题:
1. Struts2.1.8已经修正,只需要改i18n.encoding = gbk
2. 使用spring的characterencoding
例:
org.springframework.web.filter.CharacterEncodingFilter
3. 需要严格注意filter的顺序
4. 需要加到Struts2的filter前面
v.LazyInitializationException
1. OpenSessionInViewFilter
2. 需要严格顺序问题
3. 需要加到struts2的filter前面
附:
1.
@Autowired 与@Resource都可以用来装配bean. 都可以写在属性定义上,或写在set方法上
@Autowired (srping提供的)默认按类型装配
@Resource ( j2ee提供的 )默认按名称装配,当找不到(不写name属性)名称匹配的bean再按类型装配.
可以通过@Resource(name="beanName")指定被注入的bean的名称,要是指定了name属性,就用字段名去做name属性值,一般不用写name属性.
@Resource(name="beanName")指定了name属性,按名称注入但没找到bean,就不会再按类型装配了.
@Autowired 与@Resource可作用在属性定义上,就不用写set方法了(此方法不提倡);
2.
a.
Action类前加@Component,则Action可由spring来管理,例子如下:
Action中写:
@Component("u") //spring管理注解
@Scope("prototype") //多态
public class UserAction extends ActionSupportimplements ModelDriven{
//内部属性需要有get/set方法且需要set方法前加@Resource或@Autowired
}
Struts2配置文件中写
Jsp中
b.
Action中也可不加@Component,Action由struts2-spring-plugin管理。此时,如果Action中定义的属性有set方法则@Autowired与@Resource也可不写,但是如果没有set方法,则需要在属性前加上@Autowired或@Resource才能生效。
3.
Hibernate如果使用load来查询数据,例如:
Service中:
public User loadById(int id) {
returnthis.userDao.loadById(id);
}
DAO中:
public User loadById(int id) {
return(User)this.hibernateTemplate.load(User.class, id);
}
此时,session(应该说的是Hibernate的session)在事物结束(通常是service调用完)后自动关闭。由于使用的是load获取数据,在jsp页面申请取得数据时才真正的执行sql,而此时session已经关闭,故报错。
Session关闭解决方法:
在web.xml中增加filter—openSessionInView,用于延长session在jsp调用完后再关闭
如下所示:
注意:filter–openSessionInView一定要在 filter—struts2之前调用
Filter顺序—先进后出!
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
跨数据的事务管理用jta不用hibernate,用了hibernate的事务管理之后,就不需要使用try catchfinally来对异常捕获回滚
Action及其set属性有struts.xml自动装配,如果struts.xml里的action的class属性设为spring里bean的id属性值,则struts.xml不会自动装配action及其set属性,而是由spring来装配,还有struts.xml来装配action是通过属性的名字来装配的。
Spring自动化测试 opensessioninviewIntercepter