HelloWorld 善战者,求之于势,不责于人;故能择人而任势。

知止而后有定,定而后能静,静而后能安,安而后能虑,虑而后能得。物有本末,事有终始。知所先后,则近道矣。

  BlogJava :: 首页 ::  :: 联系 ::  :: 管理 ::
  167 随笔 :: 1 文章 :: 40 评论 :: 0 Trackbacks
 

4.1 AOP入门

l         从代理机制初探AOP

例子4.1.1

interface IHi {

    public void sayHi(String name);

}

class HiSpeaker implements IHi {

    public void sayHi(String name) {

       System.out.println("Hi, " + name);

    }

}

public class LogHandler implements InvocationHandler {

    private Logger logger = Logger.getLogger(this.getClass().getName());

    private Object delgate;

   

    public Object bind(Object delgate) {

       this.delgate = delgate;

       return Proxy.newProxyInstance(delgate.getClass().getClassLoader(),

                                   delgate.getClass().getInterfaces(),

                                   this);

    }

    public Object invoke(Object proxy, Method method, Object[] args)

           throws Throwable {

       Object result = null;

       try {

           log("method starts ... " + method);

           result = method.invoke(delgate, args);

           log("method ends ... " + method);

       } catch (Exception e) {

           log(e.toString());

       }

       return result;

    }

    private void log(String msg) {

       logger.log(Level.INFO, msg);

    }

    public static void main(String args[]) {

       LogHandler log = new LogHandler();

       IHi helloProxy = (IHi)log.bind(new HiSpeaker());

       helloProxy.sayHi("张怡宁");

    }

}

运行结果:

Hi, 张怡宁

2008-8-25 22:22:40 com.spring.ch4.LogHandler log

信息: method starts ... public abstract void com.spring.ch4.IHi.sayHi(java.lang.String)

2008-8-25 22:22:40 com.spring.ch4.LogHandler log

信息: method ends ... public abstract void com.spring.ch4.IHi.sayHi(java.lang.String)

 

l         AOP观念与术语

Ø         Cross-cutting concern

    在前面的例子4.1.1中,日志的动作原先被横切(Cross-cutting)入至HiSpeaker本身所负责的业务流程之中,另外类似日志这类的动作,如安全(security)、检查、事务(Transaction)等系统层面的服务(Service),在一些应用程序之中常被见到安插到各个对象的处理流程中,这些动作在Aop术语中称为Cross-cutting concernsCorss-cutting concern若直接编写在负责业务的对象流程中,会使得维护程序的成本增高,若要修改或者移除对象中的日志功能,则必须修改所有编写日志服务的程序代码,然后重新编译,另一方面,Cross-cutting concerns 混杂于业务逻辑之中,使得业务对象本身的逻辑或者程序的编写更为复杂。

Ø         Aspect

    将散落于业务逻辑之中的Cross-cutting concerns 收集起来,设计成为各个独立可重用的对象,这些对象成为Aspect。例如在上面的例子4.1.1,将日志的动作设计成一个LogHandler类,LogHandler类在AOP的术语就是Aspect的一个具体实例。在AOP中着重于Aspect的辨认,使之从业务流程中独立出来。在需要该服务的时候,织入(Weave)至应用程序之上;不需要服务的时候,可以马上从程序中脱离,且应用程序中的可用组件不做任何修改。例如例子4.1.1HiSpeaker就是一个可重用的组件,在他需要日志服务时并不用修改本身的程序代码。另一方面,对于程序中可重用的组件来说,按照AOP的设计方法,他不用知道提供服务的对象是否成立,具体的说,与服务相关的API不会出现可重用的应用程序之中,因而可提高这些组件的重用性,可以将这些组件应用到其他的程序中,不会因为加入了某些服务而与目前的应用程序框架发生耦合。

Ø         Advice

    Aspect当中对Cross-cutting concerns的具体实现称为Advice。以日志的动作而言,Advice中会包括日志程序代码是如何实现的,像例子4.1.1LogHandlerinvoke()方法,就是Advice的一个具体实例。Advice中包括了Cross-cutting concerns的行为或所要提供的服务。

Ø         Joinpoint

    Advice在程序执行时加入业务程序的点或时机称为Joinpoint,具体来说就是Advice在程序中被执行的时机。Spring只支持方法的Joinpoint,执行时机可能是某个方法被执行之前或之后,或是方法中某个异常发生的时候。

