??xml version="1.0" encoding="utf-8" standalone="yes"?>
spring 的声明式事务:
(1):配置数据?br />
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.git.mm.mysql.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/itcast?useUnicode=true&characterEncoding=UTF-8"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
<!-- q接池启动时的初始?-->
<property name="initialSize" value="1"/>
<!-- q接池的最大?-->
<property name="maxActive" value="500"/>
<!-- 最大空闲?当经q一个高峰期旉?q接池可以慢慢将已经用不到的q接释放一部分,一致减到maxIdle为止 -->
<property name="maxIdle" value="2"/>
<!-- 最空闲?当空闲的q接数少于阀值时,q接池就会预甌一些连?以免z峰到来时来不及甌 -->
<property name="minIdle" value="1"/>
</bean>
(2):配置事务:
配置事务理?
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
(3):
在Spring配置文g加入事务命名I间
xmlns:tx="http://www.springframework.org/schema/tx"
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
(4):采用注解方式配置事务所需的注解处理器
<tx:annotation-driven transaction-manager="txManager"/>
(5):Z务bean注入数据?/p>
(6)
@Transactional 被声明的cȝ每个Ҏ会在同一个事务中执行.
在需要事务执行环境的业务逻辑层需要?@Transactional 注解
2:
使用属性文件保存数据库q接信息
需要在Spring配置文g中配|的元素?
<context:property-placeholder location="classpath:jdbc.properties"/>
加入classpath 的目的ؓ高速Spring容器文g在类路径?br />
然后在Spring配置文g中的元素?{名称}代替属性文件的相应的键卛_
2:
改变Spring的默认事务行?
(1):使Spring回滚checked例外(默认不会?:
在方法的声明上标?br />
@Transactional(rollbackFor=异常的名U?class)
其中异常的名UCؓҎ抛出的异?例外)的类名称
则Spring在遇到此checked异常?׃回滚事务
(2):使Spring不回滚unchecked 例外(默认回滚)
在方法的声明上标?br />
@Transactional(noRollbackFor=RuntimeException.class)
则在Ҏ遇到unchecked例外(q行期异??则会提交事务
或者?noRollbackForClassName="异常的名U? ?rollbackForClassName="异常的名U? 来指?/p>
3:
以下的事务可以在 @Transactional(propagation=Propagation.xxx) 中的xxx即ؓ以下事务的类?
Spring事务的分c?
REQUIRED,NOT_SUPPORTED,REQUIRESNEW,MANDATORY,SUPPORTS,NERVER,NESTED
REQUIRED:
业务Ҏ需要在一个事务中q行.如果Ҏq行?已经处在一个事务中,那么假如到该事务,否则己创Z个新的事?
NOT_SUPPORTED:
声明Ҏ不需要事?如果Ҏ没有兌C个事?容器不会为它开启事?如果Ҏ在一个事务中被调?该事务会被挂?在方法调用结束后,原先的事务便会恢复执?
REQUIRESNEW:
属性表明不是否存在事?业务ҎM己发起一个新的事?容器不会为它开启事?
如果Ҏ已经存在一个事务中,则原有事务被挂v,新的事务会被创徏,直到Ҏ执行l束,新的事务才算l束.原先事务才会恢复执行.
MANDATORY:
该属性指定业务方法只能在一个已q存在的事务中执?业务Ҏ不能发v自己的事?如果业务Ҏ没有在事务的环境下调?容器׃抛出例外.
SUPPORTS:
q一事务表明属?如果业务Ҏ在某个事务范围内被调?则方法称事务的一部分.如果业务Ҏ在事务范围外被调?则方法在没有事务的环境下执行.
NEVER:
指定业务Ҏl对不能再事务范围内执行.如果业务Ҏ在某个事务中执行,容器会抛出异?只有业务Ҏ没有兌CQ何事?才能正常执行.
NESTED:
如果一个活动的事务存在,则运行一个嵌套的事务?如果没有zd事务,则按REQUIRED属性执?它用了一个单独的事务,q个事务拥有多个可以回滚的保存点。内部事务的回滚不会对外部事务造成影响。但外部事务的回滚会造成内部事务的回? 它只对DataSourceTransactionManager事务理器v?
4:
@Transactional(timeout=30)
中指定事务的时旉,一般情况下不用讄
5:
@Transactional(readOnly="")
在只M务中使用,可以提高效率,但不可以执行增删?
6:
@Transactional(isolation=Isolation.DEFAULT);
指定数据库的事务隔离U别:主要由底层数据库实现.
包括U类:
Read Uncommited : L提交数据(会出现脏数据,不可重复dq读)
Read Commited : d提交数据(会出C可重复读和? (SQLServer 默认U别)
Repeatable Read : 可重复读(会出现? (MySQL 默认U别)(一般情况下是这U?
Serializable : 串行?br />
q几U别是由数据库的不同的锁来实现:?׃n?更新?排他?/p>
脏读: 一个事务读取到另一个事务未提交的更新数?
不可重复? 在同一个事务中,多次d同一数据q回的结果有所不同.?后箋d可以d另一事物已提交的更新数据.
相反,"可重复读"在同一事务多次d数据?能够保证所d数据一?也就是说,后箋数据不能d另一事物已提交的更新数据.
可重复读在数据库采取的技术ؓ"快?技?/p>
q读:一个事物读取都另一事物已提交的insert数据.
7:
使用XML方式配置Spring事务:
<aop:config>
<aop:pointcut id="transactionPointcut" expression="execution(* cn.itcast.service..*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="transactionPointcut"/>
</aop:config>
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="get*" read-only="true" propagation="NOT_SUPPORTED"/> <!-- 对读取方法采用只?事务 -->
<tx:method name="*"/> <!-- 其他按照默认讄 如事务隔ȝ?事务cd -->
</tx:attributes>
</tx:advice>
2:
Spring aop 应用斚w:
例如:权限pȝ、运行期监控
3:
<bean id="aspectbean" class="cn.rui.aop.XmlInterceptor"/>
<aop:config>
<aop:aspect id="asp" ref="aspectbean">
<aop:pointcut id="mycut" expression="execution(* com.rui..*.*(..))"/>
<aop:before pointcut-ref="mycut" method="doAccessCheck"/>
<aop:after-returning pointcut-ref="mycut" method="doAfterReturning"/>
<aop:after-throwing pointcut-ref="mycut" method="doAfterThrowing"/>
<aop:after point-ref="mycut" method="doAfter"/>
<aop:around point-ref="mycut" method="doBasicProfiling"/>
</aop:aspect>
</aop:config>
4:
对于执行的表辑ּ execution(* com.rui..*.*(..)) execution(1 2..3.4(5))
中对? 为方法的q回?可以指定Lcd * 代表所有类? 其他cd用包?+ cd如java.lang.String,IZؓvoid, 若取非某U类型则?! 加上 cd卛_ ? !java.lang.String ?!void
对于2 为包?对于包名后的两个Ҏ为包含所有的子包,也可直接为包? cd
对于3为类?可以?* 代表所有的c?也可指定特定的类 直接cd卛_
对于4为方法名 * 代表所有方?,也可指定特定的方?/p>
对于 5 为方法的参数 可以指定 .. 代表所有的Ҏ,对于Ҏ的比如方法的W一个参数必Mؓjava.lang.Integer 的则表达式ؓ (java.lang.Integer,..)
对于最后一个参数必Mؓjava.lang.String则ؓ(..,java.lang.String) 前面的两个点代表Stringcd前可能有也可能没?/p>
2:
加入Spring AOP的支?br />
(1):加入jar包,在配|文件中导入aop命名I间Q加?lt;aop:aspectj-autoproxy/>元素
(2):定义切面c?
(3):在切面类中加入注?
: 在类前的注解
@Aspect
: 声明一个切入点
@Pointcut("execution(* cn.itcast.service..*.*(..))")
private void anyMethod() {} // 定义切入点的名称是通过Ҏ的定义来定义?
:定义前置通知
@Before("anyMethod() && args(userName)") 其中 userName 为限制方法的参数必须为String cd?br />
public void doAccessCheck(String userName) {}
:定义后置通知
@AfterReturning(pointcut="anyMethod()",returning="revalue")
public void doReturnCheck(String revalue) {}
:定义例外通知
@AfterThrowing(pointcut="anyMethod()",throwing="ex")
public void doExceptionAction(Exception ex){}
:定义最l通知
@After("anyMethod()")
public void doReleaseAction() {}
:环绕通知
@Around("anyMethod()")
public doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
return pjp.proceed();
}
以上 anyMethod() 为切入点的名U? 应用的切入点
args 、returning、throwing 为可不定义的可选参?但被标注Ҏ也要跟着参数的有无而改变方法的参数.
环绕通知的方法的{是死格式
3:
把类加入Spring理:
在Spring配置文g中加入或?@Component lg注解q行标注卛_.
4:
通知程?
// 环绕通知
// 前置通知
try{
// Ҏ执行
// 后置通知
}catch(Exception e){
// 例外通知
}finally{
// 最l通知
}
5:
W?19 ?br />
2:
q回属性的cd 是否?指定参数的类型或者是指定参数的基c?x参数{成properdesccd是否可以Q可以则q回trueQ否则返回false)
PropertyDescriptor properdesc = Introspector.getBeanInfo(Bean.class).getPropertyDescriptors();
properdesc.getPropertyType().isAssignableFrom(other.class);
3:
getDeclaredFields() 得到所有类中声明的字段Q但不包括从父类l承q来的类型)
4:
用注解来实现依赖注入的规则:
Q?Q:?字段 ?setter Ҏ上注明注?br />
(2):dXML文g
Q?Q:得到所有的属?遍历 赋?br />
(4): 得到所有的字段 判断是否有注?赋?/p>
5:
@Autowired(required=false) ?required 默认为trueQ指的是当找不到时会抛出异常Q当为falseӞ会给其赋gؓnull
6:
自动装配的几U方式:
byType: 按类型装配,可以Ҏ属性的cdQ在容器中寻找跟该类型匹配的bean?br />
如果发现多个Q那么将会抛出异常。如果没有找刎ͼ卛_性gؓnull
byName: 按名U装配,可以Ҏ属性的名称Q在容器中寻找跟该属性名相同的beanQ?br />
如果没有扑ֈQ即属性ؓnull
constructor与byType的方式类|不同之处在于它应用于构造函数。如果在容器中没有找C构造器参数cd一致的beanQ那么将会抛出异常?br />
autodetect: 通过beancȝ自省机制QintrospectionQ来军_是用constructorq是
byType方式q行自动装配。如果没有发现默认的构造器Q那么将使用byType方式?/p>
7:
@Service 用于标注业务层组?br />
@Controller 用于标注控制层组?如Struts的action)
@Repository 用于标注数据讉Klg 即DAOlg
@Component 泛指lgQ当lg不好归类的时候,我们可以使用q个注解q行标注?/p>
8:
使用Spring classpath 自动扫描 方式 把组件纳入spring容器中管?的步骤:
一Q加入context命名I间
二:在XML文g中加?元素 <context:component-scan base-package="cn.itcast"/> 注册Spring自动扫描处理?q个元素默认注册了以?lt;context:annotation-config />元素所注册的所有处理器
三:在DAOcd加入 @Repository 注解,在Servicecd加入 @Service 注解Q在控制lgcd加入 @Control 注解
四:注解所注明的类默认为单??@Scope("singleton") ,如果需要,可以?@Scope("prototype") 来?原型模式Q每一ơ请求,可以标注?@Control 上)
五:可以使用 @PostContruct 来标注初始化的方?Q?@PreDestory 来标注销毁的Ҏ 。其 @PostContruct {同?以前在XML文g中写?init-method="" 注解Q其 @PreDestory 注解{同?在xml文g中配|的 destory-method="" 元素
六:要其执?@PreDestory 所标注的方法则使用 单例singleton模式Q而不是原型prototype模式
9:
使用cglib 来创建没有实现接口的cȝ代理对象
一Q加?cglib-nodep-2.1_3.jar 文g
二:Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(要代理的c?;
enhancer.setCallback(实现MethodInterceptor接口的类);
四:写一个实?MethodInterceptor 接口的类Qƈ且实现其Ҏ
2:
PropertyDescriptor[] propDesc = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
ConvertUtils.convert(value,propDesc[0].getPropertyType()); // 转换属性的cd
3:
ProperyDescriptor
Properties props = new Properties();
props.load(this.getClass().getResourceAsStream("相对路径如:config.properties或者:l对路径: /包名/config.properties")
4:
对于集合的类型的注入Q?br />
<property name="sets">
<set>
<value>set1</value>
<value>set2</value>
<value>set3</value>
</set>
</property>
<property name="lists">
<list>
<value>list1</value>
<value>list2</value>
<value>list3</value>
</list>
</property>
<property name="props">
<props>
<prop key="key1">value1</prop>
<prop key="key2">value2</prop>
<prop key="key3">value3</prop>
</props>
</property>
<property name="map">
<map>
<entry key="key-1" value="value-1">
<entry key="key-2" value="value-3">
<entry key="key-2" value="value-3">
</map>
</property>
5:
使用构造器q行bean的配|?br />
Q?Q:在实体bean中创建构造函?br />
public PersonServiceBean(PersonDao personDao, String name) {
this.personDao = personDao;
this.name = name;
}
(2): 在配|文件中配置Q根据构造函数的索引q行配置Q烦引从0开?br />
<constructor-arg index="0" ref="personDao"></constructor-arg>
<constructor-arg index="1" value="zhangsan"></constructor-arg>
6:
使用字段Field注入Q?br />
@Autowired 默认按类型装配,如果想用名U装配,可以l合 @Qualifier注解一起?br />
eg:
@Autowired @Qualifier("personDaoBean")
private PersonDao personDao;
@Resource 如果指定name属性则ҎnameQ否则按照标注的属性名U进行寻找,
当找不到与名U匹配的bean才会按类型装?可以用在字段上,也可以用在setterҎ?/p>
2:
依赖注入:
使用构造函??setter Ҏ
3:
事务是局限在数据库连接之内的,所以用两个连接的Ҏ是不能用同一个事务的.
解决办法:
Connection conn = null;
conn.setAutoCommit(false);
Bean1.update(); // 更新金额
Bean2.save(); // 记录操作日志
// 提交事务
4:
如果不论更新金额是否成功,都需要记录日?则需要两个Ҏ分别使用不同的事?
5:
Spring 声名式事?/p>
保证两个Ҏ在同一个事务中执行,在方法的前面加上:
@Transactional(propagation=Propagation.Required)
使方法在新的事务中执?
@Transactional(propagation=Propagation.RequiredNew)
6:
Spring l我们带来的好处:
(1): 降低lg之间的耦合?实现软g各层之间的解?br />
(2): 可以使用容器提供的众多服??事务理服务,消息服务{等.
当我们用容器管理事务时,开发h员就不需要手工控制事?也不需要处理复杂的事务传播.
(3): 容器提供单利模式支持,开发h员不在需要自q写实C?
(4): 容器提供众多的辅助类,使这些类能够加快应用的开??JdbcTemplate,HibernateTemplate
(5): Spring对于L的应用框架提供了集成支持,?集成Hibernate,JPA,Struts{?q样更便于应用的开?
7:
使用Spring 提供的服务很?应用属于轻量U?br />
使用Spring 提供的服务很?应用属于重量U?br />
EJB 容器默认为应用提供了EJB规范中的所有的功能,所以它属于重量U的
EJB 的服务包? 安全服务, jndi服务,
2:
依赖注入:
使用构造函??setter Ҏ
3:
事务是局限在数据库连接之内的,所以用两个连接的Ҏ是不能用同一个事务的.
解决办法:
Connection conn = null;
conn.setAutoCommit(false);
Bean1.update(); // 更新金额
Bean2.save(); // 记录操作日志
// 提交事务
4:
如果不论更新金额是否成功,都需要记录日?则需要两个Ҏ分别使用不同的事?
5:
Spring 声名式事?/p>
保证两个Ҏ在同一个事务中执行,在方法的前面加上:
@Transactional(propagation=Propagation.Required)
使方法在新的事务中执?
@Transactional(propagation=Propagation.RequiredNew)
6:
Spring l我们带来的好处:
(1): 降低lg之间的耦合?实现软g各层之间的解?br />
(2): 可以使用容器提供的众多服??事务理服务,消息服务{等.
当我们用容器管理事务时,开发h员就不需要手工控制事?也不需要处理复杂的事务传播.
(3): 容器提供单利模式支持,开发h员不在需要自q写实C?
(4): 容器提供众多的辅助类,使这些类能够加快应用的开??JdbcTemplate,HibernateTemplate
(5): Spring对于L的应用框架提供了集成支持,?集成Hibernate,JPA,Struts{?q样更便于应用的开?
7:
使用Spring 提供的服务很?应用属于轻量U?br />
使用Spring 提供的服务很?应用属于重量U?br />
EJB 容器默认为应用提供了EJB规范中的所有的功能,所以它属于重量U的
EJB 的服务包? 安全服务, jndi服务,