繁体   English   中英

Singleton bean如何在不同的地方自动布线

[英]How Singleton bean can be Autowired in different places spring boot

在这一点上,我很困惑,根据我的理解,如果我们使用@Service批注对类进行注释,那么bean只能在一个类中进行@Autowired (如果我错了,请纠正我) )这是可以正常工作的代码,但我试图了解它的工作原理? 如何在两个不同的类中@Autowired一个bean?

如何在SampleController2SampleController3中一次@Autowired SampleService bean?

这是推荐的方法吗? 在这种情况下,两个线程可以并行更改bean中的数据?

SampleController2

@RestController
@RequestMapping(value="samplemock")
public class SampleController2 {

@Autowired
private SampleService2 sampleservice2;

@RequestMapping(value="/mock1",method=RequestMethod.GET)
public void mockCall1() {
    sampleservice2.m1();
   }

}

SampleController3

@RestController
@RequestMapping(value="samplemock2")
public class SampleController3 {

@Autowired
private SampleService2 sampleservice2;

@RequestMapping(value="/mock1",method=RequestMethod.GET)
public void mockCall1() {
    sampleservice2.m1();

   }
 }

SampleService2

@Service
 public class SampleService2 {

public void m1() {
    System.out.println("bean is autowired");
    }
 }

正如您提到的,默认情况下,所有Spring Bean都是单例的,但是您的第二个假设是错误的:同一bean可以在许多其他bean中自动装配。

实际上,这就是单身人士的全部要点。

这也意味着两个不同的线程确实可以更改同一bean的状态。 出于这种原因,您大多数时候都希望使bean保持无状态。

如果确实需要在每个自动装配的位置使用一个bean的不同实例,则可以将该bean的范围更改为prototype 参见Spring bean scopes文档

这是Spring在启动时所做的简化视图:

// Create bean: sampleService2
SampleService2 sampleService2 = new SampleService2();

// Create bean: sampleController2
SampleController2 sampleController2 = new SampleController2();
sampleController2.sampleservice2 = sampleService2; // because @Autowired

// Create bean: sampleController3
SampleController3 sampleController3 = new SampleController3();
sampleController3.sampleservice2 = sampleService2; // because @Autowired

如您所见,单例bean sampleService2被自动连接到sampleController2sampleController3

Bean被添加到存储库中,因此您可以在以后的任何时间按名称或类型进行查找。

依赖项注入和控制反转的意图很简单:

  • 定义你的注射剂(如服务) 一次 ,以及(除非另行指定),他们被实例化一次
  • 然后,这些可注射剂将在所有适用的地方使用 ,并且您无法控制其生命周期,作用域或状态。

尽管我觉得最后一点很默契地回答了您的主要问题,但我会详细说明-在直接投资的背景下,唯一真正重要的是可强制执行的合同。 就是说,如果您的服务订阅了特定类型的合同,并且您有一个组件希望注入能够履行该合同的服务,那么您的DI层应该如实地注册一个可以履行该合同的服务。

此时,您将获得有关bean优先级,限定符和应用程序配置文件的有趣知识,但这是总的想法。

举一个具体的例子: javax.sql.DataSource是一个由许多JDBC支持的解决方案(例如MySQL,Postgres,Oracle等)实现的接口。 如果你想有两个不同的豆子这跟两个不同的数据库,但要能够交替使用的,那么你定义类型的bean的DataSource使用和配置数据源被创建。 同样,这确实涉及到@Qualifier事情,以确保您在最合适的时间连接最具体的bean。

此外,最后一点对于回答问题的这一部分非常重要:

...并且在这种情况下,两个线程可以并行更改Bean中的数据?

创建具有其固有状态的可注入bean是非常不明智的。 也就是说,如果您让SampleService将其自身附加到某种内部带有集合的缓存状态,则基本上是在违反期望,因为您不知道该集合何时或多SampleService添加或删除元素从中。

更好的约定是让bean可以引用有状态服务,但不要将该状态存储在bean本身中(例如数据库连接,而不是整个数据库表)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM