----------------------------------------------------------------------------------------------
[版权申明:本文系作者原创,转载请注明出处] 
文章出处:http://blog.csdn.net/sdksdk0/article/details/52471101
作者:朱培      ID:sdksdk0      邮箱: zhupei@tianfang1314.cn   
--------------------------------------------------------------------------------------------

本文主要分享的是spring的基础,常用配置,都是非常重要的内容,理论+实践,文末配有案例源码下载链接。spring是开发javaee查询非常重要的一个框架,可以为后续使用springMVC打下良好的基础,其实主要的就是一些配置文件,需要哪些jar包,我们应该如何去配置,本文都有非常详细的阐述。通过使用spring整合hibernate、struts整合spring来做的SSH框架也是非常经典的一个开发模式,作为开发者都应该努力把这一部分的内容掌握,当然了,对于配置文件也不需要你一个个类的去背下来,只要记得去哪里找到这个类的配置,知道这个类有哪些方法是我们可以用的就好。同时对于不同的版本有的类方法的使用也是存在稍许差异的,学会多总结,多运用,多思考。

简介

什么是:Spring

Spring是一个分层的JavaSE/EE full-stack(一站式) 轻量级开源框架。 轻量级:依赖其他内容教小,使用资源消耗也少。 核心:控制反转Ioc和面向切面AOP。 spring生成的东西叫做bean.

spring是J2EE应用程序框架,是轻量级的IoC和AOP的容器框架,主要是针对javaBean的生命周期进行管理的轻量级容器。Spring包含7大模块,每个模块可以单独使用、也可以结合起来使用;但是在实际开发过程中,一般需要结合Struts、Hibernate来使用。

体系结构

核心组件:beans、core、context、expression

第一个实例

loc控制反转 1、导入jar包 2、spring核心配置文件 3、使用api获得对象实例

DI依赖注入

一个类中使用了另一个类,就称为两个类存在依赖关系。从spring获得service实现类(ioc),spring自动将dao的实现类注入给service。

service提供setter方法。

BeanFactory和ApplicationContext

采用延迟加载,当第一次调用getBean方法时初始化,Application在加载完成配置文件之后进行初始化。

装配bean基于xml

bean的三种实例化方式

1、使用默认构造

<!-- 创建dao -->
<bean id="bookDaoId" class="cn.tf.demo2.BookDaoImpl"></bean>
<!-- 创建service -->
<bean id="bookServiceId" class="cn.tf.demo2.BookServiceImpl">
<!-- 使用property来完成注入,name表示当前属性名称,ref表示配置文件中另一个bean的引用 -->
<property name="bookDao" ref="bookDaoId"></property>
</bean>

2、静态工厂 public class MyFactory {

    public static PersonDao  createPersonDao(){
return new PersonDaoImpl();
}
}

配置文件中:

<bean id="personDaoId"   class="cn.tf.demo4.MyFactory"  factory-method="createPersonDao"></bean>

3、实例工厂 使用工厂之前需要先创建

//实例工厂
public PersonDao createPersonDao(){
return new PersonDaoImpl();
}

配置文件:

<bean id="myFactory" class="cn.tf.demo4.MyFactory"  >
</bean> <bean id="personDaoId" factory-bean="myFactory" factory-method="createPersonDao"></bean>

bean的种类

普通bean:之前使用的所有bean,一般很常用,例如service和dao等

工厂bean:spring提供接口,FactoryBean,一个特殊的bean,具有Factory工厂,用于生产特定的Bean的bean。例如:ProxyFactoryBean用于生产代理对象的一个bean。

id属性和name属性:

id可以自动提示,名称不能重复。 name如果没有配置id,name也可以使用,可以编写多个名称,使用逗号分隔。

bean的作用域

spring默认情况下创建的bean都是单例的。

取值: singleton:单例。 prototype:多例。

bean的生命周期

  1. 初始化
  2. setter 属性注入
  3. 获得配置bean名称:replyDaoId,必须实现接口:BeanNameAware
  4. 获得spring容器,相当于TestApp new ClassPath... , 必须实现接口:ApplicationContextAware --- 也可以实现接口:BeanFactoryAware
  5. 初始化之前执行
  6. 初始化前属性设置
  7. 初始化方法,需要在xml配置 <bean init-method='' >
  8. 初始化之后执行
  9. save 方法

