ProxyFactoryBean determines actual proxy class in getObjectType()

AopProxy implementations accept empty Advisor chains for early proxy class creation.

Closes gh-29097
This commit is contained in:
Juergen Hoeller
2022-10-06 11:54:06 +02:00
parent efaee61f31
commit 3af0c232b7
5 changed files with 9 additions and 47 deletions

View File

@@ -126,9 +126,6 @@ class CglibAopProxy implements AopProxy, Serializable {
*/
public CglibAopProxy(AdvisedSupport config) throws AopConfigException {
Assert.notNull(config, "AdvisedSupport must not be null");
if (config.getAdvisorCount() == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
throw new AopConfigException("No advisors and no TargetSource specified");
}
this.advised = config;
this.advisedDispatcher = new AdvisedDispatcher(this.advised);
}

View File

@@ -104,9 +104,6 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
*/
public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
Assert.notNull(config, "AdvisedSupport must not be null");
if (config.getAdvisorCount() == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
throw new AopConfigException("No advisors and no TargetSource specified");
}
this.advised = config;
this.proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(this.proxiedInterfaces);

View File

@@ -274,19 +274,9 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
return this.singletonInstance.getClass();
}
}
Class<?>[] ifcs = getProxiedInterfaces();
if (ifcs.length == 1) {
return ifcs[0];
}
else if (ifcs.length > 1) {
return createCompositeInterface(ifcs);
}
else if (this.targetName != null && this.beanFactory != null) {
return this.beanFactory.getType(this.targetName);
}
else {
return getTargetClass();
}
// This might be incomplete since it potentially misses introduced interfaces
// from Advisors that will be lazily retrieved via setInterceptorNames.
return createAopProxy().getProxyClass(this.proxyClassLoader);
}
@Override
@@ -295,19 +285,6 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
}
/**
* Create a composite interface Class for the given interfaces,
* implementing the given interfaces in one single Class.
* <p>The default implementation builds a JDK proxy class for the
* given interfaces.
* @param interfaces the interfaces to merge
* @return the merged interface as Class
* @see java.lang.reflect.Proxy#getProxyClass
*/
protected Class<?> createCompositeInterface(Class<?>[] interfaces) {
return ClassUtils.createCompositeInterface(interfaces, this.proxyClassLoader);
}
/**
* Return the singleton instance of this class's proxy object,
* lazily creating it if it hasn't been created already.

View File

@@ -97,12 +97,12 @@ public abstract class AbstractAopProxyTests {
* to ensure that it was used appropriately by code.
*/
@BeforeEach
public void setUp() {
public void reset() {
mockTargetSource.reset();
}
@AfterEach
public void tearDown() {
public void verify() {
mockTargetSource.verify();
}
@@ -122,16 +122,6 @@ public abstract class AbstractAopProxyTests {
}
@Test
public void testNoInterceptorsAndNoTarget() {
assertThatExceptionOfType(AopConfigException.class).isThrownBy(() -> {
AdvisedSupport pc = new AdvisedSupport(ITestBean.class);
//Add no interceptors
AopProxy aop = createAopProxy(pc);
aop.getProxy();
});
}
/**
* Simple test that if we set values we can get them out again.
*/

View File

@@ -92,7 +92,7 @@ public class ProxyFactoryBeanTests {
@BeforeEach
public void setUp() throws Exception {
public void setup() throws Exception {
DefaultListableBeanFactory parent = new DefaultListableBeanFactory();
parent.registerBeanDefinition("target2", new RootBeanDefinition(TestApplicationListener.class));
this.factory = new DefaultListableBeanFactory(parent);
@@ -473,8 +473,8 @@ public class ProxyFactoryBeanTests {
public void testEmptyInterceptorNames() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
new XmlBeanDefinitionReader(bf).loadBeanDefinitions(new ClassPathResource(INVALID_CONTEXT, CLASS));
assertThatExceptionOfType(BeanCreationException.class).as("Interceptor names cannot be empty").isThrownBy(() ->
bf.getBean("emptyInterceptorNames"));
assertThat(bf.getBean("emptyInterceptorNames")).isInstanceOf(ITestBean.class);
assertThat(Proxy.isProxyClass(bf.getBean("emptyInterceptorNames").getClass())).isTrue();
}
/**
@@ -709,6 +709,7 @@ public class ProxyFactoryBeanTests {
}
}
/**
* Aspect interface
*/