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

Spring AOP 代理对象的生成 part3

2016-07-05 23:39 477 查看
这一节我们探究一下在Spring AOP中目标对象的代理对象的生成过程。

我们会设计到三个主要的类:

ProxyFactoryBean

ProxyCreatorSupport

AdvisedSupport

从上到下时继承的关系。为便于区分我们称之为子类ProxyFactoryBean,父类ProxyCreatorSupport和祖类AdvisedSupport。

生成代理对象过程从子类ProxyFactoryBean开始的。

这个一个FactoryBean,我们会在配置文件中配置这个bean,通过这个bean获取代理对象的。因为的他名字就是代理工厂Bean。

获取代理对象是通过getObject方法,我们把对目标对象的增强都封装在了这个方法中。

@Override
public Object getObject() throws BeansException {
initializeAdvisorChain();
if (isSingleton()) {
return getSingletonInstance();
}
else {
if (this.targetName == null) {
logger.warn("Using non-singleton proxies with singleton targets is often undesirable. " +
"Enable prototype proxies by setting the 'targetName' property.");
}
return newPrototypeInstance();
}
}


在这个方法开始的时候,有一个方法initializeAdvisorChain,这个是用来初始化通知器链的方法。

一、初始化通知器链的过程

在初始化通知器链的过程时,spring会读取配置文件,获得通知器链的名字,然后根据名字,通过getBean方法,获得它的实例。

然后将实例保存起来,具体的保存时通过下面的这个方法:

addAdvisorOnChainCreation(advice, name);
private void addAdvisorOnChainCreation(Object next, String name) {
// We need to convert to an Advisor if necessary so that our source reference
// matches what we find from superclass interceptors.
Advisor advisor = namedBeanToAdvisor(next);
if (logger.isTraceEnabled()) {
logger.trace("Adding advisor with name '" + name + "'");
}
addAdvisor(advisor);
}


主要调用的方法就是addAdvisor(advisor);很简单。

不过这个方法是祖类AdvisedSupport中定义的。

AdvisedSupport中有一个Linkedlist属性,用于存放通知器。它是私有的。

public void addAdvisor(Advisor advisor) {
int pos = this.advisors.size();
addAdvisor(pos, advisor);
}
@Override
public void addAdvisor(int pos, Advisor advisor) throws AopConfigException {
if (advisor instanceof IntroductionAdvisor) {
validateIntroductionAdvisor((IntroductionAdvisor) advisor);
}
addAdvisorInternal(pos, advisor);
}
private void addAdvisorInternal(int pos, Advisor advisor) throws AopConfigException {
Assert.notNull(advisor, "Advisor must not be null");
if (isFrozen()) {
throw new AopConfigException("Cannot add advisor: Configuration is frozen.");
}
if (pos > this.advisors.size()) {
throw new IllegalArgumentException(
"Illegal position " + pos + " in advisor list with size " + this.advisors.size());
}

this.advisors.add(pos, advisor);
updateAdvisorArray();
adviceChanged();
}


此时就将通知器保存进了AdvisedSupport中,后面还会用到,具体是下一篇博客。

通知器链初始完成之后,就开始生成代理对象了。

二、生成代理对象

在getObject 中我们看到,根据目标对象是否是单例提供两种生成代理对象的方式。

我们首先看单例模式的情况:getSingletonInstance();

private synchronized Object getSingletonInstance() {
if (this.singletonInstance == null) {
this.targetSource = freshTargetSource();
if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) {
// Rely on AOP infrastructure to tell us what interfaces to proxy.
Class<?> targetClass = getTargetClass();
if (targetClass == null) {
throw new FactoryBeanNotInitializedException("Cannot determine target class for proxy");
}
setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader));
}
// Initialize the shared singleton instance.
super.setFrozen(this.freezeProxy);
this.singletonInstance = getProxy(createAopProxy());
}
return this.singletonInstance;
}


主要看最后一行this.singletonInstance = getProxy(createAopProxy());代码。

getProxy的实现如下:

protected Object getProxy(AopProxy aopProxy) {
return aopProxy.getProxy(this.proxyClassLoader);
}


此时有一个类AopProxy,这个类就是spring中负责生产代理对象的类。准确的说这是一个接口。具体工作是由他的实现类完成的。

在Spring中还提供了一个生成这个AopProxy实现类的工厂类:AopProxyFactory 。其实这个AopProxyFactory 也是一个接口。

所以,在这个地方spring使用的时抽象工厂模式。在spring中AopProxyFactory 只有一个实现类DefaultAopProxyFactory。

AopProxy由两个直接的实现类JdkDynamicAopProxy和ObjenesisCglibAopProxy。

总结一下就是:由DefaultAopProxyFactory负责生成两个AopProxy。由JdkDynamicAopProxy和ObjenesisCglibAopProxy负责生成代理对象。

逻辑表述完毕。我们看下源码实现。

这行代码有一个参数createAopProxy()

this.singletonInstance = getProxy(createAopProxy());

我们看下这个方法createAopProxy()

这个方法定义在 父类ProxyCreatorSupport中了

protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}


我们解释一下,createAopProxy 这个方法就是创建AopProxy,刚才我们表述过,这个是由AopProxyFactory 工厂创建的。

Ok,我们需要继续看getAopProxyFactory()这个方法,获取AopProxyFactory 工厂的方法。

public AopProxyFactory getAopProxyFactory() {
return this.aopProxyFactory;
}


这个方法很简单,返回本身的aopProxyFactory对象,这个又是什么呢,我们看ProxyCreatorSupport父类的构造函数:

public ProxyCreatorSupport() {
this.aopProxyFactory = new DefaultAopProxyFactory();
}


我们发现就是默认的DefaultAopProxyFactory 工厂类。

那么createAopProxy(this); 这个方法就是DefaultAopProxyFactory 类中的方法了。

我们看下这个方法:

@Override
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);
}
}


在这个方法中我们看到了两个AopProxy实现类的创建过程。

我们还看这个createAopProxy(this);他传递的参数时this

他是自然ProxyCreatorSupport这个类的一个实例。

由于ProxyCreatorSupport是AdvisedSupport 子类,所以这个参数就可以理解了。为什么要传递这个AdvisedSupport 参数我们等下说明。

现在我们假设创建的类是JdkDynamicAopProxy;

这个类是用来创建代理对象的,我们看下这个方法aopProxy.getProxy(this.proxyClassLoader);

那么getProxy 就是JdkDynamicAopProxy中的方法:

@Override
public Object getProxy(ClassLoader classLoader) {
……
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}


这个是上一博客讲的jdk生成代理对象的方法。现在我们来看此处的三个参数:

第一个ClassLoader ,AOP使用了一个默认的ClassLoader 。事实上我们使用任何一个类都可以得到ClassLoader 。这个目标对象无关。

proxiedInterfaces 这个参数就是需要从AdvisedSupport中获取的。在这个getSingletonInstance() 方法最开始时,有一个方法 setInterfaces,这个方法在AdvisedSupport中定义,就是将接口信息保存进了AdvisedSupport中list中。这也是在createAopProxy(this);方法传递this,即传递AdvisedSupport的原因。

第三个this:此处的this 就是JdkDynamicAopProxy,因为这个类实现了InvocationHandler这个接口这就意味着 在JdkDynamicAopProxy 还有一个invoke方法。我们稍后分析这个方法,在下一篇博客中分析。以我们刚才的分析,此时生成了目标对象的代理对象。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息