所有 Spring beans 都是代理的吗?

Muk*_*lan 5 java spring spring-aop spring-boot

我试图从高层次上了解 Spring 代理的工作原理。为什么我应该在应用程序中使用“API Interface & Impl Bean”模式或仅使用“Bean Class”模式。我读了很多 SO 答案,但它们都非常古老,我相信大多与Java 7 和 Spring 3.x相关。我想知道 2020 年Java 11+ 与 Spring 5.x (Spring Boot 2.x)仍然相关。有什么可以遵循的“最佳实践”吗?

另外,随着 的可用性@FunctionalInterface,如果我有实现像ConsumerFunction和类似接口的 bean,那么用where代替是否Predicate有意义。这只是一个例子,我也可能使用我自己的功能接口(带或不带泛型)。@Autowire/@Inject Consumer<A>FooFoo implements Consumer<A>

考虑到上述所有内容,我还想知道 Spring 创建的每个 bean 是否都被代理,或者如果实际上不需要的话,spring 创建 bean 时是否不代理它们。对于前。如果一个类只是简单地注释并@Component直接注入,没有其他注释或代理需求,spring还会为这个bean创建代理吗?

我已经看过的一些问题:

2020 年 5 月 7 日更新:

在阅读了更多文章、评论和答案后,我想谈谈我想到的确切问题/疑问。让我们考虑以下示例。我有一个课程FooAnotherFoo

@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
}
Run Code Online (Sandbox Code Playgroud)

选项1:

@Component
@RequiredArgsConstructor  // From lombok
class AnotherFoo {

    private final Foo foo;

    // Use foo only to call foo.accept(bar)
}
Run Code Online (Sandbox Code Playgroud)

选项2:

@Component
@RequiredArgsConstructor  // From lombok
class AnotherFoo {

    private final Consumer<Bar> foo;

    // Use foo only to call foo.accept(bar)
}
Run Code Online (Sandbox Code Playgroud)

现在,在上述情况下,如果我们谈论FooSpring 的 bean 代理,那么什么可能是最好的编写方式AnotherFoo-选项 1选项 2或者可能与如何AnotherFoo编写无关。我没有@EnableAspectJAutoProxy在代码中的任何地方使用,所以这里默认运行,很可能类似于这个SO问题的A2的情况3

额外问题:另外,如果在这里/任何地方使用 CGLib 进行代理,我知道它会操纵字节码来创建代理。在一些文章中,我可以读到这种方法会带来安全威胁。我想了解这是否确实是一个问题,如果是,这会对应用程序产生什么影响?

kri*_*aex 0

如果你想了解 Spring 代理是如何工作的,我有两个资源供你使用: