![](/img/trans.png)
[英]In a Spring boot test, how can I create a bean and injects by @Autowired?
[英]How Singleton bean can be Autowired in different places spring boot
在这一点上,我很困惑,根据我的理解,如果我们使用@Service
批注对类进行注释,那么bean只能在一个类中进行@Autowired
(如果我错了,请纠正我) )这是可以正常工作的代码,但我试图了解它的工作原理? 如何在两个不同的类中@Autowired
一个bean?
如何在SampleController2
和SampleController3
中一次@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
被自动连接到sampleController2
和sampleController3
。
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.