文章预览
在
Spring IOC(9)
里面介绍了三级缓存的时候,提到了AOP创建代理类的内容,有两个地方会去调用AbstractAutoProxyCreator.wrapIfNecessary()去创建代理类。
-
在解析wrapIfNecessary之前先看一下上面的图,分析一些基础的类:
-
Advised
Advised要提供了Advice和Advisor的管理。
-
AdvisedSupport
Advised的实现类,从代码里就能看出Advice会被封装成DefaultIntroductionAdvisor。
public void addAdvice(int pos, Advice advice) throws AopConfigException {
Assert.notNull(advice, "Advice must not be null");
if (advice instanceof IntroductionInfo) {
// We don't need an IntroductionAdvisor for this kind of introduction:
// It's fully self-describing.
addAdvisor(pos, new DefaultIntroductionAdvisor(advice, (IntroductionInfo) advice));
}
else if (advice instanceof DynamicIntroductionAdvice) {
// We need an IntroductionAdvisor for this kind of introduction.
throw new AopConfigException("DynamicIntroductionAdvice may only be added as part of IntroductionAdvisor");
}
else {
addAdvisor(pos, new DefaultPointcutAdvisor(advice));
}
}
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();
}
-
ProxyCreatorSupport
实现了AdvisedSupport,同时定义了AopProxyFactory的成员变量(默认实现
DefaultAopProxyFactory
),所以ProxyCreatorSupport提供了通过AopProxy获得proxy的能力。
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.");
}
//如果目标类是有实现接口的,或者targetClass是由Proxy创建的(JDK代理)
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
//否则通过Cglib方式创建动态代理
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
-
ProxyFactory
在ProxyCreatorSupport提供了获取AopProxy能力之后,ProxyFactory就提供通过AopProxy获取Proxy实例的能力createAopProxy().getProxy()。
-
ProxyFactoryBean
ProxyFactoryBean不仅仅继承了ProxyCreatorSupport也有获得Proxy的能力,另外ProxyFactoryBean还实现了FactoryBean(FactoryBean的注意事项,FactoryBean在通过getBean()生成实例的时候,是默认调用getObject()创建需要的bean,如果想要FactoryBean本身的实例,需要加上&符号),所以这里默认调用getObject()方法来创建proxy对象。
-
正确的使用ProxyFactoryBean:
<bean id="subject" class="com.gary.spring.proxy.RealSubject" />
<bean id="testAdvice" class="com.gary.spring.proxy.TestAdvice" />
<bean id="subjectProxy" class="org.springframework.aop.framework.ProxyFactoryBean" >
<property name="proxyInterfaces">
<value>com.gary.spring.proxy.Subject</value>
</property>
<property name="interceptorNames">
<list>
<value>testAdvice</value>
</list>
</property>
<property name="target">
<ref bean="subject"/>
</property>
</bean>
//这里直接通过getBean获取ProxyFactoryBean的实例,会默认调用getObject()方法生成代理对象
Subject subject = (Subject) beanFactory.getBean("subjectProxy");
subject.sayName();
这里面声明了三个bean,一个真实对象RealSubject,一个Advice,还有一个ProxyFactoryBean。
三个bean创建的时机是不一样的,测试main通过getBean()创建subjectProxy,在populateBean的时候,会去创建subject对应的bean,而testAdvice是在initializeAdvisorChain的过程中通过getBean()进行实例化。
-
ProxyFactoryBean生成Proxy代码解析
-
FactoryBean.getObject()代码
public Object getObject() throws BeansException {
//调用initializeAdvisorChain来初始化Advisor
initializeAdvisorChain();
if (isSingleton()) {
return getSingletonInstance();
}
else {
if (this.targetName == null) {
logger.info("Using non-singleton proxies with singleton targets is often undesirable. " +
"Enable prototype proxies by setting the 'targetName' property.");
}
return newPrototypeInstance();
}
}
-
initializeAdvisorChain解析:
这里主要涉及Advice实例的创建,如果是单例的,就通过this.beanFactory.getBean(name)创建Advice实例。
private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException {
//在xml里面设置了interceptorNames
if (!ObjectUtils.isEmpty(this.interceptorNames)) {
//所以这里会遍历interceptorNames,创建所需要的Advisor
// Materialize interceptor chain from bean names.
for (String name : this.interceptorNames) {
//处理全局的Advisor
if (name.endsWith(GLOBAL_SUFFIX)) {
if (!(this.beanFactory instanceof ListableBeanFactory)) {
throw new AopConfigException(
"Can only use global advisors or interceptors with a ListableBeanFactory");
}
addGlobalAdvisor((ListableBeanFactory) this.beanFactory,
name.substring(0, name.length() - GLOBAL_SUFFIX.length()));
}
//处理对应的Advisor
else {
// If we get here, we need to add a named interceptor.
// We must check if it's a singleton or prototype.
Object advice;
if (this.singleton || this.beanFactory.isSingleton(name)) {
// Add the real Advisor/Advice to the chain.
//如果是单例的,就通过getBane(beanName)获得Advice
advice = this.beanFactory.getBean(name);
}
else {
// It's a prototype Advice or Advisor: replace with a prototype.
// Avoid unnecessary creation of prototype bean just for advisor chain initialization.
//否则就通过property方式创建Advisor
advice = new PrototypePlaceholderAdvisor(name);
}
//将Advice,Advisor或者object添加到interceptor 列表
addAdvisorOnChainCreation(advice, name);
}
}
}
this.advisorChainInitialized = true;
}
-
创建完Advice实例之后,调用addAdvisorOnChainCreation将Advice转换成Advisor。
advisorAdapterRegistry默认是DefaultAdvisorAdapterRegistry。
//将Advice,Advisor或者object添加到interceptor 列表
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);
}
//通过advisorAdapterRegistry将Advice转换或者wrapper成Advisor
private Advisor namedBeanToAdvisor(Object next) {
try {
return this.advisorAdapterRegistry.wrap(next);
}
catch (UnknownAdviceTypeException ex) {
// We expected this to be an Advisor or Advice,
// but it wasn't. This is a configuration error.
throw new AopConfigException("Unknown advisor type " + next.getClass() +
"; Can only include Advisor or Advice type beans in interceptorNames chain except for last entry," +
"which may also be target or TargetSource", ex);
}
}
//将Advice包装wrapper成Advisor
public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
//如果adviceObject就是Advisor,就直接返回,不需要包装
if (adviceObject instanceof Advisor) {
return (Advisor) adviceObject;
}
//如果adviceObject不是Advice类型,就报错,因为MethodInteceptor也是Advice的子类
if (!(adviceObject instanceof Advice)) {
throw new UnknownAdviceTypeException(adviceObject);
}
Advice advice = (Advice) adviceObject;
//如果是MethodInteceptor,就直接包装成DefaultPointcutAdvisor
if (advice instanceof MethodInterceptor) {
// So well-known it doesn't even need an adapter.
return new DefaultPointcutAdvisor(advice);
}
//如果是正常的Advice实现,就需要通过adapters来验证是不是支持该Advice
for (AdvisorAdapter adapter : this.adapters) {
// Check that it is supported.
if (adapter.supportsAdvice(advice)) {
return new DefaultPointcutAdvisor(advice);
}
}
throw new UnknownAdviceTypeException(advice);
}
-
Advisor都加载好之后,调用getSingletonInstance来创建代理类。
需要注意的是JdkDynamicAopProxy内部有AdvisedSupport advised成员变量,所以在通过ProxyCreatorSupport构建JdkDynamicAopProxy的时候需要传入this,因为ProxyCreatorSupport继承自AdvisedSupport。
AdvisedSupport内部有List<Advisor> advisors,所以Advice以及Advisor都会被转化成Advisor保存在该list内部。
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);
//调用ProxyCreatorSupport.createAopProxy()来获取AopProxy,再通过AopProxy获取Proxy实例
this.singletonInstance = getProxy(createAopProxy());
}
return this.singletonInstance;
}
//父类ProxyCreatorSupport.createAopProxy()创建AopProxy
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
//注意这里是将this传入,即AdvisedSupport实例
return getAopProxyFactory().createAopProxy(this);
}
protected Object getProxy(AopProxy aopProxy) {
return aopProxy.getProxy(this.proxyClassLoader);
}
再回顾一下FactoryBean的getObject流程:
正常beanFactory.getBean("subjectProxy")创建的是ProxyFactoryBean,在populateBean的过程中,创建subject的实例,在这之后会调用getObjectForBeanInstance()方法,这里面就是Bean和FactoryBean的区别之处:
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// Don't let calling code try to dereference the factory if the bean isn't a factory.
//isFactoryDereference会检查beanName是不是&打头的,如果是,就直接返回FactoryBean实例,而不是getObject()生成的实例
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}
}
// Now we have the bean instance, which may be a normal bean or a FactoryBean.
// If it's a FactoryBean, we use it to create a bean instance, unless the
// caller actually wants a reference to the factory.
// 如果不是FactoryBean,就直接返回
// 或者isFactoryDereference,即beanName是&打头的,也就直接返回bean
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
//如果是FactoryBean,就通过getObject()方法,返回真正需要的实例对象
Object object = null;
if (mbd == null) {
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
上述流程简述了利用ProxyFactoryBean来创建代理对象的过程,通过XML来演示会比较直白,下面就通过spring aop配置看看是如何创建代理对象。
………………………………