Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Spring Boot default proxying mechanism

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.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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.

>Solution :

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)

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading