创建代理的步骤分析:
1、首先对拦截器处理,interceptorNames还指定了一些拦截器进行合并,并将不同格式的拦截器处理成对应的增强器Advisor。
2、声明一个代理的工厂类ProxyFactory,并设置对应的增强器,设置TargeSource等信息。
3、根据设置堆ProxyFactory生成对应的AOP Proxy,并获取对应的代理类
咱们接着下面段代码分析:
Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
下面开始分析如何生成代理类的
// 创建代理对象 specificInterceptors:作用在这个Bean上的增强器们
// 这里需要注意的地方:入参是targetSource 而不是target
// 所以最终代理的是 ``每次AOP代理处理方法调用时,目标实例都会用到TargetSource实现
protected Object createProxy(Class> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
//增加属性值originalTargetClass ,值为beanClass 。在afterSingletonsInstantiated()方法中有应用,可以用作Bean创建完成之后的后置处理。
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
// 创建代理对象的三大方式之一. 后边会分析Spring创建代理的三种方式
ProxyFactory proxyFactory = new ProxyFactory();
//对ProxyConfig中属性值的拷贝
proxyFactory.copyFrom(this);
// 看看是否是基于类的代理(CGLIB),若表面上是基于接口的代理 我们还需要进一步去检测
if (!proxyFactory.isProxyTargetClass()) {
// 默认实现为和该bean定义是否属性值preserveTargetClass为true有关。默认情况下都不会有此属性值的
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}else {
//通过beanClass是否存在符合要求的接口,如果存在则把所有接口都放入ProxyFactory中
//判断接口的规则:
1、(InitializingBean.class == ifc || DisposableBean.class == ifc || Closeable.class == ifc ||
AutoCloseable.class == ifc || ObjectUtils.containsElement(ifc.getInterfaces(), Aware.class)这些条件都不能满足
2、(ifc.getName().equals("groovy.lang.GroovyObject") ||
ifc.getName().endsWith(".cglib.proxy.Factory") ||
ifc.getName().endsWith(".bytebuddy.MockAccess"))名字不能相同。
3、public 的方法数量最少一个。
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// buildAdvisors:整理合并得到最终的advisors (毕竟interceptorNames还指定了一些拦截器的)并构造成Advisor
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);//详见下面
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
//这个方法是交给子类的,子类可以继续去定制此proxyFactory(Spring内部并没有搭理它)
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
//设置preFiltered的属性值,默认是false。子类:AbstractAdvisorAutoProxyCreator修改为true
// preFiltered:字段意思为:是否已为特定目标类筛选Advisor
// 这个字段和DefaultAdvisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice获取所有的Advisor有关
//CglibAopProxy和JdkDynamicAopProxy都会调用此方法,然后递归执行所有的Advisor的
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
//判断采用哪一种动态代理的方式,并创建相对应的代理bean。
// getProxyClassLoader():调用者可议指定 否则为:ClassUtils.getDefaultClassLoader()
return proxyFactory.getProxy(getProxyClassLoader()); //详见下面
}
构建Bean相关的增强器
protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {
// Handle prototypes correctly...
Advisor[] commonInterceptors = resolveInterceptorNames();
List
proxyFactory.getProxy(getProxyClassLoader());
public Object getProxy(@Nullable ClassLoader classLoader) {
//下面分析分为两步:
首先分析如何创建AOP Proxy(CglibAopProxy 和 JdkDynamicAopProxy)
第二步:分析如何创建对应Bean的代理。
return createAopProxy().getProxy(classLoader);
}
第一步:
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
//首选获取AOP proxy工厂 再创建对应的AOP Proxy。
return getAopProxyFactory().createAopProxy(this);
}
public AopProxyFactory getAopProxyFactory() {
return this.aopProxyFactory; //默认采用的是:DefaultAopProxyFactory.class
}
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
//支持优化代理对象采取性能优化措施 或者 指定了采用CGLib的代理方式 或者 没有符合要求的接口
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
//获取要被代理的实例的Class对象
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.");
}
//如果被代理对象是一个接口或者,是JDK中Proxy类的子类的话,会采用JDK的方式进行代理,否则会采用CGLib的方式进行代理
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}else {
return new JdkDynamicAopProxy(config);
}
}
第二步:
首先分析CGLib代理方式的应用:
public Object getProxy(@Nullable ClassLoader classLoader) {
try {
Class> rootClass = this.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();
for (Class> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
// Validate the class, writing log messages as necessary.
validateClassIfNecessary(proxySuperClass, classLoader);
// Configure CGLIB Enhancer...
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
enhancer.setSuperclass(proxySuperClass);
//对SpringProxy和Advised接口的处理,让生成的类上实现这两个接口
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
//类名字的生产策略也就是在类的名字上加上"BySpringCGLIB" 例:MathCalculator$$EnhancerBySpringCGLIB$$7e1949802152
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
//设置用于从该生成器创建字节码的策略。默认情况下使用{@see DefaultGeneratorStrategy}的实例。
enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));
Callback[] callbacks = getCallbacks(rootClass);
Class>[] types = new Class>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
// fixedInterceptorMap only populated at this point, after getCallbacks call above
//对于ClallBack和CallbackFilter有疑问的可以参考下面链接中的其他文章
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
// Generate the proxy class and create a proxy instance.
return createProxyClassAndInstance(enhancer, callbacks);
}
catch (CodeGenerationException | IllegalArgumentException ex) {
}
}
//创建指定的代理对象、关于CGLib中如何创建代理的源码,等后续有时间会专门研究。
protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
enhancer.setInterceptDuringConstruction(false);
enhancer.setCallbacks(callbacks);
return (this.constructorArgs != null && this.constructorArgTypes != null ?
enhancer.create(this.constructorArgTypes, this.constructorArgs) :
enhancer.create());
}
对于CallbackFilter和CallBack的讲解详见:CGLib中CallbackFilter介绍 和 CGLib中Callback介绍 两篇文章