系统学习Spring之Spring in action(七)
每日一叨:
下班回来,没有立即写博客,而是欣赏了之前下载的一部电影<心灵捕手>,静下心来好好欣赏,在这就不剧透啦.
文章导读:
1.面向切面编程之XML配置
知识点:
1.面向切面编程之XML配置
在学习面向切面之前,首先理解下AOP中的术语,有助于后面能够更好的理解AOP.
ADVICE:面向切面编程的任务一般被称为ADVICE,Spring有5种ADVICE分别是Before,After,After-returnning,After-throwing,Around.
ADVICE主要的作用是定义了做什么和什么时候做.
JOIN POINTS:面向切面编程可能执行的地方被称为JOIN POINTS.
POINTCUTS:POINTCUTS主要就是缩小JOIN POINTS,系统不可能在所有的JOIN POINTS都进行处理,所以只能用POINTCUTS定义在哪处理.
ASPECTS:ADVICE和POINTCUTS的结合体,ASPECTS定义了要执行什么,在哪执行,什么时候执行.
SpringAOP只支持方法拦截,不支持构造方法和字段的拦截,简单的说就是SpringAOP无法细粒度的拦截字段的修改和bean的创建.
首先用使用通过XML配置来写第一个SpringAOP事例:
建立喝咖啡的类:
public class DrinkCoffee { //正在喝咖啡就用这个做例子吧 public void drink(){ System.out.println("咖啡好喝极了."); } }
建立咖啡类:
public class Coffee { //喝咖啡之前 public void beforeDrinkCoffee(){ System.out.println("首先把水烧开,把咖啡粉倒入杯中,倒入适量的白开水,然后用勺子搅拌."); } //喝咖啡之后 public void afterDrinkCoffee(){ System.out.println("咖啡太好喝了,好想在喝一杯..."); } //水放少了,咖啡有点苦. public void somethingIsWrong(){ System.out.println("一不小心把水放多了,味道比较淡,口感欠佳."); } //喝完咖啡要记得洗杯子哦. public void washCup(){ System.out.println("喝完咖啡后洗杯子."); } }
用XML配置的方式来配置SpringAOP:
<bean id="drinkCoffee" class="com.ricky.zero.pojo.DrinkCoffee"></bean><!-- 实例化DrinkCoffee --> <bean id="coffee" class="com.ricky.zero.pojo.Coffee"></bean><!-- 实例化Coffee --> <aop:config><!-- 配置SpringAOP --> <aop:aspect ref="coffee"> <!-- 定义DrinkCoffee实例中,当执行实例中drink方法时执行下面的point --> <aop:pointcut expression="execution(* com.ricky.zero.pojo.DrinkCoffee.drink(..))" id="drink"/>
<!-- 在执行drink之前执行beforeDrinkCoffee -->
<aop:before method="beforeDrinkCoffee" pointcut-ref="drink"/>
<!-- 无论drink方法执行成功还是抛异常,在drink方法后执行washCup -->
<aop:after method="washCup" pointcut-ref="drink"/> <aop:after-throwing method="somethingIsWrong" pointcut-ref="drink"/><!-- 当drink方法抛异常时执行 --> <aop:after-returning method="afterDrinkCoffee" pointcut-ref="drink"/><!-- 当drink方法执行成功时执行 --> </aop:aspect> </aop:config>
运行测试:
ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml"); DrinkCoffee drinkCoffee = (DrinkCoffee)ctx.getBean("drinkCoffee"); drinkCoffee.drink();
测试结果:
首先把水烧开,把咖啡粉倒入杯中,倒入适量的白开水,然后用勺子搅拌.
咖啡好喝极了.
喝完咖啡后洗杯子.
咖啡太好喝了,好想在喝一杯...
修改DrinkCoffee类,可以看到aop:after-throwing效果:
public class DrinkCoffee { //正在喝咖啡就用这个做例子吧 public void drink(){ System.out.println("咖啡好喝极了." + 1/0); } }
运行测试并得到结果:
首先把水烧开,把咖啡粉倒入杯中,倒入适量的白开水,然后用勺子搅拌.
喝完咖啡后洗杯子.
一不小心把水放多了,味道比较淡,口感欠佳.
当出现异常的时候aop:after-returning不会执行.
aop:before和aop:after两个在一起有一个致命的缺点,就是在执行drink方法的时候,before和after方法之间的数据信息是不能共享的.
Spring还提供了一个可以在drink执行前和执行后拦截并且数据可以共享的方法使用<aop:around>标签.
public class DrinkCoffee{ //正在喝咖啡就是这个做例子吧 public void drink(){ System.out.println("咖啡真好喝."); } }
public class Coffee { //喝咖啡之前 public void beforeDrinkCoffee(){ System.out.println("首先把水烧开,把咖啡粉倒入杯中,倒入适量的白开水,然后用勺子搅拌."); } //喝咖啡之后 public void afterDrinkCoffee(){ System.out.println("咖啡太好喝了,好想在喝一杯..."); } //水放少了,咖啡有点苦. public void somethingIsWrong(){ System.out.println("一不小心把水放多了,味道比较淡,口感欠佳."); } //喝完咖啡要记得洗杯子哦. public void washCup(){ System.out.println("喝完咖啡后洗杯子."); } //把所有步骤都放到一个方法里 public void allInOne(ProceedingJoinPoint p){ try { System.out.println("首先把水烧开,把咖啡粉倒入杯中,倒入适量的白开水,然后用勺子搅拌."); p.proceed(); System.out.println("咖啡太好喝了,好想在喝一杯..."); } catch (Throwable e) { // TODO Auto-generated catch block System.out.println("一不小心把水放多了,味道比较淡,口感欠佳."); }finally{ System.out.println("喝完咖啡后洗杯子."); } } }
配置文件:
<bean id="coffee" class="com.ricky.zero.pojo.Coffee"></bean> <bean id="drinkCoffee" class="com.ricky.zero.pojo.DrinkCoffee"></bean> <aop:config> <aop:aspect ref="coffee"> <aop:pointcut expression="execution(* com.ricky.zero.pojo.DrinkCoffee.drink(..))" id="drink"/> <aop:around method="allInOne" pointcut-ref="drink"/> </aop:aspect> </aop:config>
运行测试:
ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml"); DrinkCoffee drinkCoffee = (DrinkCoffee)ctx.getBean("drinkCoffee"); drinkCoffee.drink();
测试结果:
首先把水烧开,把咖啡粉倒入杯中,倒入适量的白开水,然后用勺子搅拌.
咖啡真好喝.
咖啡太好喝了,好想在喝一杯...
喝完咖啡后洗杯子.
若drink方法执行时出现异常,例如:
public class DrinkCoffee{ //正在喝咖啡就是这个做例子吧 public void drink(){ System.out.println("咖啡真好喝." + 1/0); } }
运行测试后结果为:
首先把水烧开,把咖啡粉倒入杯中,倒入适量的白开水,然后用勺子搅拌.
一不小心把水放多了,味道比较淡,口感欠佳.
喝完咖啡后洗杯子.
时间不早了,,明天在写吧...
--------------------------------申明----------------------------
本文可以免费阅读以及转载,转载时请注明出处.
本人邮箱:Ricky_LS@163.com
Thank you for your corporation.