-

<bean id="replyDaoId" class="cn.tf.demo6.ReplyDao"
init-method="replyInit"
destroy-method="replyDestory">
<property name="username" value="张三"></property>
</bean> <!-- 配置后处理bean -->
<bean class="cn.tf.demo6.MyBeanPostProcessor"></bean>

依赖注入

手工装配:使用xml:1、构造方法注入;2、setter方法注入;3、接口注入

<bean id="categoryId" class="cn.tf.demo7.a.Category">
<!-- 描述构造方法的一个参数
index:参数的索引
type:参数的类型
value:参数的值
ref:参数的值的引用对象
-->
<constructor-arg index="0" type="java.lang.String" value="123"></constructor-arg>
<constructor-arg index="1" type="java.lang.Integer" value="456"></constructor-arg>
</bean>

自动装配:框架整合时:

byType:按类型装配
byName:按名称装配
constructor按构造
auto 不确定装配。

p命名空间

简化set方法注入

setter方法:

<bean id="" class="" >
<property name="username" value="make" >
<property name="address" ref="addressId" >

p命名空间:

xmlns:p="http://www.springframework.org/schema/p"

<bean id="companyId" class="cn.tf.demo7.b.Company"  p:name="指令汇科技"  p:address-ref="addressId"></bean>
<bean id="addressId" class="cn.tf.demo7.b.Address" p:addr="湖南衡阳"></bean>

SpEL表达式

spring表达式语言。

value="#{表达式}"

<bean id="studentId" class="cn.tf.demo7.c.Student">
<property name="teacher" value="#{teacherId}"></property>
<property name="pi" value="#{T(java.lang.Math).PI}"></property>
</bean> <bean id="teacherId" class="cn.tf.demo7.c.Teacher" >
<property name="tname" value="#{'abc'.toUpperCase()}"></property>
</bean>

集合注入

常见的5种集合:

private String[] arrayData;
private List<String> listData;
private Set<String> setData;
private Map<String,String> mapData;
private Properties propsData;

配置文件中:

<bean id="collbeanId" class="cn.tf.demo7.d.CollBean">
<!-- 数组 -->
<property name="arrayData">
<array>
<value>数组1</value>
<value>数组2</value>
<value>数组3</value>
</array>
</property>
<!-- List集合 -->
<property name="listData">
<list>
<value>List集合1</value>
<value>List集合1</value>
<value>List集合1</value>
</list>
</property> <!-- Set集合 -->
<property name="setData">
<set>
<value>set集合1</value>
<value>set集合2</value>
<value>set集合3</value>
</set>
</property> <!-- map集合 -->
<property name="mapData">
<map>
<entry key="aa" value="00"></entry>
<entry>
<key><value>bb</value></key>
<value>11</value>
</entry>
</map>
</property> <!-- properties对象 -->
<property name="propsData">
<props>
<prop key="aa">00</prop>
<prop key="bb">11</prop>
</props>
</property>
</bean>

装配bean基于注解

使用注解类用于取代xml配置文件,优点在于:xml配置少,使用注解配置信息简化。不足之处在于硬编码。

@Component组件,用于取代

@Component(value = "orderDaoId")

@Repository 修饰dao层

@Service 修饰service层

Controller 修饰web层

方案1:

@AutoWired 自动注入,默认按照类型
可以修饰在字段上
也可以修饰在setter方法上
缺点:如果同一个接口,有两个实现类,就会存在冲突 @Qualifier 修改AutoWired匹配,将按照名称匹配。

方案2:

@Resource 可以完成 @AutoWired 和 @Qualifier 功能 例如:@Resource("userDaoId") 按照名称匹配

 @PostConstruct 初始化
@PreDestroy 销毁

@Scope 作用域

使用注解,必须将“被注解修饰的类”交予spring进行扫描。

<context:component-scan base-package="类所在包名">

整合junit

