spring自动注入是单例还是多例?单例如何注入多例?

单例多例需要搞明白这些问题:

1. 什么是单例多例;

2. 如何产生单例多例;

3. 为什么要用单例多例

4. 什么时候用单例,什么时候用多例;

1. 什么是单例、多例:

单例模式和多例模式说明:

  1. 单例模式和多例模式属于对象模式。

  2. 单例模式的对象在整个系统中只有一份,多例模式可以有多个实例。

  3. 它们都不对外提供构造方法,即构造方法都为私有。

2. 如何产生单例、多例:

在通用的SSH中,单例在spring中是默认的,如果要产生多例,则在配置文件的bean中添加scope=”prototype”;

3. 为什么用单例、多例:

之所以用单例,是因为没必要每个请求都新建一个对象,这样子既浪费CPU又浪费内存;

之所以用多例,是为了防止并发问题;即一个请求改变了对象的状态,此时对象又处理另一个请求,而之前请求对对象状态的改变导致了对象对另一个请求做了错误的处理;

用单例和多例的标准只有一个:

当对象含有可改变的状态时(更精确的说就是在实际应用中该状态会改变),则多例,否则单例;

4. 何时用单例?何时用多例?

对于struts2来说,action必须用多例,因为action本身含有请求参数的值,即可改变的状态;

而对于STRUTS1来说,action则可用单例,因为请求参数的值是放在actionForm中,而非action中的;

另外要说一下,并不是说service或dao一定是单例,标准同第3点所讲的,就曾见过有的service中也包含了可改变的状态,同时执行方法也依赖该状态,但一样用的单例,这样就会出现隐藏的BUG,而并发的BUG通常很难重现和查找;

spring 生成对象默认是单例的。通过scope属性可以更改为多例

但是这种写法是错误的! 不能使用spring的自动注入!

由于service是单例的,所以这种方法的结果是:User多例,service和tool都是单例。(为什么?)

官网文档:

4.5.3 Singleton beans with prototype-bean dependencies

When you use singleton-scoped beans with dependencies on prototype beans, be aware that dependencies are resolved at instantiation time. Thus if you dependency-inject a prototype-scoped bean into a singleton-scoped bean, a new prototype bean is instantiated and then dependency-injected into the singleton bean. The prototype instance is the sole instance that is ever supplied to the singleton-scoped bean.

However, suppose you want the singleton-scoped bean to acquire a new instance of the prototype-scoped bean repeatedly at runtime. You cannot dependency-inject a prototype-scoped bean into your singleton bean, because that injection occurs only once, when the Spring container is instantiating the singleton bean and resolving and injecting its dependencies. If you need a new instance of a prototype bean at runtime more than once, see Section 4.4.6, “Method injection”

正确的写法是,是每次调用tool时都生成一个新的tool对象。但是我们又不能手动new一个,要借助BeanFactory

UserService 通过实现 BeanFactoryAware 接口来获得factory

由于不使用spring的自动注入,set方法要去掉!

配置文件,不能再使用注入。因此要把tool对象的注入去掉!

测试类:

public class Test {
public static void main(String[] args) {
ClassPathResource res = new ClassPathResource(“applicationContext.xml”);
XmlBeanFactory factory = new XmlBeanFactory(res);
User user = (User)factory.getBean(“user”);
User user2 = (User)factory.getBean(“user”);
System.out.println(user);
user.getService().service();
System.out.println();
System.out.println(user2);
user2.getService().service();
}
}

Original: https://www.cnblogs.com/goody9807/p/7472139.html
Author: PointNet
Title: spring自动注入是单例还是多例?单例如何注入多例?

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/541646/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球