除了通过使用 <aop:config>或 <aop:aspectj-autoproxy>在你的配置中声明切面之外,还可以通过编程创建代理,为目标对象提供 advice 。关于 Spring 的 AOP API 的全部细节,请看下一章。在这里,我们想着重介绍一下通过使用 @AspectJ切面来自动创建代理的能力。
你可以使用 org.springframework.aop.aspectj.annotation.AspectJProxyFactory类来为一个目标对象创建代理,该对象由一个或多个 @AspectJ切面 advice。这个类的基本用法非常简单,如下面的例子所示:
// 创建一个工厂,为给定的目标对象生成一个代理。AspectJProxyFactory factory = new AspectJProxyFactory(targetObject);// 添加一个切面,该类必须是一个 @Aspect 注解的类// 你可以根据需要在不同的切面多次调用这个方法factory.addAspect(SecurityManager.class);// 你也可以添加现有的切面实例,提供的对象的类型必须是 @Aspect 切面factory.addAspect(usageTracker);// 现在得到代理对象MyInterfaceType proxy = factory.getProxy();
更多信息见 javadoc。
例子
目标接口
package cn.mrcode.study.springdocsread.aspect;/*** @author mrcode*/public interface Pojo {void foo();void bar();}
目标接口实现
package cn.mrcode.study.springdocsread.aspect;/*** @author mrcode*/public class SimplePojo implements Pojo {public void foo() {this.bar();}public void bar() {System.out.println(this);}}
声明一个切面
package cn.mrcode.study.springdocsread.aspect;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;/*** @author mrcode*/@Aspectpublic class MyPojoAspect {@Before("execution(* cn.mrcode.study.springdocsread.aspect.SimplePojo.*(..))")public void test(JoinPoint point) {System.out.println("代理的方法:" + point.getSignature());}}
编程代理
package cn.mrcode.study.springdocsread.aspect;import org.springframework.aop.aspectj.annotation.AspectJProxyFactory;/*** @author mrcode*/public class DemoTest {public static void main(String[] args) {final SimplePojo targetObject = new SimplePojo();// 创建一个工厂,为给定的目标对象生成一个代理。AspectJProxyFactory factory = new AspectJProxyFactory(targetObject);// 添加一个切面,该类必须是一个 @AspectJ 注解的类// 你可以根据需要在不同的切面多次调用这个方法factory.addAspect(MyPojoAspect.class);// 现在得到一个代理对象// 这里得到的是一个 jdk 动态代理Pojo proxy = factory.getProxy();proxy.foo();System.out.println(proxy);}}
输出信息如下
代理的方法:void cn.mrcode.study.springdocsread.aspect.Pojo.foo()cn.mrcode.study.springdocsread.aspect.SimplePojo@1d296dacn.mrcode.study.springdocsread.aspect.SimplePojo@1d296da
