Does Spring always create proxies for injected beans by default, or only when explicitly enabled (like with u/EnableAspectJAutoProxy)?
Spring doesn't wrap all your beans in proxies by default. It only creates a proxy when it needs to add extra behavior around your method - like for @Transactional
, @Async
, or @Cacheable
.
A proxy is just a wrapper that intercepts method calls. It lets Spring run extra logic before or after your method - for example, starting a transaction, catching exceptions, or logging.
For example, if you have a method like:
@Transactional
public void save() { ... }
Spring sees the @Transactional
annotation and doesn't call the method directly. Instead, it creates a proxy - a special wrapper - that steps in between. The proxy will start a database transaction before calling save()
, and commit or rollback the transaction afterward, depending on whether an exception was thrown.
This way, you don't need to write any manual transaction code - Spring handles it automatically behind the scenes.
But if your bean is just a regular @Service
or @Component
without any special annotations, Spring will inject the real instance directly, without any proxy.
The @EnableAspectJAutoProxy
annotation tells Spring to enable AOP support, which means Spring will create proxies for aspects or advice methods you define (like @Around
, @Before
, etc.). Without it, those won't work.
If you're curious whether a bean is proxied, just print its class:
System.out.println(myBean.getClass());
If the output contains something like $$SpringCGLIB$$
, it’s a proxy. Otherwise, it’s just your plain class.
Sometimes it's confusing because both @Bean
and proxies involve Spring managing the object.In both cases, the object isn't created manually - Spring handles it behind the scenes. That can give the impression that if Spring creates something, it's always a proxy.