除了通过使用 <aop:config><aop:aspectj-autoproxy>在你的配置中声明切面之外,还可以通过编程创建代理,为目标对象提供 advice 。关于 Spring 的 AOP API 的全部细节,请看下一章。在这里,我们想着重介绍一下通过使用 @AspectJ切面来自动创建代理的能力。

你可以使用 org.springframework.aop.aspectj.annotation.AspectJProxyFactory类来为一个目标对象创建代理,该对象由一个或多个 @AspectJ切面 advice。这个类的基本用法非常简单,如下面的例子所示:

  1. // 创建一个工厂,为给定的目标对象生成一个代理。
  2. AspectJProxyFactory factory = new AspectJProxyFactory(targetObject);
  3. // 添加一个切面,该类必须是一个 @Aspect 注解的类
  4. // 你可以根据需要在不同的切面多次调用这个方法
  5. factory.addAspect(SecurityManager.class);
  6. // 你也可以添加现有的切面实例,提供的对象的类型必须是 @Aspect 切面
  7. factory.addAspect(usageTracker);
  8. // 现在得到代理对象
  9. MyInterfaceType proxy = factory.getProxy();

更多信息见 javadoc

例子

目标接口

  1. package cn.mrcode.study.springdocsread.aspect;
  2. /**
  3. * @author mrcode
  4. */
  5. public interface Pojo {
  6. void foo();
  7. void bar();
  8. }

目标接口实现

  1. package cn.mrcode.study.springdocsread.aspect;
  2. /**
  3. * @author mrcode
  4. */
  5. public class SimplePojo implements Pojo {
  6. public void foo() {
  7. this.bar();
  8. }
  9. public void bar() {
  10. System.out.println(this);
  11. }
  12. }

声明一个切面

  1. package cn.mrcode.study.springdocsread.aspect;
  2. import org.aspectj.lang.JoinPoint;
  3. import org.aspectj.lang.annotation.Aspect;
  4. import org.aspectj.lang.annotation.Before;
  5. /**
  6. * @author mrcode
  7. */
  8. @Aspect
  9. public class MyPojoAspect {
  10. @Before("execution(* cn.mrcode.study.springdocsread.aspect.SimplePojo.*(..))")
  11. public void test(JoinPoint point) {
  12. System.out.println("代理的方法:" + point.getSignature());
  13. }
  14. }

编程代理

  1. package cn.mrcode.study.springdocsread.aspect;
  2. import org.springframework.aop.aspectj.annotation.AspectJProxyFactory;
  3. /**
  4. * @author mrcode
  5. */
  6. public class DemoTest {
  7. public static void main(String[] args) {
  8. final SimplePojo targetObject = new SimplePojo();
  9. // 创建一个工厂,为给定的目标对象生成一个代理。
  10. AspectJProxyFactory factory = new AspectJProxyFactory(targetObject);
  11. // 添加一个切面,该类必须是一个 @AspectJ 注解的类
  12. // 你可以根据需要在不同的切面多次调用这个方法
  13. factory.addAspect(MyPojoAspect.class);
  14. // 现在得到一个代理对象
  15. // 这里得到的是一个 jdk 动态代理
  16. Pojo proxy = factory.getProxy();
  17. proxy.foo();
  18. System.out.println(proxy);
  19. }
  20. }

输出信息如下

  1. 代理的方法:void cn.mrcode.study.springdocsread.aspect.Pojo.foo()
  2. cn.mrcode.study.springdocsread.aspect.SimplePojo@1d296da
  3. cn.mrcode.study.springdocsread.aspect.SimplePojo@1d296da