I am trying to get an high level view of how the Spring proxy works. Why should I use "API Interface & Impl Bean" pattern or only the "Bean Class" pattern in my application. I read quite a few SO answers but they are all very old, mostly relevant to Java 7 with Spring 3.x I believe. I would like to know what is still relevant in 2020 for Java 11+ with Spring 5.x (Spring Boot 2.x). Is there any "best practice" which can be followed?
Also, with the availability of @FunctionalInterface
, if I have beans that are implementing interfaces like Consumer
, Function
, Predicate
and similar ones, does it make sense to @Autowire/@Inject
Consumer<A>
instead of Foo
where Foo implements Consumer<A>
. This is just an example, I might be using Functional Interfaces (with or without Generics) of my own as well.
With all the above in mind, I would also like to know if every bean created by Spring is proxied, or does spring create beans without proxying them if it is not actually required. For ex. if a class is simply annotated with @Component
and injected directly, no other annotations or proxy requirement, will spring still create a proxy for this bean?
Some questions that I have already had a look at:
- Why always have single implementation interfaces in service and dao layers?
- what reasons are there to use interfaces (Java EE or Spring and JPA)
- What is the difference between JDK dynamic proxy and CGLib?
UPDATE 7th May, 2020:
After reading a few more articles, comments and answers, I would like to talk about the exact problem/query I have in mind. Let's consider the following example. I have a classes Foo
and AnotherFoo
.
@Component
@RequiredArgsConstructor // From lombok
class Foo extends Consumer<Bar> {
// Some private final Fields
public void accept(Bar bar) {
// do something
}
// Some private methods, no other public method
}
Option 1:
@Component
@RequiredArgsConstructor // From lombok
class AnotherFoo {
private final Foo foo;
// Use foo only to call foo.accept(bar)
}
Option 2:
@Component
@RequiredArgsConstructor // From lombok
class AnotherFoo {
private final Consumer<Bar> foo;
// Use foo only to call foo.accept(bar)
}
Now in the above case, if we talk in terms of proxying of bean of Foo
by Spring, what might be the best way of writing AnotherFoo
- Option 1 or Option 2 or maybe it is irrelevant how AnotherFoo
is written. I am not using @EnableAspectJAutoProxy
anywhere in the code, so things are running by default here, most likely similar to Case 3 of A2 of this SO question.
Extra Question: Also, if CGLib is used here/anywhere for proxying, I understand that it manipulates the byte code to create proxies. In some articles I could read that this approach poses a security threat. I would like to understand if it is actually a problem & if yes, how would that impact the application?