java - 所有 Spring beans 都是代理的吗?

标签 java spring spring-boot spring-aop

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

此外,随着 @FunctionalInterface 的可用性,如果我有实现像Consumer这样的接口(interface)的bean , Function , Predicate和类似的,对 @Autowire/@Inject 有意义吗? Consumer<A>而不是Foo哪里Foo implements Consumer<A> 。这只是一个示例,我也可能使用我自己的函数式接口(interface)(带或不带泛型)。

考虑到上述所有内容,我还想知道 Spring 创建的每个 bean 是否都被代理,或者如果实际上不需要,Spring 是否创建 bean 而不代理它们。对于前。如果一个类只是简单地用 @Component 进行注释并且直接注入(inject),没有其他注释或代理要求,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
}

选项 1:

@Component
@RequiredArgsConstructor  // From lombok
class AnotherFoo {

    private final Foo foo;

    // Use foo only to call foo.accept(bar)
}

选项 2:

@Component
@RequiredArgsConstructor  // From lombok
class AnotherFoo {

    private final Consumer<Bar> foo;

    // Use foo only to call foo.accept(bar)
}

现在在上面的例子中,如果我们谈论Foo的bean的代理Spring,什么可能是最好的写作方式 AnotherFoo - 选项 1选项 2 或者可能与 AnotherFoo 无关被写。我没有使用@EnableAspectJAutoProxy代码中的任何位置,因此这里默认运行,很可能类似于 Case 3 of A2 of this SO question .

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

最佳答案

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

  • 我的回答 here它用示例代码从概念上解释了 Spring 代理的工作原理(但不使用 Spring,只是简单的 POJO)。
  • Spring 手册,章节 "understanding Spring proxies"

关于java - 所有 Spring beans 都是代理的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61632857/

相关文章:

java - 在 Java8 中连接对象数组列表

spring-boot - 如何在Spring Boot应用程序中动态更改logback日志级别

spring-boot - 我如何在 Spring Boot-1.4.1-RELEASE 中制作 init-sql

java - 从 Java 应用程序编译和运行源代码

java - 何时使用参数以及何时使用实例数据?

java - Apache UrlValidator 认为 URL 无效

java - REST API - DTO 与否?

java - Spring 长轮询

spring - 如何在 Spring 中声明一个可选的@Bean?

java - 如何使用Spring云数据流转换Mysql数据http调用?