本教程对应视频课程:http://edu.51cto.com/course/14731.htmlhtml
Aspect oritention programming(面向切面编程),Spring的AOP使用动态代理实现,若是一个类实现了接口,那么spring就使用JDK的动态代理完成AOP,若是一个类没有实现接口,那么spring就是用cglib完成AOP;java
AOP当中的概念:spring
①切入点Pointcut:在哪些类,哪些方法上面切(where);express
②通知/加强Advice:在方法的什么时机(when)作什么(what);编程
③切面Aspect:切入点+通知:什么时间,什么地点,干什么dom
④织入Weaving:把切面加入到对象,并建立出代理对象的过程(Spring自动搞定)ide
一、添加jar包spa
com.springsource.org.aopalliance-1.0.0.jar、com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar代理
二、引入aop的命名空间code
<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/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 "> <context:property-placeholder location="classpath:db.properties"/> <context:component-scan base-package="cn.org.kingdom"/> </beans>
三、xml配置
<aop:config> <!--作什么 --> <aop:aspect ref="txManager"> <!--什么地点,哪些方法上--> <aop:pointcut expression="execution(* cn.org.kingdom.aop_xml.*ServiceImpl.*(..)) " id="txPoint"/> <!--时机:方法前、方法后、方法先后 --> <aop:before method="beginTransaction" pointcut-ref="txPoint"/> </aop:aspect> </aop:config>
注意执行表达式的格式:
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern)throws-pattern?)
modifiers-pattern:修饰符
ret-type-pattern:返回值的类型
declaring-type-pattern:这个方法的类名
name-pattern:方法名
param-pattern:参数
throws-pattern:异常
语法案例:
1.任意公共方法的执行: execution(public * *(..)) 2.任何一个名字以“set”开始的方法的执行: execution(* set*(..)) 3.AccountService接口定义的任意方法的执行: execution(* com.xyz.service.AccountService.*(..)) 4.在service包中定义的任意方法的执行: execution(* com.xyz.service.*.*(..)) 5.在service包或其子包中定义的任意方法的执行: execution(* com.xyz.service..*.*(..))
aop:before(前置通知):在方法执行以前执行加强操做(加强类中的指定加强方法)
<aop:before method="beginTransaction" pointcut-ref="txPoint"/>
aop:after-returning(后置通知):在方法正常执行完成以后执行加强操做;
<aop:after-returning method="commit" pointcut-ref="txPoint"/>
异常通知:在业务方法中出现异常,须要调用的加强操做 throwing="ex":决定方法定义为:public void rollback(Throwable ex):
<aop:after-throwing method="rollback" pointcut-ref="txPoint" throwing="ex"/>
aop:after(最终通知):在方法执行以后执行,至关于在finally里面执行
<aop:after method="close" pointcut-ref="txPoint"/>
aop:around(环绕通知):把方法的执行包裹起来,环绕通知有两个要求
一、方法必需要返回一个Object(返回的结果)
二、方法的第一个参数必须是ProceedingJoinPoint(能够继续向下传递的切入点)
<aop:around method="around" pointcut-ref="txPoint"/>
完整代码
//PersonService package cn.org.kingdom.service; public interface PersonService { public abstract int add(String msg); } //PersonServiceImpl package cn.org.kingdom.service.impl; import org.springframework.stereotype.Service; import cn.org.kingdom.service.PersonService; @Service("personService") public class PersonServiceImpl implements PersonService { public int add(String msg) { System.out.println("执行add操做"); System.out.println(10/0); return 0 ; } } //事务管理类 package cn.org.kingdom.ts; import org.aspectj.lang.ProceedingJoinPoint; import org.springframework.stereotype.Component; @Component("ts") public class Transaction { public void begin(){ System.out.println("开启事务"); } public void commit(){ System.out.println("提交事务"); } public void rollback(Throwable ex){ System.out.println("回滚事务"); System.out.println("发生的异常通知是:"+ex); } public void closeConnection(){ System.out.println("关闭链接"); } public Object around(ProceedingJoinPoint pjp){ Object value = null ; try{ begin(); value = pjp.proceed(); commit(); }catch(Throwable e) { rollback(e); }finally{ closeConnection(); } return value; } }
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" 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 "> <context:property-placeholder location="classpath:db.properties"/> <!-- 扫包 --> <context:component-scan base-package="cn.org.kingdom"/> <aop:config> <aop:aspect ref="ts"> <aop:pointcut expression="execution(* cn.org.kingdom.service..*.*(..))" id="mypointcut"/> <aop:around method="around" pointcut-ref="mypointcut"/> </aop:aspect> </aop:config> </beans>
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" 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 "> <context:property-placeholder location="classpath:db.properties"/> <!-- 扫包 --> <context:component-scan base-package="cn.org.kingdom"/> <aop:aspectj-autoproxy/> </beans>
java配置
package cn.org.kingdom.ts; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; @Component("ts") @Aspect public class Transaction { @Pointcut(value="execution(* cn.org.kingdom.service..*.*(..))") public void pointcut(){} //注意value为方法名,而且加括号 @Around(value="pointcut()") public Object around(ProceedingJoinPoint pjp){ Object value = null ; try{ begin(); value = pjp.proceed(); commit(); }catch(Throwable e) { rollback(e); }finally{ closeConnection(); } return value; } public void begin(){ System.out.println("开启事务"); } public void commit(){ System.out.println("提交事务"); } public void rollback(Throwable ex){ System.out.println("回滚事务"); System.out.println("发生的异常通知是:"+ex); } public void closeConnection(){ System.out.println("关闭链接"); } }