【源码】Spring AOP 10 ProxyFactoryBean ProxyFactory AspectJProxyFactory

【源码】Spring AOP 10 ProxyFactoryBean ProxyFactory AspectJProxyFactory

前言

ProxyCreatorSupport 的三个实现类,可以用来在不同的场景下创建代理对象,本章节集合部分源码了解下这几个实现类,同时给出示例

ProxyFactoryBean

public class ProxyFactoryBean extends ProxyCreatorSupport
		implements FactoryBean<Object>, BeanClassLoaderAware, BeanFactoryAware {

	// 指定要代理的接口
	public void setProxyInterfaces(Class<?>[] proxyInterfaces) throws ClassNotFoundException {
		setInterfaces(proxyInterfaces);
	}

	// 指定拦截器的 beanName
	public void setInterceptorNames(String... interceptorNames) {
		this.interceptorNames = interceptorNames;
	}

	// ...

	@Override
	@Nullable
	public Object getObject() throws BeansException {

		// 初始化 Interceptors Chain
		initializeAdvisorChain();

		// 单例 or Prototype
		if (isSingleton()) {
			return getSingletonInstance();
		}
		else {
			return newPrototypeInstance();
		}
	}

	-------------- initializeAdvisorChain ---------------

	private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException {

		// 未初始化 & interceptorNames 不为空
		if (!this.advisorChainInitialized && !ObjectUtils.isEmpty(this.interceptorNames)) {

			// ...

			for (String name : this.interceptorNames) {
				/**
				 * 全局拦截器处理
				 * addGlobalAdvisors 方法是用前缀名称(*前的部分)匹配 beanFactory 及其父级容器中的所有
				 * 		Advisor 和 Interceptor
				 */
				if (name.endsWith(GLOBAL_SUFFIX)) {
					addGlobalAdvisors((ListableBeanFactory) this.beanFactory,
							name.substring(0, name.length() - GLOBAL_SUFFIX.length()));
				}

				// 其他拦截器处理
				else {
					Object advice;
					if (this.singleton || this.beanFactory.isSingleton(name)) {
						advice = this.beanFactory.getBean(name);
					}
					else {
						advice = new PrototypePlaceholderAdvisor(name);
					}
					addAdvisorOnChainCreation(advice);
				}
			}
			this.advisorChainInitialized = true;
		}
	}

	private void addAdvisorOnChainCreation(Object next) {
		addAdvisor(namedBeanToAdvisor(next));
	}

	// DefaultAdvisorAdapterRegistry
	private AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
	private Advisor namedBeanToAdvisor(Object next) {
		try {
			return this.advisorAdapterRegistry.wrap(next);
		}
		catch (UnknownAdviceTypeException ex) {
			// ...
		}
	}

	--------------- getSingletonInstance ---------------

	private synchronized Object getSingletonInstance() {
		if (this.singletonInstance == null) {
			// ...
			this.singletonInstance = getProxy(createAopProxy());
		}
		return this.singletonInstance;
	}
}

略去大部分,聚焦于以上部分代码:

  • 作为一个 FactoryBeanProxyFactoryBean 基于 getObject 方法提供代理对象
  • initializeAdvisorChain 方法大体逻辑为基于我们指定的 beanName 从容器中获取对应的 Advice 实例并最终包装成 Advisor,负责包装的类就是我们之前了解的 DefaultAdvisorAdapterRegistry
  • getSingletonInstance 方法忽略细节,就是调用父类的 getProxy 方法创建代理对象维护成单例返回

demo

public class ProxyFactoryBeanDemo {

    @Configuration
    public static class Config {

        @Bean
        public MethodBeforeAdvice beforeAdvice() {

            return (m, t, a) -> System.out.println("before");
        }

        @Bean
        public Advisor advisor() {
            NameMatchMethodPointcutAdvisor nameMatchMethodPointcutAdvisor
                    = new NameMatchMethodPointcutAdvisor(beforeAdvice());
            nameMatchMethodPointcutAdvisor.setMappedName("h*");
            return nameMatchMethodPointcutAdvisor;
        }

        @Bean
        public ProxyFactoryBean proxyFactoryBean() throws ClassNotFoundException {
            ProxyFactoryBean factoryBean = new ProxyFactoryBean();
            // 指定代理接口
            factoryBean.setProxyInterfaces(new Class[]{ Hello.class });
            // 指定 Advisor 的 beanName
            factoryBean.setInterceptorNames("advisor");
			// 指定 target
            factoryBean.setTarget(new HelloImpl());
            return factoryBean;
        }

    }

    public interface Hello {
        void hello();
    }

    public static class HelloImpl implements Hello {

        @Override
        public void hello() {
            System.out.println("hello");
        }
    }

    @Test
    public void test() {
        AnnotationConfigApplicationContext context
                = new AnnotationConfigApplicationContext(Config.class);
        // 获取代理对象
        Hello bean = context.getBean(Hello.class);
        bean.hello();
    }
}

显然, Spring 创建代理用的并不是这种方式,毕竟不可能给每个对象创建一个 ProxyFactoryBean

ProxyFactory

public class ProxyFactory extends ProxyCreatorSupport {

	/** 构造方法 **/