Ø         Pointcut

    Pointcut定义了感兴趣的Jointpoint,当调用的方法符合Pointcut表示式时,将Advice织入到程序上提供服务。具体在Spring中,可以在定义文件或Annotation中编写Pointcut,说明哪些Advice要应用到方法的前后。

Ø         Target

    一个Advice被应用的对象或目标对象,例子4.1.1中的HiSpeaker就是LogHandlerAdviceTarget

Ø         Introduction

    对于一个现存的类,Introduction可以为其增加行为,且不用修改该类的程序,具体来说,可以为某个已编写或者编译完的类,在执行时期动态地加入一些方法或行为,而不用修改或新增任何一行程序代码。

Ø         Proxy

    SpringAOP主要通过动态代理来完成的,可用于代理任何的接口。另一方面,Spring也可以使用CGLIB代理,用以代理类,像一些遗留类(Legacy classes)

Ø         Weaver

    Advice被应用到对象之上的过程称为织入(Weave),AOP中织入的方式有几个时间点:编译时期,类加载时期,执行时期。

l         Spring AOP(省略)

 

4.2            Advice

      Advice实现了Aspect的真正逻辑,具体来说在Java中就是一个类或者设计成一个方法(由一个类来集中管理许多的Advices)。由于织入Targets的时机不同,Spring提供了几种不同的Advice,Before AdviceAfter AdviceAround AdviceThrow Advice。可以从编写、使用Advices来认识Spring AOP

l         Before Advice

      Before Advice 会在目标对象的方法执行之前被调用,可以实现org.springframework.aop.MethodBeforeAdvice接口来实现Before Advice的逻辑 。

例子4.2.1

<bean id="logBeforeAdvice" class="com.spring.ch4.LogBeforeAdvice"></bean>

<bean id="helloSpeaker" class="com.spring.ch4.HelloSpeaker"></bean>

<bean id="helloProxy" class="org.springframework.aop.framework.ProxyFactoryBean">

    <property name="proxyInterfaces" value="com.spring.ch4.IHello"></property>

    <property name="target" ref="helloSpeaker"></property>

    <property name="interceptorNames">

       <list><value>logBeforeAdvice</value></list>

    </property>

</bean>

interface IHello {

    public void hello(String name);

}

class HelloSpeaker implements IHello {

    public void hello(String name) {

       System.out.println("Hello, " + name);

    }

}

class LogBeforeAdvice implements MethodBeforeAdvice {

    private Logger logger = Logger.getLogger(this.getClass().getName());

    public void before(Method method, Object[] args, Object target)

           throws Throwable {

       logger.log(Level.INFO, "before method starts... " + method);

    }

}

public class BeforeAdviceDemo {

    public static void main(String args[]) {

       AbstractApplicationContext context =

           new ClassPathXmlApplicationContext("beans.xml");

       IHello proxy = (IHello)context.getBean("helloProxy");

       proxy.hello("张怡宁");

    }

}

运行结果为:

2008-8-26 22:38:48 com.spring.ch4.LogBeforeAdvice before

信息: before method starts... public abstract void com.spring.ch4.IHello.hello(java.lang.String)

Hello, 张怡宁

 

l         After Advice

    After Advice 会在目标方法执行之后被调用,可以实现org.springframework.aop.AfterReturningAdvice

class LogAfterAdvice implements AfterReturningAdvice {

    private Logger logger = Logger.getLogger(this.getClass().getName());

    public void afterReturning(Object object, Method method, Object[] args, Object target)

           throws Throwable {

       logger.log(Level.INFO, "after method starts... " + method);

    }

}

<bean id="helloProxy" class="org.springframework.aop.framework.ProxyFactoryBean">

    <property name="proxyInterfaces" value="com.spring.ch4.IHello"></property>

    <property name="target" ref="helloSpeaker"></property>

    <property name="interceptorNames">

       <list>

           <value>logBeforeAdvice</value>

           <value>logAfterAdvice</value>

       </list>

    </property>

</bean>

 

运行结果为:

2008-8-26 22:55:53 com.spring.ch4.LogBeforeAdvice before

信息: before method starts... public abstract void com.spring.ch4.IHello.hello(java.lang.String)

Hello, 张怡宁

2008-8-26 22:55:53 com.spring.ch4.LogAfterAdvice afterReturning

信息: after method starts... public abstract void com.spring.ch4.IHello.hello(java.lang.String)

 

 

