mirror of
https://github.com/spring-projects/spring-framework
synced 2026-06-08 17:33:33 +00:00
Introduce default ProxyConfig bean and exposed interfaces attribute
Taken into account by all proxy processors, this enables consistent proxy type defaulting in Spring Boot as well as consistent opting out for specific bean definitions. Closes gh-35286 Closes gh-35293
This commit is contained in:
+95
@@ -26,7 +26,10 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.aop.framework.AopProxyUtils;
|
||||
import org.springframework.aop.framework.ProxyConfig;
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.aop.framework.autoproxy.AutoProxyUtils;
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
@@ -76,6 +79,78 @@ class RetryInterceptorTests {
|
||||
assertThat(target.counter).isEqualTo(6);
|
||||
}
|
||||
|
||||
@Test
|
||||
void withPostProcessorForMethodWithInterface() {
|
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||
bf.registerBeanDefinition("bean", new RootBeanDefinition(AnnotatedMethodBeanWithInterface.class));
|
||||
RetryAnnotationBeanPostProcessor bpp = new RetryAnnotationBeanPostProcessor();
|
||||
bpp.setBeanFactory(bf);
|
||||
bf.addBeanPostProcessor(bpp);
|
||||
AnnotatedInterface proxy = bf.getBean(AnnotatedInterface.class);
|
||||
AnnotatedMethodBeanWithInterface target = (AnnotatedMethodBeanWithInterface) AopProxyUtils.getSingletonTarget(proxy);
|
||||
|
||||
assertThat(AopUtils.isJdkDynamicProxy(proxy)).isTrue();
|
||||
assertThatIOException().isThrownBy(proxy::retryOperation).withMessage("6");
|
||||
assertThat(target.counter).isEqualTo(6);
|
||||
}
|
||||
|
||||
@Test
|
||||
void withPostProcessorForMethodWithInterfaceAndDefaultTargetClass() {
|
||||
ProxyConfig defaultProxyConfig = new ProxyConfig();
|
||||
defaultProxyConfig.setProxyTargetClass(true);
|
||||
|
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||
bf.registerSingleton(AutoProxyUtils.DEFAULT_PROXY_CONFIG_BEAN_NAME, defaultProxyConfig);
|
||||
bf.registerBeanDefinition("bean", new RootBeanDefinition(AnnotatedMethodBeanWithInterface.class));
|
||||
RetryAnnotationBeanPostProcessor bpp = new RetryAnnotationBeanPostProcessor();
|
||||
bpp.setBeanFactory(bf);
|
||||
bf.addBeanPostProcessor(bpp);
|
||||
AnnotatedInterface proxy = bf.getBean(AnnotatedInterface.class);
|
||||
AnnotatedMethodBeanWithInterface target = (AnnotatedMethodBeanWithInterface) AopProxyUtils.getSingletonTarget(proxy);
|
||||
|
||||
assertThat(AopUtils.isCglibProxy(proxy)).isTrue();
|
||||
assertThatIOException().isThrownBy(proxy::retryOperation).withMessage("6");
|
||||
assertThat(target.counter).isEqualTo(6);
|
||||
}
|
||||
|
||||
@Test
|
||||
void withPostProcessorForMethodWithInterfaceAndPreserveTargetClass() {
|
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||
RootBeanDefinition bd = new RootBeanDefinition(AnnotatedMethodBeanWithInterface.class);
|
||||
bd.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
|
||||
bf.registerBeanDefinition("bean", bd);
|
||||
RetryAnnotationBeanPostProcessor bpp = new RetryAnnotationBeanPostProcessor();
|
||||
bpp.setBeanFactory(bf);
|
||||
bf.addBeanPostProcessor(bpp);
|
||||
AnnotatedInterface proxy = bf.getBean(AnnotatedInterface.class);
|
||||
AnnotatedMethodBeanWithInterface target = (AnnotatedMethodBeanWithInterface) AopProxyUtils.getSingletonTarget(proxy);
|
||||
|
||||
assertThat(AopUtils.isCglibProxy(proxy)).isTrue();
|
||||
assertThatIOException().isThrownBy(proxy::retryOperation).withMessage("6");
|
||||
assertThat(target.counter).isEqualTo(6);
|
||||
}
|
||||
|
||||
@Test
|
||||
void withPostProcessorForMethodWithInterfaceAndExposeInterfaces() {
|
||||
ProxyConfig defaultProxyConfig = new ProxyConfig();
|
||||
defaultProxyConfig.setProxyTargetClass(true);
|
||||
|
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||
bf.registerSingleton(AutoProxyUtils.DEFAULT_PROXY_CONFIG_BEAN_NAME, defaultProxyConfig);
|
||||
RootBeanDefinition bd = new RootBeanDefinition(AnnotatedMethodBeanWithInterface.class);
|
||||
bd.setAttribute(AutoProxyUtils.EXPOSED_INTERFACES_ATTRIBUTE, AutoProxyUtils.ALL_INTERFACES_ATTRIBUTE_VALUE);
|
||||
bf.registerBeanDefinition("bean", bd);
|
||||
RetryAnnotationBeanPostProcessor bpp = new RetryAnnotationBeanPostProcessor();
|
||||
bpp.setBeanFactory(bf);
|
||||
bf.addBeanPostProcessor(bpp);
|
||||
AnnotatedInterface proxy = bf.getBean(AnnotatedInterface.class);
|
||||
AnnotatedMethodBeanWithInterface target = (AnnotatedMethodBeanWithInterface) AopProxyUtils.getSingletonTarget(proxy);
|
||||
|
||||
assertThat(AopUtils.isJdkDynamicProxy(proxy)).isTrue();
|
||||
assertThatIOException().isThrownBy(proxy::retryOperation).withMessage("6");
|
||||
assertThat(target.counter).isEqualTo(6);
|
||||
}
|
||||
|
||||
@Test
|
||||
void withPostProcessorForClass() {
|
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||
@@ -160,6 +235,26 @@ class RetryInterceptorTests {
|
||||
}
|
||||
|
||||
|
||||
static class AnnotatedMethodBeanWithInterface implements AnnotatedInterface {
|
||||
|
||||
int counter = 0;
|
||||
|
||||
@Retryable(maxAttempts = 5, delay = 10)
|
||||
@Override
|
||||
public void retryOperation() throws IOException {
|
||||
counter++;
|
||||
throw new IOException(Integer.toString(counter));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
interface AnnotatedInterface {
|
||||
|
||||
@Retryable(maxAttempts = 5, delay = 10)
|
||||
void retryOperation() throws IOException;
|
||||
}
|
||||
|
||||
|
||||
@Retryable(delay = 10, jitter = 5, multiplier = 2.0, maxDelay = 40,
|
||||
includes = IOException.class, excludes = AccessDeniedException.class,
|
||||
predicate = CustomPredicate.class)
|
||||
|
||||
Reference in New Issue
Block a user