Home > Mobile >  Spring Boot default proxying mechanism
Spring Boot default proxying mechanism

Time:08-04

Recently i found spring documentation page that says:

Spring AOP uses either JDK dynamic proxies or CGLIB to create the proxy for a given target object. (JDK dynamic proxies are preferred whenever you have a choice).

If the target object to be proxied implements at least one interface then a JDK dynamic proxy will be used.

But it doesn't seem to be the case in my application. I wanted to write a small benchmark to compare the performance of both types of proxying.

There are two similar classes. Both have one method annotated with the @Transactional annotation. One class implements the interface and the other does not:

@Service
public class Cglib {
    @Transactional
    public void method() {}
}
public interface Dynamic {
    void method();
}
@Service
public class DynamicImpl implements Dynamic {
    @Override
    @Transactional
    public void method() {}
}

And based on the documentation for the first class, a CGLIB proxy should be created, and for the second, a JDK dynamic proxy.

But in my case CGLIB was used for both classes:

@Component
@RequiredArgsConstructor
public class Runner implements ApplicationRunner {
    private final Cglib cglib;
    private final Dynamic dynamic;

    @Override
    public void run(ApplicationArguments args) {
        System.out.println(cglib.getClass());
        System.out.println(dynamic.getClass());
    }
}
class com.example.demo.proxy.cglib.Cglib$$EnhancerBySpringCGLIB$$767ff22
class com.example.demo.proxy.dynamic.DynamicImpl$$EnhancerBySpringCGLIB$$20a564d6

There are no additional configurations in the application. Only @SpringBootApplication class generated via spring initializr

Am I doing something wrong? The code was run on Spring Boot 2.7.2 and JDK 17.

CodePudding user response:

That is due to spring-boot autoconfiguation:

    @Configuration(proxyBeanMethods = false)
    @ConditionalOnBean(TransactionManager.class)
    @ConditionalOnMissingBean(AbstractTransactionManagementConfiguration.class)
    public static class EnableTransactionManagementConfiguration {

        @Configuration(proxyBeanMethods = false)
        @EnableTransactionManagement(proxyTargetClass = false)
        @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false")
        public static class JdkDynamicAutoProxyConfiguration {

        }

        @Configuration(proxyBeanMethods = false)
        @EnableTransactionManagement(proxyTargetClass = true)
        @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
                matchIfMissing = true)
        public static class CglibAutoProxyConfiguration {

        }

    }

it turns @EnableTransactionManagement(proxyTargetClass = true) (Indicate whether subclass-based (CGLIB) proxies are to be created (true) as opposed to standard Java interface-based proxies (false)) when the property spring.aop.proxy-target-class is not set (matchIfMissing = true)

  • Related