l         Around Advice

    如果要在方法执行前后加入Advices的服务逻辑,可以通过实现org.aopalliance.intercept.MethodInterceptor接口,在方法执行前、执行后执行相关的服务。MethodInvocationproceed()方法来执行目标对象的方法。Proceed()会回传方法执行后的Object执行结果,所以在invoke()结束之前,你有机会修改这个对象,或者回传一个不相干的对象。

public class LogInterceptor implements MethodInterceptor {

    private Logger logger = Logger.getLogger(this.getClass().getName());

 

    public Object invoke(MethodInvocation methodInvocation) throws Throwable {

       logger.log(Level.INFO, "method starts..." + methodInvocation.getMethod());

       Object obj = null;

       try {

           obj = methodInvocation.proceed();

       } catch (Exception e) {

          

       } finally {

           logger.log(Level.INFO, "method ends..." + methodInvocation.getMethod());

       }

       return obj;

    }

}

<bean id="helloProxy" class="org.springframework.aop.framework.ProxyFactoryBean">

    <property name="proxyInterfaces" value="com.spring.ch4.IHello"></property>

    <property name="target" ref="helloSpeaker"></property>

    <property name="interceptorNames">

       <list>

       <!--

           <value>logBeforeAdvice</value>

           <value>logAfterAdvice</value>

        -->

        <value>logInterceptor</value>

       </list>

    </property>

</bean>

<bean id="logInterceptor" class="com.spring.ch4.LogInterceptor"></bean>

 

2008-8-28 21:43:50 com.spring.ch4.LogInterceptor invoke

信息: method starts...public abstract void com.spring.ch4.IHello.hello1(java.lang.String)

2008-8-28 21:43:50 com.spring.ch4.LogInterceptor invoke

信息: method ends...public abstract void com.spring.ch4.IHello.hello1(java.lang.String)

Hello1, 张怡宁

 

l         Throw Advice

       如果要在异常发生时通知某些服务对象做某些事,可以使用Throws Advice,Spring中要使用,必须使用org.springframework.aop.ThrowsAdvice接口,然而这个接口没有定义任何方法,只是一个标签接口,可以在当中定义afterThrowing([Method],[args],[target], subClassOfThrowable);括号中的设置可以省略,方法中一定要的是subClassOfThrowable。注意到当异常发生的时候,Throw Advice的任务只是执行对应的方法,并不能在Throw Advice并不介入应用程序的异常处理,异常处理仍旧是应用程序本省所要负责的,如果想要在Throw Advice处理时中止应用程序的处理流程,做法是丢出其他的异常。

interface IHello {

       public void hello1(String name) throws Throwable;

}

 

class HelloSpeaker implements IHello {

       public void hello1(String name) throws Throwable {

              System.out.println("Hello2, " + name);

              throw new Exception("发生异常...");

       }

}

public class SomeThrowAdvice implements ThrowsAdvice {

       private Logger logger = Logger.getLogger(this.getClass().getName());

       public void afterThrowing(Method method, Object[] args, Object target, Throwable subclass) {

              logger.log(Level.INFO,"Logging that a " + subclass + "Exception was thrwon in " + method.getName());

       }

}

<bean id="helloProxy" class="org.springframework.aop.framework.ProxyFactoryBean">

    <property name="proxyInterfaces" value="com.spring.ch4.IHello"></property>

    <property name="target" ref="helloSpeaker"></property>

    <property name="interceptorNames">

       <list>

       <!--

           <value>logBeforeAdvice</value>

           <value>logAfterAdvice</value>

           <value>logInterceptor</value>

        -->

        <value>someThrowAdvice</value>

       </list>

    </property>

</bean>

Hello2, 张怡宁

2008-8-28 22:15:15 com.spring.ch4.SomeThrowAdvice afterThrowing

信息: Logging that a java.lang.Exception: 发生异常...Exception was thrwon in hello1

java.lang.Exception: 发生异常...

 

4.3            PointcutAdvisor

l         NameMatchMethodPointcutAdvisor

       Spring中内建的Pointcut都有对应的PointcutAdvisor, org.springframework.aop.support.NameMatchMethodPointcutAdvisor是最基本的Pointcut,用来提供spring中静态的Pointcut实例,可使用表达式指定Advice应用目标上的方法名称,或者是用*来指定,例如当hello*表示执行代理对上以hello作为开头的方法名称,它都会应用制定的Advices

