我试图从高层次上了解 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)(带或不带泛型)。
@Component
进行注释并且直接注入(inject),没有其他注释或代理要求,spring还会为这个bean创建代理吗?
我已经看过的一些问题:
- 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?
2020 年 5 月 7 日更新:
阅读了更多文章、评论和答案后,我想谈谈我想到的确切问题/疑问。让我们考虑以下示例。我有课Foo
和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
}
选项 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/