您的位置:首页 > 编程语言 > Java开发

系统学习Spring之Spring in action(七)

2013-03-28 01:05 381 查看

每日一叨:

    下班回来,没有立即写博客,而是欣赏了之前下载的一部电影<心灵捕手>,静下心来好好欣赏,在这就不剧透啦.

文章导读:

    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.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: