Description
See spring-projects/spring-retry#214 (comment)
Spring retry uses AOP auto proxy to add a proxy for @Retryable
methods; the code unconditionally wraps the target in a new proxy. If proxyTargetClass
is true (default in Spring Boot), the AbstractAutoProxyCreator
does not add interfaces if the target is a JDK proxy.
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
This causes, for example, @Retryable
on a spring data repository to create an invalid bean
@Repository
public interface TestRepository extends CrudRepository<Test, String> {
@Override
@Retryable(maxAttempts = 4)
List<Test> findAll();
}
The inner (spring-data) proxy implements TestRepository
, etc, but the outer proxy only implements the Retryable
interceptor interface.
The bean 'testRepository' could not be injected as a 'com.example.demo.TestRepository' because it is a JDK dynamic proxy that implements:
org.springframework.data.repository.CrudRepository
Although the error message is wrong (spring-projects/spring-boot#26821), it is because the proxy only implements Retryable
.
Perhaps the AbstractAutoProxyCreator
could detect that the target is a JDK proxy and copy the interfaces (even when proxyTargetClass
) is true?