您的位置:首页 > 编程语言 > Java开发

SpringAOP源码解析之代理创建篇

2017-12-30 18:23 661 查看

阅读须知

Spring源码版本:4.3.8

注释规则:

//单行注释做普通注释

/**/多行注释做深入分析

建议配合Spring源码阅读

正文

承接上文,在获取了所有bean匹配的增强器之后,就可以创建代理了:

AbstractAutoProxyCreator:

protected Object createProxy(
Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this); //复制当前对象的相关属性
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true); //proxy-target-class配置
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
for (Advisor advisor : advisors) {
proxyFactory.addAdvisor(advisor); //加入匹配的增强器
}
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
/*创建代理*/
return proxyFactory.getProxy(getProxyClassLoader());
}


ProxyFactory:

public Object getProxy(ClassLoader classLoader) {
/*创建aop代理并获取代理对象*/
return createAopProxy().getProxy(classLoader);
}


ProxyCreatorSupport:

protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
/*创建aop代理*/
return getAopProxyFactory().createAopProxy(this);
}


DefaultAopProxyFactory:

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
//判断使用哪种代理
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}


这里我们看到了Spring如何选择使用JDK动态代理还是CGLIB代理,optimize用来控制通过CGLIB创建的代理是否使用激进的优化策略,这个配置对JDK动态代理无效,不推荐使用,proxy-target-class文章开始已经介绍过,逻辑就是在这里实现的,hasNoUserSuppliedProxyInterfaces判断目标类是否没有用户自定义的代理接口。我们先看JDK动态代理的方式:

JdkDynamicAopProxy:

public Object getProxy(ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
}
/*是代理的接口完整*/
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
/*创建代理*/
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}


AopProxyUtils:

static Class<?>[] completeProxiedInterfaces(AdvisedSupport advised, boolean decoratingProxy) {
Class<?>[] specifiedInterfaces = advised.getProxiedInterfaces();
if (specifiedInterfaces.length == 0) {
Class<?> targetClass = advised.getTargetClass();
if (targetClass != null) {
if (targetClass.isInterface()) {
advised.setInterfaces(targetClass);
}
else if (Proxy.isProxyClass(targetClass)) {
advised.setInterfaces(targetClass.getInterfaces());
}
specifiedInterfaces = advised.getProxiedInterfaces();
}
}
boolean addSpringProxy = !advised.isInterfaceProxied(SpringProxy.class);
boolean addAdvised = !advised.isOpaque() && !advised.isInterfaceProxied(Advised.class);
boolean addDecoratingProxy = (decoratingProxy && !advised.isInterfaceProxied(DecoratingProxy.class));
int nonUserIfcCount = 0;
if (addSpringProxy) {
nonUserIfcCount++;
}
if (addAdvised) {
nonUserIfcCount++;
}
if (addDecoratingProxy) {
nonUserIfcCount++;
}
Class<?>[] proxiedInterfaces = new Class<?>[specifiedInterfaces.length + nonUserIfcCount];
System.arraycopy(specifiedInterfaces, 0, proxiedInterfaces, 0, specifiedInterfaces.length);
int index = specifiedInterfaces.length;
if (addSpringProxy) {
proxiedInterfaces[index] = SpringProxy.class;
index++;
}
if (addAdvised) {
proxiedInterfaces[index] = Advised.class;
index++;
}
if (addDecoratingProxy) {
proxiedInterfaces[index] = DecoratingProxy.class;
}
return proxiedInterfaces;
}


这里我们看到为即将创建的代理类添加了3个接口SpringProxy、Advised和DecoratingProxy,后面执行的过程中会用到。代理对象的创建到这里就结束了,我们会在下篇文章中继续分析AOP执行过程的源码。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: