Spring Boot
proxying
Java
Spring Framework
software development

Spring Boot default proxying mechanism

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Spring uses proxies to implement features such as @Transactional, caching, async execution, and method-level AOP advice. To understand Spring Boot’s default proxying behavior, you need to separate two ideas: how Spring Framework can proxy beans in general, and which proxy style Spring Boot prefers when its auto-configuration is involved.

The two proxy styles

Spring commonly uses one of these mechanisms:

  • JDK dynamic proxies, which proxy interfaces
  • CGLIB class-based proxies, which subclass the target class

If a bean is proxied with JDK dynamic proxies, callers typically interact with the bean through an interface. If CGLIB is used, Spring creates a subclass of the concrete class and intercepts method calls there.

A minimal target might look like this:

java
1public interface BillingService {
2    void charge();
3}
4
5@Service
6public class BillingServiceImpl implements BillingService {
7
8    @Transactional
9    public void charge() {
10        System.out.println("charging");
11    }
12}

The transaction behavior is not injected into the method body directly. Instead, Spring places a proxy in front of the bean and the proxy starts and ends the transaction around the method call.

What Spring Boot defaults to

In plain Spring Framework, interface-based proxying is a common baseline if interfaces are available. In Spring Boot applications, auto-configured AOP generally defaults to class-based proxying, which means CGLIB-style proxies are the usual default unless you turn that behavior off.

That is why many Boot applications proxy concrete classes successfully even when the code does not rely on interfaces everywhere.

You can make the preference explicit in configuration:

properties
spring.aop.proxy-target-class=true

and switch back to interface-based proxying with:

properties
spring.aop.proxy-target-class=false

The property name is useful because it describes the actual choice: proxy the target class itself, or do not.

Why proxies matter for application behavior

Understanding proxying explains several common Spring behaviors:

  • advice applies only when a call goes through the proxy
  • self-invocation usually bypasses proxy advice
  • final classes or final methods can interfere with class-based proxies

For example:

java
1@Service
2public class ReportService {
3
4    @Transactional
5    public void outer() {
6        inner();
7    }
8
9    @Transactional
10    public void inner() {
11        System.out.println("inside inner");
12    }
13}

If outer() calls inner() directly on this, that second call does not pass through the proxy. This surprises many developers because both methods are annotated, but the proxy can only intercept external calls that actually go through it.

When JDK proxies still make sense

Interface-based proxies are still useful when:

  • your code is already strongly interface-driven
  • you want proxying limited to interface contracts
  • you prefer not to rely on subclassing semantics

They also make proxy type expectations more predictable in some architectures. For example, code that expects the bean to be assignable to a concrete implementation may behave differently depending on proxy style.

Common Pitfalls

The biggest pitfall is forgetting that proxies wrap method calls; they do not rewrite your class internals. Self-invocation is therefore a frequent source of "why didn’t @Transactional run" bugs.

Another issue is assuming the proxy style is irrelevant. It affects whether concrete classes, interfaces, final methods, and bean-type checks behave the way you expect.

People also confuse Spring Boot’s convenience default with a universal Spring rule. Framework behavior is broader than Boot’s default settings, so it helps to speak precisely about which layer you mean.

Finally, if you force class-based proxies, remember that final classes and final methods limit what subclass-based interception can do.

Summary

  • Spring features such as transactions and AOP commonly work through proxies.
  • The two main mechanisms are JDK interface proxies and CGLIB class-based proxies.
  • In Spring Boot auto-configuration, class-based proxying is the usual default.
  • Advice is applied only when calls pass through the proxy, so self-invocation often bypasses it.
  • Understanding the proxy style helps explain transaction, caching, and AOP surprises in real applications.

Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.