interface IName {

    public void helloNewbie(String name);

    public void helloMaster(String name);

}

 

class NameSpeaker implements IName {

    public void helloMaster(String name) {

       System.out.println("你好 " + name +" master!");

    }

 

    public void helloNewbie(String name) {

       System.out.println("你好 " + name +" newbie!");

    }

   

}

 

public class NameMatchDemo {

    public static void main(String args[]) {

       AbstractApplicationContext context =

           new ClassPathXmlApplicationContext("beans.xml");

       IName name = (IName)context.getBean("helloProxy");

       name.helloMaster("刘德华");

       name.helloNewbie("张怡宁");

    }

}

<bean id="logBeforeAdvice" class="com.spring.ch4.LogBeforeAdvice"></bean>

<bean id="nameAdvisor"

    class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">

    <property name="mappedName" value="*Newbie"></property>

<!—

<property name=”mappedNames”>

    <list>

       <value>helloNewbie</value>

       <value>helloMaster</value>

    </list>

</property>

 -->

    <property name="advice" ref="logBeforeAdvice"></property>

</bean>

<bean id="nameSpeaker" class="com.spring.ch4.NameSpeaker"></bean>

 

<bean id="helloProxy"

    class="org.springframework.aop.framework.ProxyFactoryBean">

    <property name="proxyInterfaces"

       value="com.spring.ch4.IName">

    </property>

    <property name="target" ref="nameSpeaker"></property>

    <property name="interceptorNames">

       <list>

           <value>nameAdvisor</value>

       </list>

    </property>

</bean>

你好 刘德华 master!

你好 张怡宁 newbie!

2008-9-2 21:09:25 com.spring.ch4.LogBeforeAdvice before

信息: before method starts... public abstract void com.spring.ch4.IName.helloNewbie(java.lang.String)

 

l         RegExpMethodPointcutAdvisor

    .   符合任何单一字符

    +   前一个字符出现一次或者多次

    *   前一个字符出现零次或者多次

    \   Escape任何Regular expression使用到的符号

    RegexpMethodPointcutAdvisor”pattern”属性让你指定要符合的完整类名称(包括包名称)和方法名称,例如若要求符合com.test.Ihello下得到hello开始的方法名称,则要如下编写:

    com\.test\.Ihello\.hello.*

<bean id="regExpAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">

    <property name="pattern" value=".*Newbie"></property>

    <property name="advice" ref="logBeforeAdvice"></property>

</bean>

 

<bean id="nameSpeaker" class="com.spring.ch4.NameSpeaker"></bean>

 

<bean id="helloProxy"

    class="org.springframework.aop.framework.ProxyFactoryBean">

    <property name="proxyInterfaces"

       value="com.spring.ch4.IName">

    </property>

    <property name="target" ref="nameSpeaker"></property>

    <property name="interceptorNames">

       <list>

           <value>regExpAdvisor</value>

       </list>

    </property>

</bean>

 

l         ControlFlowPointcut

    Org.springframework.aop.support.ControlFlowPointcutspring所提供的类,作用是判断在方法的执行堆栈中,某个指定类的某个方法是否曾经要求目标对象执行某个动作,由用户这在执行时期才会确定是否介入Advices,所以Spring提供的是动态Pointcut功能。

 

4.4            Introduction

       spring中,Introduction是一种特殊的Advice,从行为上来看,它不像Before Advice, After AdviceAdvice在方法前后介入服务,而是直接介入整个对象的行为,就好像对象凭空多了一些可操作的行为,为对象动态加入原先没有的职责。

l         IntroductionInterceptor

       Introduction是个特别的Advice,从用户的角度来看,动态地为对象增加可操作的方法显的不可思议,可以通过实现org.springframework.aop.IntroductionInterceptor来实现IntroductionIntroductionInterceptor继承了MethodInterceptorDynamicIntroductionAdvice接口,其中implementsInterface()方法如果传回true,表示目前的IntroductionInterceptor实现了规定的接口(也就是额外要增加行为的接口),此时你要执行invoke(),让目标对象执行额外的行为,不可以使用MethodInvocationproceed()方法,因为要执行的是对象上原来没有的行为,执行proceed()方法没有意义。

interface ISome {

    public void doSome();

}

class SomeA implements ISome {

    public void doSome() {

       System.out.println("原来对象的职责...");

    }

}

