advisor:顾问,提供意见者。
broker:经纪人。
一,初始化Advisor链
1,ProxyFactoryBean
初始化Advisor链的源码就在ProxyFactoryBean.initializeAdvisorChain()这个方法中。我们来具体分析。
第一步,判断拦截器链是否被初始化过。如果没有初始化,则继续。
this.advisorChainInitialized()
第二步,判断当前获取到的拦截器数组是否为空。如果不为空,则继续。
ObjectUtils.isEmpty(this.interceptorNames())
this.interceptorNames()是一个字符串数组,这个数组对外提供了setter()方法,外部类通过调用setter()方法来给这个数组赋值。
第三步:循环处理this.interceptorNames()
打印trace日志:
Configuring advisor or advice “name”
第四步:进入循环以后,分两种情况来处理。
if (name.endWith("*")){
// 添加通配符形式的advice到通知链
this.addGlobalAdsivor();
} else {
// 通知
Object advice;
// 获取需要通知的bean
if (!this.singleton && !this.beanFactory.isSingleton(name)){
advice = new PProxyFactoryBean.PrototypePlaceholderAdvisor(name);
} else {
advice = this.beanFactory.getBean(name);
}
// 添加Advisor,最终会放到一个list中。
// List<Advisor> advisors
this.addAdvisorOnChainCreation();
}
通配符形式的配置,是从ListableBeanFactory中取bean,然后转化为Advisor,最后注册到advisor链。
单个的Advisor配置,是从当前的beanFactory中直接取bean,然后转化为Advisor,最后注册到advisor链。
不管是通配符advice还是单个advice,最终都是注册到List<Advisor> advisors,这个集合是定义在AdvisedSupport.class中的。
这个List<Advisor> advisors就是传说中的advisor链,也就是通知链。
二,反射生成代理类
ProxyFactoryBean.getObject()方法源码如下:
// 初始化advisor链,上面已经讲过了
this.initializeAdvisorChain()
// 判断bean的作用域
if (this.isSingleton()){
// 单例bean生成代理
return this.getSingletonInstance();
} else {
// prototype bean生成代理
this.newPrototypeInstance();
}
我们这里以单例bean为例来进行说明。
// 反射生成代理类
this.singletonInstance = this.getProxy(this.createAopProxy());
反射生成代理类主要分成2步:
第一步:初始化动态代理框架。
this.createAopProxy()
创建AopProxy实例是借助ProxyCreatorSupport来实现的。ProxyCreatorSupport.createAopProxy()
这个方法最终调用了AopProxyFactory.createAopProxy()。AopProxyFactory是一个工厂类接口,默认实现是DefaultAopProxyFactory。
DefaultAopProxyFactory就是大名鼎鼎的生成AopProxy的工厂类,注意,这里的AOP框架有2种:
JDK动态代理:JdkDynanicAopProxy.class
Cglib动态代理:ObjenesisCglibAopProxy
OK,到这里完成了动态代理框架的初始化。
第二步:生成代理类
this.getProxy(this.createAopProxy());
这一步的主要功能就是:使用动态代理框架生成代理类。
首先看使用JDK生成代理的具体实现。
// 获取代理类的所有接口,是一个class数组。这个class数组是所有需要生成代理类的接口。
Class<?>[] proxiedInterfaces = AopProxyUntils.comlpeteProxiedInterfaces(this.advised, true);
// 从需要生成代理类的接口中,打标equals方法和hashcode方法,如果代理类中包含equals方法或者hashcode方法,则置为true
this.findDefinedEqualsAndHashcodeMethids(proxiedInterfaces);
进入方法,有这样的判断:
if (AopUtils.isEqualsMethod(method)){
this.equalsDefined = true;
}
if (AopUtils.isHashcodeMethod(method)){
this.hashcodeDefined = true;
}
打标这两个方法,就是标记一下target是否重写了equals方法和hashcode方法。这样在回调代理类的equals方法和hashcode方法时,就知道到底要调用target的方法,还是要调用Object的方法了。
// 生成代理类并返回
return Proxy.newProxyInstance(classloader, proxiedInterfaces, this);
接着我们来看Cglib生成代理的具体实现。
// 从adsivors通知链中拿到目标类
Class<?> rootClass = this.advised.getTargetClass();
Class<?> proxySuperClass = rootClass;
// 验证当前代理类是否可以被代理。代理类不能是final修饰的,并且代理类的类加载器和当前的类加载器是同一个类加载器。
this.validateClassIfNecessary(proxySuperClass, classloader);
// 创建类增强器Enhancer,大名鼎鼎的一个技术。Cglib就是使用这个类增强器来生成代理的。
Enhancer enhancer = this.createEnhancer();
// 接下来就是设置Enhancer的一系列属性,我们重点关注这个CallBack,回调方法。
Callback[] callbacks = this.getCallbacks(rootClass);
// 调用Enhancer.create(),创建代理类
return this.createProxyClassAndInstance(enhancer, callbacks);
后面的细节我们不再关注,我们这里重点来看一下Cglib的增强器Enhancer。
Enhancer是一个字节码增强器,与反射不同的是,Enhancer是通过分析class的字节码文件来生成代理类的。Enhancer即可以为实现了接口的类生成代理,也可以为没有实现接口的类生成代理。
三,拦截器拦截调用代理方法
如何回调代理类的方法呢?入口就是大名鼎鼎的InvocationHandler接口的invoke()方法。而大名鼎鼎的JdkDynamicAopProxy就实现了大名鼎鼎的InvocationHandler接口。
JdkDynamicAopProxy.invoke()方法,这里不再分析,后面会另起文章专门来讨论。
总之我们知道,JDK动态代理最终回调代理类的方法,入口就在JdkDynamicAopProxy.invoke()方法就行了。