Spring实战读书笔记 第四章 面向切面的Spring
1,AOP术语
-1,通知(advice):通知定义了切面是什么时候以及何时用的。除了描述切面的工作,通知还决定了合适解决。Spring切面可以用5中类型的通知。
Before:在方法调用之前使用。
After:在方法完成之后调用通知,无论方法是否执行成功。
After-returning:在方法执行成功后调用。
After-throwing:在方法抛出异常后调用。
Around:通知包裹了被通知的方法,在被通知的方法调用之前和调用之后执行自定义行为。
-2,切点(pointcut):一个或多个连接点。
-3,连接点(join point):应用在执行过程中能够插入切面的点。
-4,切面(Aspect):切面是通知和切点的结合,通知和切点共同定义了关于切面的全部内容。
-5,引入(Introduction):引入允许我们向现有的类添加新的方法或属性。
2,Spring借助AspectJ的切点表达式语言来定义Spring切面
-1,arg() :限制连接点匹配参数为制定类型的执行方法。
-2,@args() :限制连接点匹配参数由制定注解标注的执行方法。
-3,execution():用于匹配是连接点的执行方法。
-4,this():限制连接点匹配AOP代理的Bean引用为制定类型的类。
-5,target():限制连接点匹配目标对象为制定类型的类。
-6,@target():限制连接点匹配特定的执行对象,这些对象对应的类要具备制定注解。
-7,within():限制连接点匹配指定的类型。
-8,@within():限制连接点匹配制定注解的类型。
-9,@annotation:限制匹配带有制定注解连接点。
3,编写切点:
<aop:config><aop:aspect ref="audience"><aop:beforepointcut="execution(* chp02.springdol.Perform.perform(..))"method="takeSeat" /><aop:beforepointcut="execution(* chp02.springdol.Perform.perform(..))"method="turnOffCellPhone" /><aop:after-returningpointcut="execution(* chp02.springdol.Perform.perform(..))"method="applaud" /><aop:after-throwingpointcut="execution(* chp02.springdol.Perform.perform(..))"method="demandRefund" /></aop:aspect></aop:config>
package chp04.aop;/*** 类描述:观众类,测试AOP** @author: Jing* History: Jan 7, 2015 3:33:35 PM Jing Created.**/public class Audience {public void takeSeat(){System.out.println("The audience is taking their seats.");}public void turnOffCellPhone(){System.out.println("The audience is turning off their cellphone!");}public void applaud(){System.out.println("CLAP CLAP CLAP CLAP CLAP ");}public void demandRefund(){System.out.println("Boo! we want our money back!");}}
package chp04.aop;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import chp02.springdol.Perform;/*** 类描述:** @author: Jing* History: Jan 8, 2015 4:52:20 PM Jing Created.**/public class Main {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("chp04/aop/spring.xml");Perform perform = (Perform) ctx.getBean("juggler");perform.perform();}}
输出结果The audience is taking their seats.The audience is turning off their cellphone!Juggler perform(),beanBags : 3CLAP CLAP CLAP CLAP CLAP
因为以上涉及到的切点都相同,我们可以将切点配置抽取,如下:
<aop:config><aop:aspect ref="audience"><aop:pointcut id="perform"expression="execution(* chp02.springdol.Perform.perform(..))" /><aop:before pointcut-ref="perform" method="takeSeat" /><aop:before pointcut-ref="perform"method="turnOffCellPhone" /><aop:after-returning pointcut-ref="perform"method="applaud" /><aop:after-throwing pointcut-ref="perform"method="demandRefund" /></aop:aspect></aop:config>
声明环绕通知
环绕通知java处理代码:
/**** 方法说明:环绕通知** Author: Jing Create Date: Jan 9, 2015 10:44:37 AM*/public void watchPerformance(ProceedingJoinPoint joinPoint) {try {System.out.println("The audience is taking their seats.");System.out.println("The audience is turning off their cellphone!");long start = System.currentTimeMillis();joinPoint.proceed();long end = System.currentTimeMillis();System.out.println("CLAP!CLAP!CLAP!CLAP!");System.out.println("The perform took " + ( end - start) + " s");} catch (Throwable e) {System.out.println("Exception, we want our money back! ");}}
环绕通知XML配置:
<aop:config><aop:aspect ref="audience"><aop:pointcut id="perform2"expression="execution(* chp02.springdol.Perform.perform(..))" /><aop:around pointcut-ref="perform2"method="watchPerformance" /></aop:aspect></aop:config>
为通知传递参数:
package chp04.aop;/*** 类描述:测试通知参数** @author: Jing* History: Jan 9, 2015 11:00:32 AM Jing Created.**/public interface MindReader {void interceptThoughts(String thoughts);String getThoughts();}
package chp04.aop;/*** 类描述:** @author: Jing* History: Jan 9, 2015 2:13:29 PM Jing Created.**/public class Magician implements MindReader{private String thoughts;public String getThoughts() {return thoughts;}public void setThoughts(String throughts) {this.thoughts = throughts;}@Overridepublic void interceptThoughts(String throughts) {System.out.println("intercept Thoughts");this.thoughts = throughts;}}
package chp04.aop;/*** 类描述:** @author: Jing* History: Jan 9, 2015 2:26:51 PM Jing Created.**/public interface Thinker {void thinkOfSomething(String thoughts);public String getThoughts();}
package chp04.aop;/*** 类描述:** @author: Jing* History: Jan 9, 2015 2:27:48 PM Jing Created.**/public class Volunteer implements Thinker {private String thoughts;@Overridepublic void thinkOfSomething(String thoughts) {this.thoughts = thoughts;}public String getThoughts() {return thoughts;}}
<bean id="volunteer" class="chp04.aop.Volunteer" /><bean id="magician" class="chp04.aop.Magician" /><aop:config><aop:aspect ref="magician"><aop:pointcut id="thinking" expression="execution(* chp04.aop.Thinker.thinkOfSomething(String)) and args(thoughts)"/><aop:before pointcut-ref="thinking" method="interceptThoughts" arg-names="thoughts"/></aop:aspect></aop:config>
package chp04.aop;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;/*** 类描述:** @author: Jing* History: Jan 8, 2015 4:52:20 PM Jing Created.*/public class Main {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("chp04/aop/spring.xml");// Volunteer volunteer = (Volunteer) ctx.getBean("volunteer");// volunteer.thinkOfSomething("Thinking the world!");Thinker volunteer = (Thinker) ctx.getBean("volunteer");//因为AOP配置,此处必须转换为接口volunteer.thinkOfSomething("Thinking the world!");System.out.println(volunteer.getThoughts());}}
4,通过切面引入新功能。
package chp04.aop;/*** 类描述:其他功能接口** @author: Jing* History: Jan 9, 2015 3:15:40 PM Jing Created.**/public interface Contestant {void receiveAward();}
package chp04.aop;/*** 类描述:接口实现** @author: Jing* History: Jan 9, 2015 3:25:47 PM Jing Created.**/public class GraciousContestant implements Contestant{@Overridepublic void receiveAward() {System.out.println("Auto Add method");}}
<bean id="graciousContestant" class="chp04.aop.GraciousContestant" /><aop:config><aop:aspect><aop:declare-parents types-matching="chp04.aop.Thinker+"implement-interface="chp04.aop.Contestant"delegate-ref="graciousContestant" /><!--default-impl="chp04.aop.GraciousContestant"/> 此处同delegate-ref 目的一致,声明对应接口的默认实现 --></aop:aspect></aop:config>
package chp04.aop;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;/*** 类描述:** @author: Jing* History: Jan 8, 2015 4:52:20 PM Jing Created.*/public class Main {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("chp04/aop/spring.xml");Contestant volunteer = (Contestant) ctx.getBean("volunteer");volunteer.receiveAward();}}
5,基于注解的配置
package chp04.aop;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.AfterReturning;import org.aspectj.lang.annotation.AfterThrowing;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.aspectj.lang.annotation.Pointcut;/*** 类描述:观众类,测试AOP** @author: Jing History: Jan 7, 2015 3:33:35 PM Jing Created.**/@Aspectpublic class Audience {@Pointcut("execution(* chp02.springdol.Perform.perform(..))")/*** 定义切点*/public void perform(){}@Before("perform()")public void takeSeat() {System.out.println("The audience is taking their seats.");}@Before("perform()")public void turnOffCellPhone() {System.out.println("The audience is turning off their cellphone!");}@AfterReturning("perform()")public void applaud() {System.out.println("CLAP CLAP CLAP CLAP CLAP ");}@AfterThrowing("perform()")public void demandRefund() {System.out.println("Boo! we want our money back!");}/**** 方法说明:环绕通知** Author: Jing Create Date: Jan 9, 2015 10:44:37 AM*/public void watchPerformance(ProceedingJoinPoint joinPoint) {try {System.out.println("The audience is taking their seats.");System.out.println("The audience is turning off their cellphone!");long start = System.currentTimeMillis();joinPoint.proceed();long end = System.currentTimeMillis();System.out.println("CLAP!CLAP!CLAP!CLAP!");System.out.println("The perform took " + ( end - start) + " s");} catch (Throwable e) {System.out.println("Exception, we want our money back! ");}}}
配置文件启用注解API
<aop:aspectj-autoproxy />
环绕通知:
/**** 方法说明:环绕通知** Author: Jing Create Date: Jan 9, 2015 10:44:37 AM*/@Around("perform()")public void watchPerformance(ProceedingJoinPoint joinPoint) {try {System.out.println("The audience is taking their seats.");System.out.println("The audience is turning off their cellphone!");long start = System.currentTimeMillis();joinPoint.proceed();long end = System.currentTimeMillis();System.out.println("CLAP!CLAP!CLAP!CLAP!");System.out.println("The perform took " + ( end - start) + " s");} catch (Throwable e) {System.out.println("Exception, we want our money back! ");}}
欢迎转载,但转载请注明原文链接[博客园: http://www.cnblogs.com/jingLongJun/]
[CSDN博客:http://blog.csdn.net/mergades]。
如相关博文涉及到版权问题,请联系本人。
[CSDN博客:http://blog.csdn.net/mergades]。
如相关博文涉及到版权问题,请联系本人。

浙公网安备 33010602011771号