interface IOther {

    public void doOther();

}

class OtherIntroduction implements IntroductionInterceptor, IOther {

    public Object invoke(MethodInvocation methodInvocation) throws Throwable {

       if (implementsInterface(methodInvocation.getMethod().getDeclaringClass())) {

           return methodInvocation.getMethod().invoke(this, methodInvocation.getArguments());

       } else {

           return methodInvocation.proceed();

       }

    }

    public boolean implementsInterface(Class cls) {

       return cls.isAssignableFrom(IOther.class);

    }

    public void doOther() {

       System.out.println("增加对象的职责...");

    }

}

public class IntroductionDemo {

    public static void main(String args[]) {

       AbstractApplicationContext context =

           new ClassPathXmlApplicationContext("beans.xml");

       ISome some = (ISome)context.getBean("otherProxy");

       some.doSome();

       ((IOther)some).doOther();

    }

}

 

<bean id="someA" class="com.spring.ch4.SomeA"></bean>

<bean id="otherIntroduction" class="com.spring.ch4.OtherIntroduction"></bean>

<bean id="otherAdviser" class="org.springframework.aop.support.DefaultIntroductionAdvisor">

    <constructor-arg ref="otherIntroduction"></constructor-arg>

    <constructor-arg value="com.spring.ch4.IOther"></constructor-arg>

</bean>

<bean id="otherProxy"

    class="org.springframework.aop.framework.ProxyFactoryBean">

    <property name="proxyInterfaces"

       value="com.spring.ch4.ISome">

    </property>

    <property name="target" ref="someA"></property>

    <property name="interceptorNames">

       <list>

           <value>otherAdviser</value>

       </list>

    </property>

</bean>

原来对象的职责...

增加对象的职责...

 

l         DelegatingIntroductionInterceptor

       org.springframework.aop.support.DelegatingIntroductionInterceptorSpring Aop中为IntroductionInterceptor接口所提供的实现类。你可以直接继承这个类,添加希望为目标增加的行为,并可以有自己的状态,比如让对象拥有”,”锁定的状态。

interface ISome {

    public void setSome(String some) ;

    public String getSome();

}

class SomeA implements ISome {

    private String some;

    public String getSome() {

       return some;

    }

    public void setSome(String some) {

       this.some = some;

    }

}

interface ILockable {

    public void lock();

    public void unlock();

    public boolean isLock();

}

class OtherIntroduction extends DelegatingIntroductionInterceptor implements ILockable {

    private boolean locked;

    public Object invoke(MethodInvocation methodInvocation) throws Throwable {

       if (isLock() && methodInvocation.getMethod().getName().indexOf("set") == 0) {

           throw new AopConfigException("对象锁定!!");

       }

       return super.invoke(methodInvocation);

    }

    public boolean isLock() {

       return locked;

    }

    public void lock() {

       this.locked = true;

    }

    public void unlock() {

       this.locked = false;

    }

}

public class IntroductionDemo {

    public static void main(String args[]) {

       AbstractApplicationContext context =

           new ClassPathXmlApplicationContext("beans.xml");

       ISome some = (ISome)context.getBean("otherProxy");

       some.setSome("张怡宁");

       System.out.println(some.getSome());

       try {

           ((ILockable)some).lock();

           some.setSome("默认");

           System.out.println(some.getSome());

       } catch (Exception e) {

           e.printStackTrace();

       }

       ((ILockable)some).unlock();

       some.setSome("默认X");

       System.out.println(some.getSome());

    }

}

<bean id="someA" class="com.spring.ch4.SomeA"></bean>

<bean id="otherIntroduction" class="com.spring.ch4.OtherIntroduction"></bean>

<bean id="otherAdviser" class="org.springframework.aop.support.DefaultIntroductionAdvisor">

    <constructor-arg ref="otherIntroduction"></constructor-arg>

    <constructor-arg value="com.spring.ch4.ILockable"></constructor-arg>

</bean>

<bean id="otherProxy"

    class="org.springframework.aop.framework.ProxyFactoryBean">

    <property name="proxyInterfaces"

       value="com.spring.ch4.ISome">

    </property>

    <property name="target" ref="someA"></property>

    <property name="interceptorNames">

       <list>

           <value>otherAdviser</value>

       </list>

    </property>

</bean>

张怡宁