导入spring-test-4.2.5.RELEASE.jar

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:cn/tf/demo9/beans.xml")
public class TestApp {
@Autowired
private UserDao userDao; @Test
public void test1(){
userDao.save();
}

在classpath中加载注解文件

xml和注解混搭使用

<!-- 使 注入的注解可以使用 -->
<context:annotation-config></context:annotation-config> <!-- 所有的bean都在xml配置
所有的依赖都是注解
-->
<bean id="userDaoId" class="cn.tf.demo10.UserDaoImpl"></bean>
<bean id="userServiceId" class="cn.tf.demo10.UserServiceImpl"></bean>
<bean id="userActionId" class="cn.tf.demo10.UserAction"></bean>

AOP

面向切面编程:采用横向抽取机制,取代了传统纵向继承体系重复性代码。

AOP的应用:性能监视、事务管理、安全检查、缓存等。

target:目标类,需要被代理的类,也是需要被增强的类。

JoinPoint:连接点,需要被拦截点,spring中连接点就是方法,及目标类所有方法。 PointCut:切入点,已经被拦截的连接点,有哪些连接点需要被增强。 Advice:通知/增强,增强的内容。 Weaving:织入,用增强Advice应用目标类Target,生成代理对象过程。 proxy:代理。 aspect:切面,通知advice与切入点Point

spring AOP底层

接口+实现类:使用jdk的动态代理。

实现类:使用的是cglib(字节码增强)

字节码增强框架,不用使用接口,在运行时,动态的创建目标类的子类,目标类不能使用final。

目标类:

public class BookService {
public void addBook(){
System.out.println("cglib addBook");
} public void updateBook(){
System.out.println("cglib updateBook");
}
}

切面类:

public class MyAspect {

public void before(){
System.out.println("之前执行");
}
public void after(){
System.out.println("之后执行");
}
}

工厂:

public static Object getBean(){
final BookService bookService=new BookService();
//切面类
final MyAspect myAspect=new MyAspect();
//生成代理类。代理类是目标类的子类
//核心类
Enhancer enhancer=new Enhancer();
//确定父类
enhancer.setSuperclass(bookService.getClass());
//设置处理
enhancer.setCallback(new MethodInterceptor() { @Override
public Object intercept(Object proxy, Method method, Object[] args,
MethodProxy methodProxy) throws Throwable {
//执行目标类的方法
myAspect.before();
Object obj=method.invoke(bookService, args);
methodProxy.invokeSuper(proxy, args);
myAspect.after();
return obj;
}
});
//创建代理类
Object proxyObj=enhancer.create();
return proxyObj; }

aop通知类型

aop是一种思想,有aop联盟提出,spring对aop的规范进行支持。

5种通知: 前置通知:在目标方法执行之前实施增强。 后置通知:在执行目标后实施增强。 环绕通知:在方法执行前后实施增强。 异常抛出通知:在方法抛出异常后实施增强。 引介通知:在目标类中添加一些新的方法和属性。

spring工厂bean--半自动

切面类:需要实现接口, MethodInterceptor 环绕通知

public class MyAspect implements MethodInterceptor {

@Override
public Object invoke(MethodInvocation mi) throws Throwable {
System.out.println("前");
//执行目标方法
Object obj = mi.proceed();
System.out.println("后");
return obj;
}
}

配置文件:

<bean id="personServiceId" class="cn.tf.demo3.PersonServiceImpl"></bean>

<!-- 切面类,含通知 -->
<bean id="myAspect" class="cn.tf.demo3.MyAspect" ></bean> <!--
ProxyFactoryBean 用于生产代理类一个特殊的工厂bean
proxyInterfaces 用于确定需要实现接口
interceptorNames 用于确定通知实现类,需要提供的bean名称
target 用于确定代理类bean名称
--> <!-- 代理类 -->
<bean id="personServiceProxyId" class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 确定接口 -->
<property name="proxyInterfaces" value="cn.tf.demo3.PersonService"></property>
<!-- 确定通知 -->
<property name="interceptorNames" value="myAspect"></property>
<!-- 确定目标类 -->
<property name="target" ref="personServiceId"></property>
<!-- 强制cglib -->
<property name="optimize" value="true"></property> </bean>

AOP全自动

使用AspectJ的表达式

<!-- 切面类,含通知 -->
<bean id="myAspect" class="cn.tf.demo4.MyAspect" ></bean>
<!-- aop编程 -->
<aop:config>
<!-- 切入点 -->
<aop:pointcut expression="execution(* cn.tf.demo4.*ServiceImpl.*(..))" id="myPointCut"/>
<!-- 一个特殊的切面 ,包含一个切入点和一个通知-->
<aop:advisor advice-ref="myAspect" pointcut-ref="myPointCut"/>
</aop:config>

aspectJ切入点表达式

导入jar包: aspectJ、springaop、aop联盟规范、

1、execution

execution:匹配方法的执行 格式:execution(修饰符 返回值类型 包.类名.方法名(参数列表)throws 异常)

修饰符:public|private

返回值类型:String|void|*

包:cn.tf.service --指定包 cn.tf.pm..Service --指定模块 cn.tf.pm..service.. --表示当前目录以及子目录

类名:UserService --指定名称 *Service --以Service结尾

方法名:save --执行方法名称 add* --add开头

参数列表: () --无参 (int) --参数整形 (String,int) --两个参数 (..) --参数任意

execution(* cn.tf..service...*(..))

2、within 确定包或者子包 within(cn.tf.pm.*.service..)

3、this 匹配实现接口的代理类 this(cn.tf.pm.user.service.UserService)

4、taeget 目标类

5、args 参数列表

6、bean

通知类型

前置通知[Before advice]:在连接点前面执行,前置通知不会影响连接点的执行,除非此处抛出异常。

正常返回通知[After returning advice]:在连接点正常执行完成后执行,如果连接点抛出异常,则不会执行。

异常返回通知[After throwing advice]:在连接点抛出异常后执行。

返回通知[After (finally) advice]:在连接点执行完成后执行,不管是正常执行完成,还是抛出异常,都会执行返回通知中的内容。

环绕通知[Around advice]:环绕通知围绕在连接点前后,比如一个方法调用的前后。这是最强大的通知类型,能在方法调用前后自定义一些操作。环绕通知还需要负责决定是继续处理join point(调用ProceedingJoinPoint的proceed方法)还是中断执行。

声明通知类型

