Skip to content

Commit 3af0c23

Browse files
committed
ProxyFactoryBean determines actual proxy class in getObjectType()
AopProxy implementations accept empty Advisor chains for early proxy class creation. Closes gh-29097
1 parent efaee61 commit 3af0c23

File tree

5 files changed

+9
-47
lines changed

5 files changed

+9
-47
lines changed

spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,6 @@ class CglibAopProxy implements AopProxy, Serializable {
126126
*/
127127
public CglibAopProxy(AdvisedSupport config) throws AopConfigException {
128128
Assert.notNull(config, "AdvisedSupport must not be null");
129-
if (config.getAdvisorCount() == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
130-
throw new AopConfigException("No advisors and no TargetSource specified");
131-
}
132129
this.advised = config;
133130
this.advisedDispatcher = new AdvisedDispatcher(this.advised);
134131
}

spring-aop/src/main/java/org/springframework/aop/framework/JdkDynamicAopProxy.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,6 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
104104
*/
105105
public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
106106
Assert.notNull(config, "AdvisedSupport must not be null");
107-
if (config.getAdvisorCount() == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
108-
throw new AopConfigException("No advisors and no TargetSource specified");
109-
}
110107
this.advised = config;
111108
this.proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
112109
findDefinedEqualsAndHashCodeMethods(this.proxiedInterfaces);

spring-aop/src/main/java/org/springframework/aop/framework/ProxyFactoryBean.java

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -274,19 +274,9 @@ public Class<?> getObjectType() {
274274
return this.singletonInstance.getClass();
275275
}
276276
}
277-
Class<?>[] ifcs = getProxiedInterfaces();
278-
if (ifcs.length == 1) {
279-
return ifcs[0];
280-
}
281-
else if (ifcs.length > 1) {
282-
return createCompositeInterface(ifcs);
283-
}
284-
else if (this.targetName != null && this.beanFactory != null) {
285-
return this.beanFactory.getType(this.targetName);
286-
}
287-
else {
288-
return getTargetClass();
289-
}
277+
// This might be incomplete since it potentially misses introduced interfaces
278+
// from Advisors that will be lazily retrieved via setInterceptorNames.
279+
return createAopProxy().getProxyClass(this.proxyClassLoader);
290280
}
291281

292282
@Override
@@ -295,19 +285,6 @@ public boolean isSingleton() {
295285
}
296286

297287

298-
/**
299-
* Create a composite interface Class for the given interfaces,
300-
* implementing the given interfaces in one single Class.
301-
* <p>The default implementation builds a JDK proxy class for the
302-
* given interfaces.
303-
* @param interfaces the interfaces to merge
304-
* @return the merged interface as Class
305-
* @see java.lang.reflect.Proxy#getProxyClass
306-
*/
307-
protected Class<?> createCompositeInterface(Class<?>[] interfaces) {
308-
return ClassUtils.createCompositeInterface(interfaces, this.proxyClassLoader);
309-
}
310-
311288
/**
312289
* Return the singleton instance of this class's proxy object,
313290
* lazily creating it if it hasn't been created already.

spring-context/src/test/java/org/springframework/aop/framework/AbstractAopProxyTests.java

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,12 @@ public abstract class AbstractAopProxyTests {
9797
* to ensure that it was used appropriately by code.
9898
*/
9999
@BeforeEach
100-
public void setUp() {
100+
public void reset() {
101101
mockTargetSource.reset();
102102
}
103103

104104
@AfterEach
105-
public void tearDown() {
105+
public void verify() {
106106
mockTargetSource.verify();
107107
}
108108

@@ -122,16 +122,6 @@ protected boolean requiresTarget() {
122122
}
123123

124124

125-
@Test
126-
public void testNoInterceptorsAndNoTarget() {
127-
assertThatExceptionOfType(AopConfigException.class).isThrownBy(() -> {
128-
AdvisedSupport pc = new AdvisedSupport(ITestBean.class);
129-
//Add no interceptors
130-
AopProxy aop = createAopProxy(pc);
131-
aop.getProxy();
132-
});
133-
}
134-
135125
/**
136126
* Simple test that if we set values we can get them out again.
137127
*/

spring-context/src/test/java/org/springframework/aop/framework/ProxyFactoryBeanTests.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ public class ProxyFactoryBeanTests {
9292

9393

9494
@BeforeEach
95-
public void setUp() throws Exception {
95+
public void setup() throws Exception {
9696
DefaultListableBeanFactory parent = new DefaultListableBeanFactory();
9797
parent.registerBeanDefinition("target2", new RootBeanDefinition(TestApplicationListener.class));
9898
this.factory = new DefaultListableBeanFactory(parent);
@@ -473,8 +473,8 @@ public void testNoInterceptorNamesWithTarget() {
473473
public void testEmptyInterceptorNames() {
474474
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
475475
new XmlBeanDefinitionReader(bf).loadBeanDefinitions(new ClassPathResource(INVALID_CONTEXT, CLASS));
476-
assertThatExceptionOfType(BeanCreationException.class).as("Interceptor names cannot be empty").isThrownBy(() ->
477-
bf.getBean("emptyInterceptorNames"));
476+
assertThat(bf.getBean("emptyInterceptorNames")).isInstanceOf(ITestBean.class);
477+
assertThat(Proxy.isProxyClass(bf.getBean("emptyInterceptorNames").getClass())).isTrue();
478478
}
479479

480480
/**
@@ -709,6 +709,7 @@ public DependsOnITestBean(ITestBean tb) {
709709
}
710710
}
711711

712+
712713
/**
713714
* Aspect interface
714715
*/

0 commit comments

Comments
 (0)