Spring注入-单例/多例模式问题

5,668 阅读2分钟

Spring注入-单例/多例模式问题

什么是单例模式、多例模式?

单例模式:

  1. 构造方法为私有,这样外界就不能随意调用;

  2. get的方法为静态,由类直接调用;

    (单例模式的类实现方法有饿汉式和懒汉式,这个可以单独学习了解)

多例模式:

  1. 类可以有多个实例 ;
  2. 类必须能够自我创建并管理自己的实例,并向外界提供自己的实例;

总结:

  1. 每次调用单例类的实例对象时,都获得同一个对象;
  2. 每次调用多例类的实例对象时,会获取到不同的对象(类会自建新的对象)。

Spring注入如何实现单例/多例模式?

单例模式:

Spring的bean默认注入单例的,它在Spring容器初始化的时候创建对象;

多例模式:

  • 可以修改为多例,在此bean节点中添加一个属性,scope="prototype":
<bean id="xxx" class="全类名" scope="prototype"></bean>
  • 或者通过注解实现:
@Component
@Scope("prototype")
  • 注意

(1)多例模式在进行注入时,不能使用 @Autowired,否则注入的还是单例模式,实现多例模式需要使用工厂模式

(2)此外,@Autowired+@Qualifier("student") 与@Resource作用一致,当获取对象时,并不能稳定获 取到多例,在使用时需要注意。

单例/多例模式测试

单例模式:

image-20210930104042408.png

多例模式:

image-20210930104144865.png

Spring注解 单例/多例模式测试

@Autowired注入的是单例模式还是多例模式,使用两个测试类分别通过@Autowired注入类对象,通过debug断点测试,看在两个测试类中的对象是否为同一个。

测试结果:

  1. 结果证明通过@Scope("prototype"),@Autowired注入的也是单例模式
  2. 通过相同证明方法, @Resource注入的是对象不稳定,有时能获取相同对象,有时获取到的是不同对象
  3. @Autowired+@Qualifier("student") 与@Resource作用一致;
这里的区别是因为@Autowired@Resource注解的处理逻辑不同:
​
对于@Resource注解,会根据要注入属性的name,从单实例池中找到类,获取bean,完成属性注入;
spring在解析@Autowired注解的时候,并不是直接从单实例池中查找bean,而是先从beanDefinitionMap中,根据type查找,如果找到多个,再根据name从单实例池中查找,只有找到确定要注入哪个类,才会从单实例池中找到对应的bean,完成注入

单例模式:

image-20210930105438796.png

image-20210930105359251.png

多例模式:

image-20210930115107366.png

image-20210930115136192.png

如有错误,欢迎指正