            1 前置通知 , 目标方法之前执行。
* 第一个参数为JoinPoint,可以获得目标方法名等。
<aop:before method="myBefore" pointcut-ref="myPonitCut"/>
2 后置通知,目标方法之后执行,可以获得返回值。 通过“returning”属性配置第二个参数的名称,获得返回值的,类型必须Object
* 第一个参数为:JoinPoint
* 第二个参数为:Object xxx
<aop:after-returning method="myAfterReturning" pointcut-ref="myPonitCut" returning="xxx"/>
3 环绕通知, 目标方法前后
方法要求:public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{
执行目标方法:joinPoint.proceed();
<aop:around method="myAround" pointcut-ref="myPonitCut"/>
4 抛出异常通知,目标方法出现异常时才执行。通过“throwing”属性配置第二个参数的名称,获得具体的异常信息,类型必须是Throwable
* 第一个参数为:JoinPoint
* 第二个参数为:Throwable e
<aop:after-throwing method="myAfterThrowing" pointcut-ref="myPonitCut" throwing="e"/>

切面类:

public void myBefore(JoinPoint  joinPoint){
System.out.println("前置通知"+joinPoint.getSignature().getName());
} public void myAfterReturning(JoinPoint joinPoint,Object xxx){
System.out.println("后置通知, 返回值:" + xxx);
} public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{ System.out.println("前");
//必须执行目标方法
Object obj = joinPoint.proceed(); System.out.println("后");
return obj;
} public void myAfterThrowing(JoinPoint joinPoint, Throwable e){
System.out.println("抛出异常通知, " + e.getMessage());
} public void myAfter(){
System.out.println("最终");
}

配置文件:

<aop:config>
<aop:aspect ref="myAspect">
<aop:pointcut expression="execution(* cn.tf.demo5.*.*(..))" id="myPointCut"/>
<!-- 声明通知类型 -->
<aop:before method="myBefore" pointcut-ref="myPointCut"/>
<aop:after-returning method="myAfterReturning" pointcut-ref="myPointCut" returning="xxx"/>
<aop:around method="myAround" pointcut-ref="myPointCut" />
<aop:after-throwing method="myAfterThrowing" pointcut-ref="myPointCut" throwing="e"/>
<aop:after method="myAfter" pointcut-ref="myPointCut"/> </aop:aspect>
</aop:config>

基于注解

如果使用注解进行aop开发,必须进行aspectj自动代理。

<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

通知注解:

@Before @AfterReturning @Around @AfterThrowing @After

@Component
@Aspect
public class MyAspect { @Before("myPointCut()")
public void myBefore(JoinPoint joinPoint){
System.out.println("前置通知"+joinPoint.getSignature().getName());
} @AfterReturning(value="execution(* cn.tf.demo6.*.*(..))",returning="xxx")
public void myAfterReturning(JoinPoint joinPoint,Object xxx){
System.out.println("后置通知, 返回值:" + xxx);
} @Around("myPointCut()")
public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{ System.out.println("前");
//必须执行目标方法
Object obj = joinPoint.proceed(); System.out.println("后");
return obj;
} @AfterThrowing(value="myPointCut()",throwing="e")
public void myAfterThrowing(JoinPoint joinPoint, Throwable e){
System.out.println("抛出异常通知, " + e.getMessage());
}
@After("myPointCut()")
public void myAfter(){
System.out.println("最终");
}
//用来声明切入点表达式,在通知中通过方法名来获得,相当于调用方法
@Pointcut("execution(* cn.tf.demo6.*.*(..))")
private void myPointCut(){ }
}

配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
"> <!-- bean definitions here --> <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<!-- 扫描注解 -->
<context:component-scan base-package="cn.tf.demo6"></context:component-scan>
</beans>

JDBC模板

导入spring中的jdbc,tx,c3p0,dbcp

属性文件:jdbcInfo.properties

jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql://localhost:3306/dbone
jdbc.user=zp
jdbc.password=a

在spring的配置文件中配置:

<!-- 加载properties文件 -->
<context:property-placeholder location="classpath:cn/tf/jdbc/d/jdbcInfo.properties"/> <!-- 配置数据源
如果properties文件已经被加载,可以通过 ${key}获得配置文件中内容
-->
<bean id="dataSourceId" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClass}"></property>
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean> <!-- 配置dao -->
<bean id="userDaoId" class="cn.tf.jdbc.d.UserDao">
<property name="dataSource" ref="dataSourceId"></property>
</bean>

dao的配置可以依据实际情况写。

事务管理

一组业务操作,要么全部成功,要么全部失败。

ACID:原子性、一致性、隔离型、持久性 隔离问题:脏读、不可重复读、虚读

隔离级别:读未提交、读已提交、可重复读、串行化

jdbc事务操作:
try{
//获得连接
conn=DriverManage...
//开启事务
conn.setAutoCommit(false);
savepoint=conn.setSavepoint(); conn.commit(); }catch(){
if(savepoint==null){
//回滚
conn.rollback(); }else{
conn.rollback(savepoint);
conn.commit();
} }finally{
//释放
conn.close();
}

Spring的事务

spring是基于aop进行事务管理的,导入jar包:spring-tx...

PlatformTransactionManager:平台事务管理器,spring的基本操作都必须izai事务管理器的平台上进行操作。 TransactionStatus:事务状态,用于记录事务状态,方便在事务管理器平台上,进行事务操作。 
TransactionDefinition:事务定义,事物详情说明,

核心组件详解

平台事务管理器

JDBC、Hibernate、Mybatis、JPA都具有自己的事务管理器。

导入jar包:spring-jdbc... spring-orm...

事务管理器: DataSourceTransactionManager , JDBC事务管理器 HibernateTransactionManager , hibernate 事务管理器

通过事务管理器去解析事务详情去获得事务状态,通过状态管理事务。

事务状态

是否是新的事务、是否有保存点、设置了回滚、是否回滚、是否已经完成、刷新状态同步

事务详情:

名称、是否只读、获得超时时间、隔离级别、传播行为

传播行为:

PROPAGATION_REQUIRED, required : 默认 支持当前事务,A如果已经在事务中,B将直接使用A中事务。 如果不存在创建新的,A不在事务中,B将创建新的。

PROPAGATION_SUPPORTS supports : 支持当前事务,A如果已经在事务中,B将直接使用A中事务。 使用非事务执行,A不在事务中,B将也不使用事务执行。

PROPAGATION_MANDATORY mandatory : 支持当前事务,A如果已经在事务中,B将直接使用A中事务。 如果没有事务将抛出异常,A不在事务中,B将抛异常。

PROPAGATIONREQUIRESNEW ,requires new : 创建新的。如果A没有,B将创建新的。 挂起之前的。如果A有事务,B将挂起A的事务,创建新的。

PROPAGATIONNOTSUPPORTED , not supported: B将以非事务执行,如果A已经在事务中,将A事务挂起。

PROPAGATION_NEVER ,never B将以非事务执行,如果A已经在事务中,B将抛异常。

PROPAGATION_NESTED nested : 将采用嵌套事务执行。底层使用保存点Savepoint

采用配置的方式去设置“事务详情”,spring通过事务管理器去管理事务。

案例:转账

半自动事务

使用工厂Bean生成代理、 设置事务管理代码、设置事务管理器 、设置接口、设置目标、设置事务属性(事务详情)

配置文件:

<!-- 事务管理器 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="DataSource" ref="dataSource"></property>
</bean> <!-- 代理对象,用于生产事务的代理对象 -->
<bean id="accountServiceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="txManager"></property>
<!-- 接口 -->
<property name="proxyInterfaces" value="cn.tf.service.AccountService"></property>
<!-- 目标类 -->
<property name="target" ref="accountService"></property>
<!-- 事务属性 -->
<property name="transactionAttributes">
<props>
<prop key="transfer">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>

使用AOP

<!-- 事务管理器 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean> <!-- 配置事务详情 -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<!-- <tx:method> 确定事务详情配置
name : 确定方法名称
transfer 确定名称
add* add开头
* 任意
propagation 传播行为
isolation 隔离级别
read-only="false" 是否只读
rollback-for="" 指定异常回滚(-)
no-rollback-for="" 指定异常提交(+)
经典应用:开发中规定
<tx:method name="add*"/>
<tx:method name="update*"/>
<tx:method name="delete*"/>
<tx:method name="find*" read-only="true"/> -->
<tx:method name="transfer" propagation="REQUIRED" isolation="DEFAULT" read-only="false"/>
</tx:attributes>
</tx:advice> <!-- aop,将通知应用 目标类 -->
<aop:config>
<aop:pointcut expression="execution(* cn.tf.service..*.*(..))" id="myPointcut"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="myPointcut"/>
</aop:config>

基于注解

添加注解:@Transactional,可以修饰在类或者方法上

在xml中配置事务管理器,并交由spring。

<!-- 事务管理器 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 使用注解 -->
<tx:annotation-driven transaction-manager="txManager"/>

web开发

导入jar包,spring-web...

在web.xml中配置:

<!-- 通过 servletContext 初始化参数设置xml位置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param> <!-- spring 监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

在servlet的post方法中:

//spring 加容器存在 ServletContext中, sc.setAttribute(name, object)
ServletContext sc = this.getServletContext();
ApplicationContext ac = WebApplicationContextUtils.getWebApplicationContext(sc);
UserService userService = (UserService) ac.getBean("userService");

在applicationContext.xml中

<bean id="userService"  class="cn.tf.service.UserService"></bean>

SSH整合

jar包

配置文件: applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd"> </beans>

hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="hibernate.connection.url">
jdbc:mysql://localhost:3306/dbone?useUnicode=true&amp;characterEncoding=UTF-8
</property>
<property name="hibernate.connection.username">zp</property>
<property name="hibernate.connection.password">a</property>
<property name="hibernate.dialect">
org.hibernate.dialect.MySQL5Dialect
</property> <!-- 3 sql -->
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property> <!-- 4 语句ddl -->
<property name="hibernate.hbm2ddl.auto">update</property> <!-- 5 取消bean校验 -->
<property name="javax.persistence.validation.mode">none</property> <!-- 6 绑定session -->
<property name="hibernate.current_session_context_class">
thread
</property> <!-- 添加映射 -->
<mapping resource="cn/tf/domain/User.hbm.xml" /> </session-factory>
</hibernate-configuration>

User.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="cn.tf.domain.User" table="t_user">
<id name="id">
<generator class="native"></generator>
</id>
<property name="username"></property>
<property name="password"></property>
</class>
</hibernate-mapping>

struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<!-- 开发模式 -->
<constant name="struts.devMode" value="true" />
<!-- struts标签模板 -->
<constant name="struts.ui.theme" value="simple"></constant> <package name="default" namespace="/" extends="struts-default"> </package>
</struts>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<!-- 确定xml文件位置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- spring监听器,加载xml文件 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener> <!-- struts 前端控制器 -->
<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>
</web-app>

spring整合hibernate

有cfg.xml

使用Hibernate模板

<bean  id="userService"  class="cn.tf.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao"></property>
</bean>
<bean id="userDao" class="cn.tf.dao.impl.UserDaoImpl">
<property name="hibernateTemplate" ref="hibernateTemplate"></property>
</bean> <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean> session工厂 ,特殊的bean生成SessionFactory加载配置文件
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocations" value="classpath:hibernate.cfg.xml"></property>
</bean> 事务管理
<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean> 事务详情
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="add*"/>
<tx:method name="update*"/>
<tx:method name="delete*"/>
<tx:method name="find*" read-only="true"/>
</tx:attributes>
</tx:advice> <aop:config>
<aop:advisor advice-ref="txAdvice" pointcut="execution(* cn.tf.service..*.*(..))"/>
</aop:config>

无cfg.xml

<!-- 1 service层 -->
<bean id="userService" class="cn.tf.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao"></property>
</bean>
<!-- 2 dao 层 -->
<bean id="userDao" class="cn.tf.dao.impl.UserDaoImpl">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean> <!-- 3.1 加载properties配置文件 -->
<context:property-placeholder location="classpath:jdbcInfo.properties"/>
<!-- 3.2 数据源(c3p0)-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClass}"></property>
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean> <!-- 4 session工厂
* LocalSessionFactoryBean 特殊bean生成 SessionFactory
-->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <!-- 4.1 配置数据源 -->
<property name="dataSource" ref="dataSource"></property>
<!-- 4.2 hibernate 特有设置 -->
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="javax.persistence.validation.mode">none</prop>
</props>
</property>
<property name="mappingDirectoryLocations" value="classpath:cn/tf/*"></property>
</bean> <!-- 5 事务管理 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean> <!-- 5.2 事务详情 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add*"/>
<tx:method name="update*"/>
<tx:method name="delete*"/>
<tx:method name="find*" read-only="true"/>
</tx:attributes>
</tx:advice> <!-- 5.3 aop 事务通知 应用 切入点 -->
<aop:config>
<aop:advisor advice-ref="txAdvice" pointcut="execution(* cn.tf.service..*.*(..))"/>
</aop:config>

