added "expose-proxy" attribute to aop namespace (enforcing AopContext proxy exposure with CGLIB; SPR-7261)
git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@3389 50f2f4bb-b051-0410-bef5-90022cba6387
This commit is contained in:
parent
20cb9addbd
commit
9ec3a3798c
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2008 the original author or authors.
|
* Copyright 2002-2010 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -97,6 +97,13 @@ public abstract class AopConfigUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void forceAutoProxyCreatorToExposeProxy(BeanDefinitionRegistry registry) {
|
||||||
|
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
|
||||||
|
BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
|
||||||
|
definition.getPropertyValues().add("exposeProxy", Boolean.TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private static BeanDefinition registerOrEscalateApcAsRequired(Class cls, BeanDefinitionRegistry registry, Object source) {
|
private static BeanDefinition registerOrEscalateApcAsRequired(Class cls, BeanDefinitionRegistry registry, Object source) {
|
||||||
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
|
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2010 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -46,6 +46,11 @@ public abstract class AopNamespaceUtils {
|
||||||
*/
|
*/
|
||||||
public static final String PROXY_TARGET_CLASS_ATTRIBUTE = "proxy-target-class";
|
public static final String PROXY_TARGET_CLASS_ATTRIBUTE = "proxy-target-class";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The <code>expose-proxy</code> attribute as found on AOP-related XML tags.
|
||||||
|
*/
|
||||||
|
private static final String EXPOSE_PROXY_ATTRIBUTE = "expose-proxy";
|
||||||
|
|
||||||
|
|
||||||
public static void registerAutoProxyCreatorIfNecessary(
|
public static void registerAutoProxyCreatorIfNecessary(
|
||||||
ParserContext parserContext, Element sourceElement) {
|
ParserContext parserContext, Element sourceElement) {
|
||||||
|
|
@ -102,6 +107,10 @@ public abstract class AopNamespaceUtils {
|
||||||
if (proxyTargetClass) {
|
if (proxyTargetClass) {
|
||||||
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
|
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
|
||||||
}
|
}
|
||||||
|
boolean exposeProxy = Boolean.valueOf(sourceElement.getAttribute(EXPOSE_PROXY_ATTRIBUTE));
|
||||||
|
if (exposeProxy) {
|
||||||
|
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2008 the original author or authors.
|
* Copyright 2002-2010 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -268,7 +268,7 @@ final class Cglib2AopProxy implements AopProxy, Serializable {
|
||||||
|
|
||||||
// Choose a "straight to target" interceptor. (used for calls that are
|
// Choose a "straight to target" interceptor. (used for calls that are
|
||||||
// unadvised but can return this). May be required to expose the proxy.
|
// unadvised but can return this). May be required to expose the proxy.
|
||||||
Callback targetInterceptor = null;
|
Callback targetInterceptor;
|
||||||
if (exposeProxy) {
|
if (exposeProxy) {
|
||||||
targetInterceptor = isStatic ?
|
targetInterceptor = isStatic ?
|
||||||
new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
|
new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
|
||||||
|
|
@ -316,12 +316,8 @@ final class Cglib2AopProxy implements AopProxy, Serializable {
|
||||||
// Now copy both the callbacks from mainCallbacks
|
// Now copy both the callbacks from mainCallbacks
|
||||||
// and fixedCallbacks into the callbacks array.
|
// and fixedCallbacks into the callbacks array.
|
||||||
callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
|
callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
|
||||||
for (int x = 0; x < mainCallbacks.length; x++) {
|
System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
|
||||||
callbacks[x] = mainCallbacks[x];
|
System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
|
||||||
}
|
|
||||||
for (int x = 0; x < fixedCallbacks.length; x++) {
|
|
||||||
callbacks[x + mainCallbacks.length] = fixedCallbacks[x];
|
|
||||||
}
|
|
||||||
this.fixedInterceptorOffset = mainCallbacks.length;
|
this.fixedInterceptorOffset = mainCallbacks.length;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
@ -610,7 +606,7 @@ final class Cglib2AopProxy implements AopProxy, Serializable {
|
||||||
targetClass = target.getClass();
|
targetClass = target.getClass();
|
||||||
}
|
}
|
||||||
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
|
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
|
||||||
Object retVal = null;
|
Object retVal;
|
||||||
// Check whether we only have one InvokerInterceptor: that is,
|
// Check whether we only have one InvokerInterceptor: that is,
|
||||||
// no real advice, but just reflective invocation of the target.
|
// no real advice, but just reflective invocation of the target.
|
||||||
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
|
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2007 the original author or authors.
|
* Copyright 2002-2010 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -113,7 +113,9 @@ public class ProxyConfig implements Serializable {
|
||||||
* ThreadLocal for retrieval via the AopContext class. This is useful
|
* ThreadLocal for retrieval via the AopContext class. This is useful
|
||||||
* if an advised object needs to call another advised method on itself.
|
* if an advised object needs to call another advised method on itself.
|
||||||
* (If it uses <code>this</code>, the invocation will not be advised).
|
* (If it uses <code>this</code>, the invocation will not be advised).
|
||||||
* <p>Default is "false", for optimal performance.
|
* <p>Default is "false", in order to avoid unnecessary extra interception.
|
||||||
|
* This means that no guarantees are provided that AopContext access will
|
||||||
|
* work consistently within any method of the advised object.
|
||||||
*/
|
*/
|
||||||
public void setExposeProxy(boolean exposeProxy) {
|
public void setExposeProxy(boolean exposeProxy) {
|
||||||
this.exposeProxy = exposeProxy;
|
this.exposeProxy = exposeProxy;
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,15 @@
|
||||||
]]></xsd:documentation>
|
]]></xsd:documentation>
|
||||||
</xsd:annotation>
|
</xsd:annotation>
|
||||||
</xsd:attribute>
|
</xsd:attribute>
|
||||||
|
<xsd:attribute name="expose-proxy" type="xsd:boolean" default="false">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation><![CDATA[
|
||||||
|
Indicate that the proxy should be exposed by the AOP framework as a
|
||||||
|
ThreadLocal for retrieval via the AopContext class. Off by default,
|
||||||
|
i.e. no guarantees that AopContext access will work.
|
||||||
|
]]></xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:attribute>
|
||||||
</xsd:complexType>
|
</xsd:complexType>
|
||||||
</xsd:element>
|
</xsd:element>
|
||||||
|
|
||||||
|
|
@ -84,6 +93,15 @@
|
||||||
]]></xsd:documentation>
|
]]></xsd:documentation>
|
||||||
</xsd:annotation>
|
</xsd:annotation>
|
||||||
</xsd:attribute>
|
</xsd:attribute>
|
||||||
|
<xsd:attribute name="expose-proxy" type="xsd:boolean" default="false">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation><![CDATA[
|
||||||
|
Indicate that the proxy should be exposed by the AOP framework as a
|
||||||
|
ThreadLocal for retrieval via the AopContext class. Off by default,
|
||||||
|
i.e. no guarantees that AopContext access will work.
|
||||||
|
]]></xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:attribute>
|
||||||
</xsd:complexType>
|
</xsd:complexType>
|
||||||
</xsd:element>
|
</xsd:element>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue