@Autowired 或 private Final 哪种方法更有效?

发布于 2025-01-18 18:57:20 字数 415 浏览 0 评论 0原文

我的问题很简单。哪种方法更有效? 正如我所看到的,method2 中的 DI 是更新的。但我想问一下,我该用哪一个呢?

方法一:

@Autowired
private CustomerRepository customerRepo;

方法二:

private final CustomerRepository custormerRepo;
public StudentService(CustomerRepository customerRepo) {
    this.customerRepo = customerRepo;
}

My question is simple. Which approach is more efficient?
As I see, the DI in the method2 is more recent. But I wanted to ask you which one should I use?

method 1:

@Autowired
private CustomerRepository customerRepo;

method 2:

private final CustomerRepository custormerRepo;
public StudentService(CustomerRepository customerRepo) {
    this.customerRepo = customerRepo;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

梦言归人 2025-01-25 18:57:20

tl; dr:方法2更灵活。

方法1是现场注入的一个示例,方法2是构造函数注入的示例。

现场注射具有一些构造仪注入避免的缺点。以下是构造函数注入的一些优点:

不变性:

您做不到的是普通的Java:

@Autowired
private final CustomerRepository customerRepo;

// No constructor that sets "customerRepo".

因此,Spring提供构造函数注入:

private final CustomerRepository customerRepo;

@Autowired
public StudentService(final CustomerRepository customerRepo) {
  this.customerRepo = customerRepo;
}

有时不可超过。原因之一是它有助于线程安全。另一个是安全性。

就个人而言,我遵循以下规则:“如果可以是最终,那应该是最终的。” 编辑23-05-23:如果您编写库是没有意义的,因为您希望功能可以轻松扩展和更改。

测试:

您不需要反思来设置依赖项。是的,许多模拟框架为您处理此操作,但是使用构造函数注入,您可以选择在构造函数上调用new

nasty nullpointerexception s:

通过调用其构造函数创建对象,对吗?我们通常希望我们的论点在传递时是非无效的。随着构造函数注入,弹簧IOC容器确保在将它们传递到构造函数之前,都可以使用构造函数中的所有参数。

TL;DR: Method 2 is much more flexible.

Method 1 is an example of field injection and method 2 is an example of constructor injection.

Field injection has some drawbacks that constructor injection avoids. Here are some advantages of constructor injection:

Immutability:

You can't do this is plain Java:

@Autowired
private final CustomerRepository customerRepo;

// No constructor that sets "customerRepo".

So, Spring offers constructor injection:

private final CustomerRepository customerRepo;

@Autowired
public StudentService(final CustomerRepository customerRepo) {
  this.customerRepo = customerRepo;
}

Immutability is sometimes preferred. One reason is that it helps with thread-safety. Another is security.

Personally, I follow the rule, "if it can be final, it should be final." EDIT 23-05-23: This rule doesn't make sense if you are writing a library, since you want functionality to be easily extended and changed.

Testing:

You won't need reflection to set the dependencies. Yes, many mocking frameworks handle this for you, but with constructor injection, you have the option to call new on the constructor.

Nasty NullPointerExceptions:

An object is created by calling its constructor, right? We usually want our arguments to be non-null at the time they are passed in. With constructor injection, the Spring IoC container makes sure that all the arguments passed in the constructor are available before passing them into the constructor.

Oo萌小芽oO 2025-01-25 18:57:20

我建议你推荐一些更好的东西。通过使用 Lombok 库的 @RequiredArgConstructor,您可以避免样板代码。如果你想知道为什么不推荐@Autowired,因为当你想在应用程序中编写单元测试时,如果你使用@Autowired,就会出现问题。

I suggest you suggest something better. By using the Lombok library's @RequiredArgConstructor you are thus avoiding the boilerplate code. and if you wonder why @Autowired not recommended , because of when you want to write unit testing in your application and there will be problem , where if you use @Autowired.

予囚 2025-01-25 18:57:20

在您的主代码中,您应该使用方法 2,因为不建议使用字段注入(方法 1)。 (参见此处 原因)

在您的测试代码中,可以使用方法 1。

In your main code, you should use method 2 as field injection (method 1) is not recommended. (see here for reasons)

In your test code, it's okay to use method 1.

往事随风而去 2025-01-25 18:57:20

使用构造函数注入,Spring也推荐它

use constructor injection, Spring also recommends it

零度℉ 2025-01-25 18:57:20

除了其他答案对不变性所说的话外,构造函数注入的另一个好处是能够避免NPE是该领域的初始化。使用自动化,从测试中,您将创建类,然后必须记住设置字段。使用构造函数注入,您无法初始化该字段。这在Kotlin中更为突出,在Kotlin中,自动字段被称为lateinit var,并在初始化之前使用运行时例外。但是,可以将构造函数参数声明为无效类型,这使您无法明确传递null。

In addition to what the other answers have said about immutability, another benefit of constructor injection is to be able to avoid NPE is the field is not initialized. Using autowired, from a test, you’d create the class and then must remember to set the field. Using constructor injection, you can’t not initialize the field. This is more prominent in Kotlin where autowired fields are declared as lateinit var and throw a runtime exception if used before initialized. But a constructor argument can be declared as not null type which prevents you from even explicitly passing null.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文