struts整合spring

在applicationContext.xml中配置:

<bean id="userAction"  class="cn.tf.action.UserAction" scope="prototype">
<property name="userService" ref="userService"></property>
</bean>

在struts.xml中

<package name="default" namespace="/" extends="struts-default">
<action name="userAction_*" class="userAction" method="{1}">
<result name="add">/success.jsp</result>
</action>
</package>

注解开发

配置扫描注解

<bean id="hibernateTemplate"  class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean> <context:component-scan base-package="cn.tf"></context:component-scan>

配置事务管理器

<!-- 5 事务管理 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!-- 5.2 注释事务 -->
<tx:annotation-driven transaction-manager="transactionManager"/>

struts的配置中:

@Namespace("/")
@ParentPackage("struts-default") public class UserAction extends ActionSupport implements ModelDriven<User>{ private User user=new User();
@Autowired
private UserService userService; @Override
public User getModel() {
return user;
} public void setUserService(UserService userService) {
this.userService = userService;
}
@Action(value="userAction_add" ,results=@Result(name="add",location="/success.jsp"))
public String add(){
this.userService.addUser(user);
return "add";
} }

本文中使用的案例源码:

https://github.com/sdksdk0/springDemo1  (包含bean装配,scope作用域,spring表达式,spring生命周期,注解配置等)