	// 指定 target,会基于 target 指定接口
	public ProxyFactory(Object target) {
		setTarget(target);
		setInterfaces(ClassUtils.getAllInterfaces(target));
	}
	// 只指定接口
	public ProxyFactory(Class<?>... proxyInterfaces) {
		setInterfaces(proxyInterfaces);
	}
	// 增加接口和 Advice
	public ProxyFactory(Class<?> proxyInterface, Interceptor interceptor) {
		addInterface(proxyInterface);
		addAdvice(interceptor);
	}
	// 增加接口,指定 TargetSource
	public ProxyFactory(Class<?> proxyInterface, TargetSource targetSource) {
		addInterface(proxyInterface);
		setTargetSource(targetSource);
	}

	/** getProxy **/

	public Object getProxy() {
		return createAopProxy().getProxy();
	}
	public Object getProxy(@Nullable ClassLoader classLoader) {
		return createAopProxy().getProxy(classLoader);
	}

	/** 静态方法 **/
	
	public static <T> T getProxy(Class<T> proxyInterface, Interceptor interceptor) {
		return (T) new ProxyFactory(proxyInterface, interceptor).getProxy();
	}
	public static <T> T getProxy(Class<T> proxyInterface, TargetSource targetSource) {
		return (T) new ProxyFactory(proxyInterface, targetSource).getProxy();
	}
	public static Object getProxy(TargetSource targetSource) {
		if (targetSource.getTargetClass() == null) {
			throw new IllegalArgumentException("Cannot create class proxy for TargetSource with null target class");
		}
		ProxyFactory proxyFactory = new ProxyFactory();
		proxyFactory.setTargetSource(targetSource);
		proxyFactory.setProxyTargetClass(true);
		return proxyFactory.getProxy();
	}
}
  • 提供了多个场景下的构造方法
  • getProxy 方法的实现如出一辙
  • 提供了对应构造方法的静态方法

demo

public class ProxyFactoryDemo {

    @Test
    public void test() {
        ProxyFactory proxyFactory = new ProxyFactory(new HelloImpl());
        proxyFactory.addAdvice(new MethodBeforeAdvice() {
            @Override
            public void before(Method method, Object[] args, Object target) throws Throwable {
                System.out.println("before");
            }
        });
        Hello proxy = ((Hello) proxyFactory.getProxy());
        proxy.hello();
    }

    public interface Hello {

        void hello();

    }

    public class HelloImpl implements Hello {

        @Override
        public void hello() {
            System.out.println("hello");
        }
    }
}

AspectJProxyFactory

这个类顾名思义,用来基于 Aspect 切面创建代理对象,就不贴源码了,跟下面这段代码原理大致相同:

	public void test() throws NoSuchMethodException {

        // MetadataAwareAspectInstanceFactory 来提供切面实例、切面元数据
        MetadataAwareAspectInstanceFactory aspectInstanceFactory
                = new SimpleMetadataAwareAspectInstanceFactory(MyAspect.class
                , "myAspect");

        // AspectJAdvisorFactory 基于此获取对应的 InstantiationModelAwarePointcutAdvisorImpl(s)
        AspectJAdvisorFactory aspectJAdvisorFactory
                = new ReflectiveAspectJAdvisorFactory();
        InstantiationModelAwarePointcutAdvisor advisor =
                (InstantiationModelAwarePointcutAdvisor) aspectJAdvisorFactory
                        .getAdvisor(
                                MyAspect.class.getMethod("hello")
                                , aspectInstanceFactory
                                , 0, "myAspect"
        );
        
        // 基于上述 InstantiationModelAwarePointcutAdvisorImpl(s) 创建代理
    }

简单的概括就是:

  • MetadataAwareAspectInstanceFactory 负责维护切面实例、切面元数据
  • ReflectiveAspectJAdvisorFactory 基于此可以生成对应的 InstantiationModelAwarePointcutAdvisorImpls
  • InstantiationModelAwarePointcutAdvisorImpl = AspectJExpressionPointcut + AbstractAspectJAdvice

demo

public class AspectJProxyFactoryDemoB {

    @Test
    public void test() {
        AspectJProxyFactory factory = new AspectJProxyFactory(new HelloImpl());
        factory.addAspect(MyAspect.class);
        Hello proxy = (Hello) factory.getProxy();
        proxy.hello();
    }

    @Aspect
    public static class MyAspect {

        @Pointcut("execution(* com.example.springdemoall.advised..hello())")
        public void pointcut() {

        }

        @Before("pointcut()")
        public void before() {
            System.out.println("before");
        }

    }

    public interface Hello {
        void hello();
    }

    public class HelloImpl implements Hello {

        @Override
        public void hello() {
            System.out.println("hello");
        }
    }
}

这段示例 demo 就不难理解了

总结

这章介绍了 ProxyCreatorSupport 的三个实现类,它们三个创建代理对象的方法最终都是委托到 createAopProxy().getProxy() 方法即 AopProxy#getProxy,因此下一章了解下 AopProxyFactory AopProxy

上一篇:【源码】Spring AOP 9 Advised

下一篇:【源码】Spring AOP 11 AopProxyFactory AopProxy

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值