4

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:

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?

Mukund Jalan
  • 1,145
  • 20
  • 39
  • 3
    No, beans aren't _always_ proxied; at a minimum, it's perfectly possible to create a bean of a `final` class. – chrylis -cautiouslyoptimistic- May 06 '20 at 10:39
  • What if the class is not final? – Mukund Jalan May 06 '20 at 10:44
  • 1
    Please go through A2 part of this answer https://stackoverflow.com/a/59770104/4214241 – R.G May 06 '20 at 10:46
  • 1
    Also a non-final class only gets proxied if it is necessary because you use cross-cutting functionality implemented in Spring AOP, which is also used internally in Spring for some cross-cutting concerns such as transactions and probably (I am not a Spring user, thus the guess) also für security (authorisation), to name a few. As long as your own application or Spring itself do not "hook into" the bean to decorate it with interceptors, advices or other additional functionality, no proxy will be created. That happens on demand. – kriegaex May 06 '20 at 11:02

1 Answers1

0

If you want to understand how Spring proxies work, I have two sources for you:

  • my answer here which conceptually explains with sample code (but without using Spring, just simple POJOs) how Spring proxies work.
  • the Spring manual, chapter "understanding Spring proxies"
kriegaex
  • 63,017
  • 15
  • 111
  • 202