【源码】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;
}
}
略去大部分,聚焦于以上部分代码:
- 作为一个
FactoryBean
,ProxyFactoryBean
基于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
基于此可以生成对应的InstantiationModelAwarePointcutAdvisorImpl
sInstantiationModelAwarePointcutAdvisorImpl = 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