(造轮子)手写Spring框架-AOP代理工厂

83 阅读1分钟

AOP代理工厂

代码地址:github.com/WangChao-ly…

建议订阅博主专栏,从下到上系统手写spring源码,体会其中过程!

增加AOP代理工厂ProxyFactory,由AdvisedSupport#proxyTargetClass属性决定使用JDK动态代理还是CGLIB动态代理。

  • AdvisedSupport:增加一个布尔属性,来决定使用什么代理方式。
//是否使用cglib代理
private boolean proxyTargetClass = false;

public boolean isProxyTargetClass(){
    return proxyTargetClass;
}

public void setProxyTargetClass(boolean proxyTargetClass){
    this.proxyTargetClass = proxyTargetClass;
}
  • ProxyFactory:这里是工厂的关键所在,根据用户对AdvisedSupport中proxyTargetClass设置的属性,来决定用什么类型的代理方式。
public class ProxyFactory {
    private AdvisedSupport advisedSupport;

    public ProxyFactory(AdvisedSupport advisedSupport){
        this.advisedSupport = advisedSupport;
    }

    public Object getProxy(){
        return createAopProxy().getProxy();
    }

    private AopProxy createAopProxy(){
        if(advisedSupport.isProxyTargetClass()){
            return new CglibAopProxy(advisedSupport);
        }
        return new JdkDynamicAopProxy(advisedSupport);
    }
}
  • 测试:
private AdvisedSupport support = new AdvisedSupport();

@Before
public void setup(){
    WorldService worldService = new WorldServiceImpl();
    TargetSource targetSource = new TargetSource(worldService);
    MethodMatcher methodMatcher = new AspectJExpressionPointcut("execution(* org.springframework.test.service.WorldService.explode(..))").getMethodMatcher();

    support.setMethodMatcher(methodMatcher);
    support.setMethodInterceptor(new WorldServiceInterceptor());
    support.setTargetSource(targetSource);
}

@Test
public void testProxyFactory(){
    // 使用JDK动态代理
    support.setProxyTargetClass(false);
    WorldService worldService1 = (WorldService)new ProxyFactory(support).getProxy();
    worldService1.explode();

    // 使用CGLIB动态代理
    support.setProxyTargetClass(true);
    WorldService worldService2 = (WorldService)new ProxyFactory(support).getProxy();
    worldService2.explode();
}

总结:工厂模式不是第一次在spring中用到,之前的实例化方式也同样用到了这种策略工厂模式,具体回顾Bean的实例化策略处。