<?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: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/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"
default-autowire="byName" default-lazy-init="true">
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!-- the transactional semantics... -->
<tx:attributes>
<!-- all methods starting with 'get' are read-only -->
<tx:method name="get*" read-only="true"/>
<tx:method name="find*" read-only="true"/>
<!-- other methods use the default transaction settings (see below) -->
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:advisor advice-ref="txAdvice" pointcut="execution(* com.becom.XXXX.service..*(..))"/>
<aop:aspect id="aspectForService" ref="catTransactionAspectForService">
<aop:pointcut id="webserviceService"
expression="execution(* com.becom.XXXX.service..*(..))" />
<aop:around pointcut-ref="webserviceService" method="doAround" />
</aop:aspect>
</aop:config>
<bean id="catTransactionAspectForService" class="com.becom.dkyd.webapp.util.CatTransactionAspect">
<property name="transactionType" value="SERVICE"></property>
</bean>
</beans>
一 .面向切面编程(AOP)的基础概念:
以一个普通的java方法来举例
public 返回类型 方法名(参数列表){ ——>环绕通知
方法前处理代码 ——> 前置通知
try{
方法具体实现(方法体)…….
方法后处理代码 ——> 后置通知
}Catch(异常类型 e){
异常处理…… ——> 例外通知
}finally{
最后处理代理…… ——> 最终通知
}
}
a. 横切关注点:如上面5个通知的位置,在java对象中,可以这些具有类似共同处理逻辑的位置加入如权限验证、事物处理、日志记录等处理逻辑的对象称为横切关注点,面向对象编程(OOP)的关注点是纵向将现实世界的事物抽象成编程的对象模型。而面向切面编程(AOP)的关注点是横向的,它将编程对象模型中拥有类似处理逻辑的地方抽象出来形成切面,而编程对象中的处理逻辑就是横切关注点。
b. 切面(Aspect):将横切关注点抽象就形成切面,与类类似,二者关注点不同,类是事物特性的抽象,切面是横切关注点的抽象。
c. 连接点(Joinpoint):被拦截到的点,在Spring中指方法,因为spring只支持方法类型的连接点,即被拦截的方法。如上面例子的方法。
d. 切入点(Pointcut):指对连接点进行拦截的定义,是连接点的集合,即一系列被拦截方法的集合。
e. 通知(Advice):指拦截到连接点之后要做的事情,即拦截之后的逻辑处理。通常的权限验证、事物处理、日志记录等操作就是在通知中定义和完成的。
f. 目标对象(Target):代理的目标对象,即被拦截的对象。如上面例子中方法所在的对象。
g. 织入(Weave):指将切面应用到目标对象,并导致代理对象创建的过程。
h. 引入(Introduction):在不修改代码的前提下,引入可以在运行期为类动态的添加一些方法和字段。
二.配置
1. Spring中支持面向切面编程(AOP)的依赖包:
Spring解压后目录中的如下3个包:
lib/aspectj/aspectjweaver.jar
lib/aspectj/aspectjrt.jar
lib/cglib/cglib-nodep-2.1-3.jar
2. 在spring中使用面向切面编程(AOP)时,需要在spring配置文件中引入aop的命名空间,即添加如下的配置:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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/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"
default-autowire="byName" default-lazy-init="true">
注意:Spring2.5以后提供两种AOP方法,即基于xml配置文件方式和基于java注解方式。
A.若要使用注解方式的aop,需要在spring配置文件中添加如下的对象注解方式aop的支持:
<aop:aspectj-autoProxy/>
- JavaBean的包装类——BeanWrapper:
Spring通过BeanWrapper类封装一个javabean的行为,可以设置和获取其属性值,如:
BeanWrapper 包装类对象 = BeanWrapperImpl(new 被包装类());
包装类对象.setPropertyValue(“属性名”,”属性值”);
通过这种方法就可以给被包装类设置属性。
- 基于注解方式的面向切面编程(AOP)开发:
(1).在spring配置文件中加入对注解方法的aop支持。
(2).定义切面:和创建普通类类似,在类前加上”@Aspect”注解,表明该类是一个切面。
(3).在切面中加入切入点:
切入点就是被拦截对象方法的集合,通常切入点定义在切面中某个对切入点进行处理的方法上。使用”@Pointcut”注解,语法如下:
@Pointcut(“execution(* com.test.service..*.*(..))”)
public void anyMethod(){//方法名为切入点名
切入点处理
}
语法参数详解:
a. 第一个”*”:表示被拦截的方法是任意的返回类型。
b. com.test.service:这里是举一个简单的例子,表示要被拦截的包名,即被拦截的包。
c.被拦截包名后面的两个”..”:表示被拦截包下面的子包也递归进行拦截,即被拦截的子包。
d. ”..”之后的”*”:表示被拦截包及其子包下面的所有类,即被拦截的类。
e. 最后一个”*”:表示被拦截类中的所有方法,即被拦截的方法。
f. ”(..)”:表示被拦截的方法接收任意的参数,即被拦截的参数。
注意:切入点定义语法可以支持通配符,但是一定要严格遵循语法规则。如:
@Pointcut(“execution(*com.test.service..*.add*(..))”)
表示对com.test.service包及其子包下所有的类中以”add”开头的方法进行拦截。
(4).在切面中添加通知:
Spring中通知位置请参看下面的小例子。
”@Before”注解:声明前置通知。
“@AfterRutruning”注解:声明后置通知。
“@After”注解:声明最终通知。
“@AfterThrowing”注解:声明例外通知。
“@Around”注解:声明环绕通知。
一个定义通知的例子如下:
-
@Before(“anyMethod()(切面中声明的切入点名)”) public void doAccessCheck(){ …… }
注意:环绕通知和其他4种通知的稍有不同,环绕通知的定义方式比较特别,环绕通知在整个方法调用前后都会起作用,因此必须使用连接点对象告诉连接点在环绕通知处理之后继续其逻辑处理。其定义方式如下:
@Around(切入点名)
public Object doBasicProfiling(ProcedingJoinPoint pjp) throws Throwable{
……
return pjp.proceed();//该句是告诉连接点继续执行其他的操作
}
- 基于注解方式的面向切面编程(AOP)开发的一些小技巧:
(1).获取输入参数:
-
@Before(“切入点名 && args(输入参数名)”) public void doSomething(String 输入参数名){……}
(2).获取返回结果:
@AfterReturning(Pointcut=”切入点名”,returning=”返回结果名”)
public void dosomething(String 结果名){……}
B. 基于XML方式的面向切面编程(AOP)开发:
(1).定义切面类,在切面类中添加通知。
(2).将切面类想普通java类一样在spring配置文件中配置。
(3).在spring配置文件中添加AOP配置如下:
-
<aop:config> <!--配置切面--> <aop:aspect id=”切面id” ref=”spring配置文件中切面类的id”> <!--配置切入点--> <aop:pointcut id=”切入点id” expression=”execution(* com.test.service..*.*(..))”/> <!--配置通知--> <aop:before pointcut-ref=”切入点id” method=”切面类中相应的处理方法”/> <aop:after ……/> …… </aop:aspect> </aop:config>
三. Spring的事务处理(Spring的声明式事务处理):
事务简单来说是指数据库中的一条最基本的操作,关于事务的详细讲解以后会在数据库相关总结中具体说明。Spring的面向切面编程(AOP)一个最重要的应用是事务管理,Spring2.5以后版本的事务管理支持基于注解的方式和基于XML文件的方式两种:
(1).基于注解方式的事务管理:
a. 在spring配置文件中添加事务管理的命名空间如下:
-
xmlns:ts=http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
b. 在spring配置文件中配置事务管理器如下:
-
<bean id=”txManager” class=”org.springframework.jdbc.datasource.DataSourceTransactionManager”> <property name=”dataSource” ref=”spring中配置的数据源bean的id”/> </bean>
c. 在spring配置文件中添加支持注解方式的事务配置项如下:
-
<tx:annotation-driventransaction-managertx:annotation-driventransaction-manager=”txManager(spring中配置的事务管理器bean的id)”/>
d. 使用基于注解的事务管理:
在Spring所管理的JavaEE工程中,需要使用事务的业务逻辑地方加上“@Transactional”注解。
(2).基于XML文件方式的事务管理:
a. 在spring配置文件中配置事务管理器如下:
-
<bean id=”txManager” class=”org.springframework.jdbc.datasource.DataSourceTransactionManager”> <property name=”dataSource” ref=”spring中配置的数据源bean的id”/> </bean>
b. 在spring配置文件中添加事物管理的切面如下:
<aop:config>
<!--配置事务切入点-->
<aop:pointcut id=”transactionPointcut”
Expression=”execution(* com.test.service..*.*(..))”/>
<!--配置事务通知-->
<aop:advisor advice-ref=”txAdvice” pointcut-ref=”transactionPointcut”/>
</aop:config>
c.在spring配置文件中为事务通知添加事物处理特性如下:
<tx:advice id=”txAdvice” transactionManager=”txManager”>
<tx:attributes>
<!--这里举例将以get开头的查询方法设置为只读,不支持事务-->
<tx:method name=”get*” read-only=”true” propagation=”NOT_SUPPORTED”/>
<!--其他的方法设置为spring默认的事物行为-->
<tx:method name=”*”/>
</tx:attributes>
</tx:advice>