org.springframework.aop.framework.AopConfigException: 对象锁定!!

     at com.spring.ch4.OtherIntroduction.invoke(IntroductionDemo.java:34)

     at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)

     at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)

     at com.spring.ch4.$Proxy1.setSome(Unknown Source)

     at com.spring.ch4.IntroductionDemo.main(IntroductionDemo.java:60)

默认X

 

4.5            Autoproxing

       自动代理可以不用为每一个目标对象手动定义代理对象,使用自动代理,你可以通过Bean名称或是Pointcut对比,自动为符合对比条件的目标对象建立代理对象。

 

l         BeanNameAutoProxyCreator

       如果要为目标提供Advice,则必须为他们建立代理对象,在程序规模大的时候,如果要提供Advice的目标对象很多,一个一个为他们建立代理是麻烦的事,Spring为一些情况提供了自动代理。

       你可以为目标对象取好适当的Bean名称,例如某些服务对象取名为xxxService,这个样使用org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator来为这些Bean设置自动代理,只要改一下配置文件就可以了:

interface ISome {

    public void setSome(String some) ;

    public String getSome();

}

class SomeA implements ISome {

    private String some;

    public String getSome() {

       return some;

    }

    public void setSome(String some) {

       this.some = some;

    }

}

interface ILockable {

    public void lock();

    public void unlock();

    public boolean isLock();

}

class OtherIntroduction extends DelegatingIntroductionInterceptor implements ILockable {

    private boolean locked;

    public Object invoke(MethodInvocation methodInvocation) throws Throwable {

       if (isLock() && methodInvocation.getMethod().getName().indexOf("set") == 0) {

           throw new AopConfigException("对象锁定!!");

       }

       return super.invoke(methodInvocation);

    }

    public boolean isLock() {

       return locked;

    }

    public void lock() {

       this.locked = true;

    }

    public void unlock() {

       this.locked = false;

    }

}

public class IntroductionDemo {

    public static void main(String args[]) {

       AbstractApplicationContext context =

           new ClassPathXmlApplicationContext("beans.xml");

       ISome some = (ISome)context.getBean("someService");

       some.setSome("张怡宁");

       System.out.println(some.getSome());

       try {

           ((ILockable)some).lock();

           some.setSome("默认");

           System.out.println(some.getSome());

       } catch (Exception e) {

           e.printStackTrace();

       }

       ((ILockable)some).unlock();

       some.setSome("默认X");

       System.out.println(some.getSome());

    }

}

<bean id="someService" class="com.spring.ch4.SomeA"></bean>

<bean id="otherIntroduction" class="com.spring.ch4.OtherIntroduction"></bean>

<bean id="otherAdviser" class="org.springframework.aop.support.DefaultIntroductionAdvisor">

    <constructor-arg ref="otherIntroduction"></constructor-arg>

    <constructor-arg value="com.spring.ch4.ILockable"></constructor-arg>

</bean>

<bean id="otherProxy"

    class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">

    <property name="beanNames">

       <list>

           <value>*Service</value>

       </list>

    </property>

    <property name="interceptorNames" value="otherAdviser"></property>

</bean>

 

org.springframework.aop.framework.AopConfigException: 对象锁定!!

     at com.spring.ch4.OtherIntroduction.invoke(IntroductionDemo.java:34)

     at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)

     at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)

     at com.spring.ch4.$Proxy1.setSome(Unknown Source)

     at com.spring.ch4.IntroductionDemo.main(IntroductionDemo.java:60)

张怡宁

默认X

 

 

l         DefaultAdvisorAutoProxyCreator

       Bean文件定义被读取完之后,DefaultAdvisorAutoProxyCreator会自动搜索所有的Advisor,并自动将Advisor应用到符合Pointcuts的目标对象上。

<bean id="someService" class="com.spring.ch4.SomeA"></bean>

<bean id="otherIntroduction" class="com.spring.ch4.OtherIntroduction"></bean>

<bean id="otherAdviser" class="org.springframework.aop.support.DefaultIntroductionAdvisor">

     <constructor-arg ref="otherIntroduction"></constructor-arg>

     <constructor-arg value="com.spring.ch4.ILockable"></constructor-arg>

</bean>

<bean id="autoProxyCreator" class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"></bean>

执行结果同上

 



</script>

posted on 2008-09-03 22:39 helloworld2008 阅读(441) 评论(0)  编辑  收藏 所属分类: java - spring

只有注册用户登录后才能发表评论。


网站导航: