简体   繁体   English

Spring框架中的原型bean scope实现

[英]Prototype bean scope implementation in Spring Framework

Hello guys I am trying to understand how exactly prototype Scope works in Spring IoC.大家好,我想了解原型 Scope 在 Spring IoC 中的工作原理。

For prototype beans I tried to understand by:对于原型 bean,我试图通过以下方式理解:
1. Reading this again and again but could not understand fully( https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-factory-scopes-other-injection ) 1.一遍又一遍地阅读但无法完全理解( https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-factory-scopes-other-injection
2. Tried to debug via source code,only understood one thing if we do not specify proxyMode, it will not create proxy for prototype bean. 2.尝试通过源码调试,只明白一件事,如果我们不指定proxyMode,它就不会为prototype bean创建代理。
3. default ScopedProxyMode for prototype scope is DEFAULT which typically equals NO.. unless configured in component scan. 3. 原型 scope 的默认ScopedProxyMode为 DEFAULT,通常等于 NO.. 除非在组件扫描中配置。

So I have 3 examples here:所以我在这里有3个例子:

Case A: Prototype bean used independently(not having any dependency or is not dependency for any bean) without proxymode defined案例 A:原型 bean 独立使用(没有任何依赖关系或不依赖任何 bean),没有定义代理模式

@Bean
@Scope("prototype")
public Employee employee(){
  return new Employee();
}

Case B: Prototype bean inside a singleton bean as dependency without proxymode defined案例 B:singleton bean 中的原型 bean 作为依赖项,但未定义代理模式

@Bean
@Scope("prototype")
public Employee employee(){
  return new Employee();
}

@Bean
@Scope("singleton")
public Department department(){
  return new Department();
}

Case C: Prototype bean inside a singleton bean as dependancy with proxymode defined案例 C:singleton bean 中的原型 bean 作为定义的代理模式的依赖关系

@Bean
@Scope("prototype",proxyMode= ScopedProxyMode.TARGET_CLASS)
public Employee employee(){
  return new Employee();
}

@Bean
@Scope("singleton")
public Department department(){
  return new Department();
}

Guys questions here are:伙计们的问题是:

  1. How will case A, case B and case C work?案例 A、案例 B 和案例 C 将如何工作?
  2. I am trying to understand what exactly will be correct way.我试图了解正确的方法。
  3. Also not specifying proxymode is correct or not?也不指定 proxymode 是否正确?
  4. What happens when proxyMode is not set?未设置 proxyMode 时会发生什么? how does prototype work then?那么原型是如何工作的呢?

What I typically saw in implementation examples on internet is people often do not configure proxyMode either mistakenly or are not aware about this option or maybe they are right.我通常在互联网上的实现示例中看到的是,人们通常不会错误地配置 proxyMode,或者不知道这个选项,或者他们可能是对的。

Thank you for your valuable time.感谢您宝贵的时间。

  • A, B, and C will all return new instance of Employee when requested. A、B 和 C 都会在请求时返回新的 Employee 实例。
  • A and B are usual ways to use prototype scopes. A 和 B 是使用原型作用域的常用方法。
  • Not specifying is the usual way.不指定是通常的方式。 Though in some instances where scope is RequestScope or Session scope, etc, it might make sense to specify proxyMode.尽管在某些情况下 scope 是 RequestScope 或 Session scope 等,但指定 proxyMode 可能是有意义的。 Regarding specifying proxyMode, see the last paragraph.关于指定 proxyMode,请参见最后一段。
  • If not set, you get the expected behavior.如果未设置,您将获得预期的行为。 That is, you get new instance every time a bean instance is requested.也就是说,每次请求 bean 实例时都会获得新实例。

The prototype scope instructs Spring to instantiate a new instance of the bean everytime a bean instance is requested by the application.原型 scope 指示 Spring 每次应用程序请求 bean 实例时实例化 bean 的新实例。

You should consider using prototype scope in the following scenarios:您应该考虑在以下情况下使用原型 scope:

  • If you have a bean that has a lot of writable state, you may find that the cost of synchronization is greater than the cost of creating a new instance to handle each request from a dependent object.如果您的 bean 有很多可写的 state,您可能会发现同步的成本大于创建新实例以处理来自依赖 object 的每个请求的成本。
  • Some dependent objects need a bean that has private state so that they can conduct their processing separately from other objects that depend on the bean.一些依赖对象需要一个具有私有 state 的 bean,以便它们可以独立于依赖 bean 的其他对象进行处理。 In this case, singletons are clearly not suitable.在这种情况下,单例显然是不合适的。 Consider prototypes.考虑原型。

It is a good practice that your beans should implement some interface. bean 应该实现一些接口是一个很好的做法。 In that case, Spring uses JDK proxy mechanism to create proxy of your class.在这种情况下,Spring 使用 JDK 代理机制来创建 class 的代理。 But implementing interface is not a requirement.但是实现接口不是必需的。 If no interface is implemented by your bean, then Spring uses CGLIB library to create proxy of your bean (unless a class is annotated with @Configuration in which case a different proxy mechanism is used).如果您的 bean 没有实现任何接口,则 Spring 使用 CGLIB 库来创建您的 bean 的代理(除非 class 使用 @Configuration 注释,在这种情况下使用不同的代理机制)。

By specifying proxyMode=ScopedProxyMode.TARGET_CLASS , you are forcing Spring to use CGLIB proxy mechanism.通过指定proxyMode=ScopedProxyMode.TARGET_CLASS ,您将强制 Spring 使用 CGLIB 代理机制。 In the end, just providing @Scope("prototype") is sufficient.最后,只需提供@Scope("prototype")就足够了。

On a side note, know that if you have any methods that hook into lifecycle of a bean (like @PreDestroy , implementing DisposableBean interface, or destroyMethod as a flag in @Bean ), then those methods will never be called in prototype scoped beans.附带说明一下,如果您有任何挂钩到 bean 生命周期的方法(例如@PreDestroy ,实现DisposableBean接口,或作为destroyMethod中的标志的@Bean ),那么这些方法将永远不会在原型范围的 bean 中调用。

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

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