https://github.com/sdksdk0/springDemo2  (包括AOP、aspectJ切入点表达式、jdbc模板等)

https://github.com/sdksdk0/springDemo3  (包含事务管理、转账案例、spring整合hibernate,struts整合spring等)

Spring常用配置的更多相关文章

  1. Spring 常用配置、Bean

    spring模块 Spring-Core: Core包是框架的最基础部分,并提供依赖注入(Dependency Injection)管理Bean容器功能. Spring-Context:(Spring ...

  2. Spring常用配置使用示例

    上篇介绍了Spring配置的基本情况,本篇介绍Spring常用配置具体如何使用.关于基础的配置,比如Configuration之类的就不示例,主要示例相对用的比较多同时可能比较复杂的标签或属性. 1) ...

  3. Spring常用配置示例

    Spring 是一款Java平台的开源框架,是为解决企业级应用程序开发的复杂性而创建的,通过良好的分层架构让开发人员能够专注于业务逻辑的开发. Spring框架是一个分层架构,由不同的模块组成,构成s ...

  4. Spring常用配置(二)

    OK,上篇博客我们介绍了Spring中一些常见的配置,上篇博客中介绍到的都是非常常见的注解,但是在Spring框架中,常见的注解除了上篇博客提到的之外,还有许多其他的注解,只不过这些注解相对于上文提到 ...

  5. Spring Boot实战笔记(二)-- Spring常用配置(Scope、Spring EL和资源调用)

    一.Bean的Scope Scope描述的是Spring容器如何新建Bean实例的.Spring的Scope有以下几种,通过@Scope注解来实现. (1)Singleton:一个Spring容器中只 ...

  6. Spring Boot实战笔记(四)-- Spring常用配置(事件Application Event)

    一.事件(Application Event) Spring的事件为Bean和Bean之间的消息通信提供了支持.当一个Bean处理完一个任务之后,希望另一个Bean知道并能做相应的处理,这时我们就需要 ...

  7. Spring Boot实战笔记(三)-- Spring常用配置(Bean的初始化和销毁、Profile)

    一.Bean的初始化和销毁 在我们的实际开发的时候,经常会遇到Bean在使用之前或之后做些必要的操作,Spring对Bean的生命周期操作提供了支持.在使用Java配置和注解配置下提供如下两种方式: ...

  8. springboot学习章节-spring常用配置

    1.Scope package com.zhen.highlights_spring4.ch2.scope; import org.springframework.context.annotation ...

  9. Spring Boot实战(2) Spring常用配置

    1. Bean的Scope scope描述Spring容器如何新建Bean的实例.通过注解@Scope实现,取值有: a. Singleton:一个Spring容器中只有一个Bean的实例.此为Spr ...

