Spring AOP 2.0 研究

来源:互联网 发布:mysql存储引擎 编辑:程序博客网 时间:2024/04/28 09:53
我们用Hello的例子来诠释Spring AOP 2.0 的特性。
Hello
public interface Hello {void sayHelloBefore();void sayHelloAfter();void sayHelloAround();}

SayHello
public class SayHello implements Hello{/** *  */public void sayHelloBefore() {System.out.println("say Hello before!");}/** *  */public void sayHelloAfter() {System.out.println("say Hello after!");}/** *  */public void sayHelloAround() {System.out.println("say Hello around!");}}

Before
public class Before {public void invoke(JoinPoint joinPoint) {System.out.println("Before:" + joinPoint.getSignature().getName());}}

After
public class After {public void invoke(JoinPoint joinPoint) {System.out.println("After:" + joinPoint.getSignature().getName());}}

Around
public class Around {public Object invoke(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println("Around:" + joinPoint.getSignature().getName());return joinPoint.proceed();}}

Introduction
public class Introduction {public Object invoke(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println("Introduction:" + joinPoint.getSignature().getName());return joinPoint.proceed();}}

Introduction 引入的作用在于是一个类在不做任何代码修改的前提下,拥有另一套方法,或者说具备另一套本领,比如我们现在就想让这个实现了Hello接口的SayHello类拥有Ok接口的方法
public interface Ok {void sayOk();}

IntroductionOk  首先要解决上述接口Ok的实现
public class IntroductionOk implements Ok { @Overridepublic void sayOk() {System.out.println("Ok!");}}

AllTest
public class AllTest {private ApplicationContext app;/** * @throws java.lang.Exception */@Beforepublic void setUp() throws Exception {app = new ClassPathXmlApplicationContext("applicationContext.xml");}@Testpublic final void testHello() {Hello hello = (Hello) app.getBean("hello");hello.sayHelloBefore();hello.sayHelloAfter();hello.sayHelloAround();// 由于对Hello接口进行了引入,// 使得实现了Hello接口的类可以具备Ok接口的功能。// 同时,我们可以拦截这个方法让他执行其他我们需要执行的操作hello.sayHelloIntroduction();((Ok) hello).sayOk();}}

关于表达式符号
.*+定义目标为包下的所有类
+定义目标为该接口的所有实现类
<?xml version="1.0" encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"><beanid="hello"class="org.zlex.aop.SayHello" /><!-- after --><beanid="after"class="org.zlex.aop.After" /><aop:config><aop:pointcutid="afterPoint"expression="execution(* org.zlex.aop.Hello.sayHelloAfter(..))" /><aop:aspectid="afterAspect"ref="after"><aop:aftermethod="invoke"pointcut-ref="afterPoint" /></aop:aspect></aop:config><!-- before --><beanid="before"class="org.zlex.aop.Before" /><aop:config><aop:pointcutid="beforePoint"expression="execution(* org.zlex.aop.Hello.sayHelloBefore(..))" /><aop:aspectid="beforeAspect"ref="before"><aop:beforemethod="invoke"pointcut-ref="beforePoint" /></aop:aspect></aop:config><!-- around --><beanid="around"class="org.zlex.aop.Around" /><aop:config><aop:pointcutid="aroundPoint"expression="execution(* org.zlex.aop.Hello.sayHelloAround(..))" /><aop:aspectid="aroundAspect"ref="around"><aop:aroundmethod="invoke"pointcut-ref="aroundPoint" /></aop:aspect></aop:config><!-- introduction --><!-- .*+是用于包下的,不是用于接口+定义目标为该接口的所有实现类 --><beanid="introduction"class="org.zlex.aop.Introduction" /><beanid="introductionOk"class="org.zlex.aop.IntroductionOk" /><aop:config><aop:aspectref="introduction"><aop:pointcutid="introductionPoint"expression="execution(* org.zlex.aop.Hello.sayHelloIntroduction(..))" /><aop:declare-parentsimplement-interface="org.zlex.aop.Ok"types-matching="org.zlex.aop.Hello+"delegate-ref="introductionOk" /><aop:aroundmethod="invoke"pointcut-ref="introductionPoint" /></aop:aspect></aop:config></beans>

执行查看日志:
引用

Before:sayHelloBefore
say SayHello before!
say Hello after!
After:sayHelloAfter
Around:sayHelloAround
say Hello around!
Introduction:sayHelloIntroduction
say Hello introduction!
Ok!

仔细观察
引用

Before:sayHelloBefore
say Hello before!

在输出say Hello before!前输出Before:sayHelloBefore
引用

say Hello after!
After:sayHelloAfter

在输出say Hello after!后输出After:sayHelloAfter
Around比较特殊,可以用ProceedingJoinPoint调用proceed()方法
引用

Around:sayHelloAround
say Hello around!

引用

Introduction:sayHelloIntroduction
say Hello introduction!
Ok!

同样是Hello接口,在执行了sayHelloIntroduction方法时被拦截,同时输出say Hello introduction!,此时还可以执行Ok的方法输出
引用
Ok!
。显然,Hello的实现类多了Ok接口的本领。
Spring Beans 结构图如下:

如此这样,就可以控制AOP了,当前资料少,实例也少,继续研究!希望能做出来点实际的东西。
原创粉丝点击