Spring源码分析 AOP设计实现过程
设计理念
将分散在程序各处的横切关注点剥离出来,并已集中的方式进行表达
AOP和继承有些类似,前者重点考虑程序横切逻辑,后者重点考虑纵向职责分派
AOP核心概念
Advice(通知)
-定义在连接点处的行为,围绕方法调用而进行注入
-Pointcut(切点)
-确定在哪些连接点处应用通知
Advisor()通知器
-组合Advice与Pointcut
AOP 代理
未使用代理如下
已使用代理如下
如图所示
AOP代理可以 执行目标对象之前后都可以先执行指定好的通知器(切点和通知)
SpringAOP目标代理对象创建如下
- JDK动态代理 (代理接口)
- CGLIB(代理实现类)
AOP代理源码分析
public class ProxyFactoryBean extends ProxyCreatorSupport implements
FactoryBean, BeanClassLoaderAware, BeanFactoryAware
public Object getObject() throws BeansException {
//步骤1
initializeAdvisorChain();
//步骤2
if (isSingleton())
return getSingletonInstance();
if (targetName == null)
logger.warn("Using non-singleton proxies with singleton targets is often undesirable. Enable prototype proxies by setting the 'targetName' property.");
return newPrototypeInstance();
}
}
ProxyFactoryBean是springAop底层实现源头,构建其AOP代理
如上 步骤1
配置通知事件会调用getObject()方法,initializeAdvisorChain()会把配置的Adviser通知器方法加载到集合中,以便后续目标方法执行前后去集合中匹配,根据每个Adviser的pointcut去执行
步骤2 根据配置的 scope属性,默认是single
紧接着分析 getSingletonInstance()方法获取代理对象
private synchronized Object getSingletonInstance() {
if (singletonInstance == null) {
targetSource = freshTargetSource();
if (autodetectInterfaces && getProxiedInterfaces().length == 0
&& !isProxyTargetClass()) {
Class targetClass = getTargetClass();
if (targetClass == null)
throw new FactoryBeanNotInitializedException(
"Cannot determine target class for proxy");
//1
setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass,
proxyClassLoader));
}
super.setFrozen(freezeProxy);
//2
singletonInstance = getProxy(createAopProxy());
}
return singletonInstance;
}
public interface AopProxy {
public abstract Object getProxy();
public abstract Object getProxy(ClassLoader classloader);
}
如上 //1 表示创建出来代理对象要实现代理接口
//2 通过工厂代理创建AopProxy接口,调用其getProxy,生成代理实例
AOP选择动态代理和CGLIB 源码如下
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
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())
return new JdkDynamicAopProxy(config);
else
return CglibProxyFactory.createCglibProxy(config);
} else {
return new JdkDynamicAopProxy(config);
}
}
|
源码分析
如果目标对象实现了接口,那么Spring就会通过动态代理为目标对象生成代理对象,否则通过CGLIB代理
代理模式作用是:为其它对象提供一种代理以控制对这个对象的访问
接着分析JDK动态代理源码如下
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler,
Serializable {
public Object getProxy(ClassLoader classLoader) {
if (logger.isDebugEnabled())
logger.debug((new StringBuilder())
.append("Creating JDK dynamic proxy: target source is ")
.append(advised.getTargetSource()).toString());
Class proxiedInterfaces[] = AopProxyUtils
.completeProxiedInterfaces(advised);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
//rs Proxy
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
}
public interface InvocationHandler extends Callback {
public abstract Object invoke(Object obj, Method method, Object aobj[])
throws Throwable;
}
通过其源码发现
如上rs Proxy真正使用JDK动态代理获得代理实例,代理类需要继承InvocationHandler接口,
InvocationHandler内部只有一个抽象方法invoke(参数1指代理类,参数2指代理方法,参数3指方法参数值)
Proxy.newProxyInstance(参数1 类加载器,参数2 动态代理对象实现了接口,参数3 指InvocationHandler 实例通过反射生成对象的实例)
由此可得
JDK动态代理 实现步骤
1.创建一个实现接口InvocationHandler的类吗,它必须实现invoke方法
2.创建被代理类以及接口
3.通过proxy的静态方法创建代理
4.通过代理调用方法
CGLIB 源码如下
final class CglibAopProxy implements AopProxy, Serializable {
public Object getProxy(ClassLoader classLoader) {
if (logger.isDebugEnabled())
logger.debug((new StringBuilder())
.append("Creating CGLIB proxy: target source is ")
.append(advised.getTargetSource()).toString());
try {
Class rootClass = advised.getTargetClass();
Assert.state(rootClass != null,
"Target class must be available for creating a CGLIB proxy");
Class proxySuperClass = rootClass;
if (ClassUtils.isCglibProxyClass(rootClass)) {
proxySuperClass = rootClass.getSuperclass();
Class additionalInterfaces[] = rootClass.getInterfaces();
Class arr$[] = additionalInterfaces;
int len$ = arr$.length;
for (int i$ = 0; i$ < len$; i$++) {
Class additionalInterface = arr$[i$];
advised.addInterface(additionalInterface);
}
}
validateClassIfNecessary(proxySuperClass);
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if ((classLoader instanceof SmartClassLoader)
&& ((SmartClassLoader) classLoader)
.isClassReloadable(proxySuperClass))
enhancer.setUseCache(false);
}
enhancer.setSuperclass(proxySuperClass);
enhancer.setStrategy(new UndeclaredThrowableStrategy(java / lang
/ reflect / UndeclaredThrowableException));
enhancer.setInterfaces(AopProxyUtils
.completeProxiedInterfaces(advised));
enhancer.setInterceptDuringConstruction(false);
Callback callbacks[] = getCallbacks(rootClass);
enhancer.setCallbacks(callbacks);
enhancer.setCallbackFilter(new ProxyCallbackFilter(advised
.getConfigurationOnlyCopy(), fixedInterceptorMap,
fixedInterceptorOffset));
Class types[] = new Class[callbacks.length];
for (int x = 0; x < types.length; x++)
types[x] = callbacks[x].getClass();
enhancer.setCallbackTypes(types);
Object proxy;
//结果
if (constructorArgs != null)
proxy = enhancer.create(constructorArgTypes, constructorArgs);
else
proxy = enhancer.create();
return proxy;
} catch (CodeGenerationException ex) {
throw new AopConfigException(
(new StringBuilder())
.append("Could not generate CGLIB subclass of class [")
.append(advised.getTargetClass())
.append("]: ")
.append("Common causes of this problem include using a final class or a non-visible class")
.toString(), ex);
} catch (IllegalArgumentException ex) {
throw new AopConfigException(
(new StringBuilder())
.append("Could not generate CGLIB subclass of class [")
.append(advised.getTargetClass())
.append("]: ")
.append("Common causes of this problem include using a final class or a non-visible class")
.toString(), ex);
} catch (Exception ex) {
throw new AopConfigException("Unexpected AOP exception", ex);
}
}
}
如上结果 通过 Enhancer.create生成代理实例,其通过Enhancer 字节码类构建类的接口、类型、类回调等参数
最终会的代理实例对象
总结:
本篇文章主要阐述 AOP拦截触发器执行过程、AOP代理实现的两种方式
作者简介:张程 技术研究
更多文章请关注微信公众号:zachary分解狮 (frankly0423)