随机推荐

  1. Http协议消息报头

    哎.不知道怎么写Http协议... 超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议. HTTP基于TCP/IP通信协议来传递数据 ...

  2. Spring Cloud学习笔记-009

    API网关服务:Spring Cloud Zuul API网关是一个更为智能的应用服务器,它的定义类似于面向对象设计模式中的Façade模式,它的存在就像是整个微服务架构系统的门面一样,所有的外部客户 ...

  3. 【PYTHON】用户登录三次错误锁定

    黑名单:blacklist.txt 用户名单:username_password.py # Author:Stephen Yuan # 用户名和密码 username_password = { ', ...

  4. 初探Javascript之Canvas

    什么是Canvas <canvas>是 HTML5 新增的元素,可使用JavaScript脚本来绘制图形. canvas是一个矩形区域,您可以控制其每一像素. 引入Canvas ```ht ...

  5. 用ECMAScript4 ( ActionScript3) 实现Unity的热更新 -- 在脚本中使用MonoBehaviour

    继上次分析了热更新的Demo后,这次来介绍如何在热更新代码中使用MonoBehaviour. MonoBehaviour挂载到GameObject对象上的脚本的基类.平常Unity开发时,简单的做法就 ...

  6. orabbix插件监控oracle表空间问题

    我们安装好orabbix插件后,查看Tablespaces监控项是发项值为none,第一反应是没监控成功,其实不然. 1.我们打开orabbix监控项参数的路径,下面为Tablespaces的sql代 ...

  7. enumerate给列表加序号

    #coding=utf-8#给列表加上序号,enumerate(l1),默认从0开始l1=['money','house','joo']for item in enumerate(l1,1): #pr ...

  8. Scrapy定时执行爬取任务与定时关闭任务

    当我们利用Python scrapy框架写完脚本后,脚本已经可以稳定的进行数据的爬取,但是每次需要手动的执行,太麻烦,如果能自动运行,在自动关闭那就好了,经过小编研究,完全是可以实现的,今天小编介绍2 ...

  9. JS 变量类型互相转换

    转载自:http://zhaizhiyuan.blog.163.com/blog/static/1897672632009093147268/ Java中几种常用的数据类型之间转换方法:  1. sh ...

  10. 深入理解事件(Event)

    前言 在前一篇文章中讲到了Event 发布与订阅(一) 里面用到了事件来实现一些发布与订阅,当时对事件及其委托理解的还不是太深入,可能在使用上有点捉急.这篇来好好讲讲事件,以及通过一些小DEMO来加深 ...