Spring-单例模式和依赖注入
设计模式
参考:https://www.cnblogs.com/android-blogs/p/5530239.html
1. Spring管理的对象的作用域与生命周期(不常用)
由Spring管理的对象,默认都是单例的!并且,都是饿汉式的单例模式。
在配置<bean>
节点时,可以添加scope
属性其是否单例,当取值为singleton
时表示单例,该值也是默认值,当取值为prototype
时表示非单例:
<bean id="user" class="cn.tedu.spring.User"scope="prototype"></bean>
在单例模式的基础之上,还可以通过lazy-init
属性配置它是否为懒汉式的单例模式,默认值为false
,即非懒汉式,也就是饿汉式的单例模式,当取值为true
时,表示懒汉式的单例模式:
<bean id="user" class="cn.tedu.spring.User"scope="singleton"lazy-init="true"></bean>
如果某个类被配置为单例模式,还可以配置它的生命周期方法:首先,在类中声明2个方法,这2个方法都应该是public
方法,返回值都是void
,方法名称可以自由定义,方法必须没有参数,例如:
public void init() {System.out.println("User.init()");
}public void destroy() {System.out.println("User.destroy()");
}
然后,在Spring的配置文件中,在<bean>
节点中配置init-method
和destroy-method
属性,即可配置初始化方法和销毁方法,这2个属性的取值都是需要调用的方法的名称:
<bean id="user" class="cn.tedu.spring.User"scope="singleton"lazy-init="true"init-method="init"destroy-method="destroy"></bean>
2. Spring的IoC
2.1. 什么是IoC
IoC表示Inversion of control,即“控制反转”。传统模式下,对象的创建与管理都是由开发人员编写代码直接完成的,而使用Spring后,将创建与管理交给了框架,则称之为控制反转。
其中,比较重要的环节是为对象的某些属性进行赋值,称之为DI,即Dependency Injection,表示“依赖注入”,通俗的来说,是为其属性赋值,也称之为“为其属性注入值”。
Spring通过DI实现了IoC,即DI是实现手段,而IoC是需要实现的目标。
2.2. 通过SET方式注入属性的值
假设User
类中有名为name
的属性,需要为该属性注入值,首先,需要为该属性添加SET/GET方法(其实只有SET方法是必须的):
public void setName(String name) {this.name = name;
}
然后,在<bean>
节点子级添加<property>
节点进行配置:
<bean id="user" class="cn.tedu.spring.User"><!-- 使用property节点为属性注入值 --><!-- name:属性名 --><!-- value:属性值 --><property name="name" value="Kitty"></property>
</bean>
其实,框架在处理时,发现有<property>
节点,就会尝试为属性赋值,它会基于该节点的name
属性值得到SET方法的名称,规则就是set
加上属性名且首字母改为大写,得到SET方法名称,如果属性名称是name
,则框架将调用的方法就是setName
,如果属性名称是password
,则框架将调用的方法已经setPassword
,然后,将value
属性对应的值,作为将调用的方法的参数,以上示例代码中的配置,使得框架将调用对象.setName("Kityy");
语句。
所以,在<property>
节点中,name
属性配置的其实是SET方法的方法名右侧的部分,且首字母改为小写!
但是,在实际使用时,SET方法都是由开发工具自动生成,生成规则与Spring框架处理时的规则是完全相同的,所以,也可以简单的认为<property>
节点中配置的name
就是属性的名称!
在某些情况下,需要注入的属性值并不是基本值(可以直接书写的值,例如数值、字符串等),而是另一个类的对象时,可以先使得Spring也管理另一个类的对象,然后,注入值时,通过ref
属性引用那个<bean>
即可:
2.3. 通过构造方法注入属性的值(不常用)
如果某个属性是通过构造方法设置值的,例如:
public class Person {// 25private Integer age;public Person(Integer age) {super();this.age = age;}@Overridepublic String toString() {return "Person [age=" + age + "]";}}
则在配置时,应该使用<constructor-arg>
节点进行配置:
<bean id="person" class="cn.tedu.spring.Person"><constructor-arg index="0" value="25" />
</bean>
以上属性的配置中,index
表示第几个参数,从0开始顺序编号,然后,根据值的类型选择使用value
或ref
属性进行配置即可!
2.4. 注入集合类型的值
如果某个类中的属性是List
集合类型的,并需要注入值:
public class SampleBean {// Alex, Lucy, Kitty, Henrypublic List<String> names;public void setNames(List<String> names) {this.names = names;}}
然后,在Spring的配置文件中:
<bean id="sampleBean"class="cn.tedu.spring.SampleBean"><property name="names"><list><value>Alex</value><value>Lucy</value><value>Kitty</value><value>Henry</value></list></property>
</bean>
如果需要注入Set
类型的值,例如:
// Beijing, Shanghai, Guangzhou, Shenzhen
public Set<String> cities;
在配置注入时,使用<set>
节点即可:
<property name="cities"><set><value>Beijing</value><value>Shanghai</value><value>Guangzhou</value><value>Shenzhen</value></set>
</property>
另外,关于Map
类型集合的配置例如:
<property name="session"><map><entry key="username" value="Jack" /><entry key="password" value="1234" /><entry key="from" value="Nanjing" /></map>
</property>
关于数组类型集合的配置例如:
<property name="numbers"><array><value>9</value><value>5</value><value>2</value><value>7</value></array>
</property>
在配置数组时,也可以使用
<list>
节点,反之,在配置List
集合时,也可以使用<array>
节点,但是,推荐使用匹配的节点进行配置。
关于Properties
类型的配置:
<property name="config"><props><prop key="driver">com.mysql.jdbc.Driver</prop><prop key="username">root</prop><prop key="password">root</prop></props>
</property>
在配置以上集合类型的值时,也可以事先使用例如<util:list>
这类节点先将值配置好:
<util:list id="names"><value>Tom</value><value>Alex</value><value>Lucy</value><value>Kitty</value><value>Henry</value>
</util:list>
然后再注入到属性中:
<property name="names" ref="names" />
比较特殊的是读取Properties
类型的数据,在Spring中,可以通过<util:properties>
节点的location
属性指定需要读取的文件:
<util:properties id="config"location="classpath:db.properties" />
然后,就可以注入到相应的属性中:
<property name="config" ref="config" />
Spring-单例模式和依赖注入相关推荐
- JavaEE开发之Spring中的依赖注入与AOP编程
上篇博客我们系统的聊了<JavaEE开发之基于Eclipse的环境搭建以及Maven Web App的创建>,并在之前的博客中我们聊了依赖注入的相关东西,并且使用Objective-C的R ...
- spring中的依赖注入——构造函数注入、set方法注入( 更常用的方式)、复杂类型的注入/集合类型的注入
spring中的依赖注入 依赖注入: Dependency Injection IOC的作用:降低程序间的耦合(依赖关系) 依赖关系的管理:以后都交给spring来维护.在当前类需要用到其他类的对象, ...
- spring四种依赖注入方式
平常的java开发中,程序员在某个类中需要依赖其它类的方法,通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理. spring提出了依赖注入的思想,即依赖不由程序 ...
- 详解Spring框架的依赖注入
本篇主要介绍Spring的依赖注入.依赖注入是Spring协调不同Bean实例之间的合作而提供的一种工作机制,在确保Bean实例之间合作的同时,并能保持每个Bean的相对独立性.通过本篇的学习,可以达 ...
- Spring系列之依赖注入的三种方式
目录 一.依赖注入方式 1.使用属性的setXXX方法注入 2.构造函数注入 (1)按类型匹配入参type (2)按索引匹配入参index (3)联合使用类型和索引匹配入参[type和index一起使 ...
- Spring -Spring的 DI - 依赖注入的 使用学习
一 . spring的DI 依赖注入,一句话总结 :给属性赋值 : 一个类中的属性都可以采用springDI的方式进行赋值,但是并不是所有的属性都适合赋值: 1. 利用set给属性 ...
- Spring.net的依赖注入
Spring.net的依赖注入 IOC的基本概念是:不创建对象,但是描述创建它们的方式.在代码中不直接与对象和服务连接,但在配置文件中描述哪一个组件需要哪一项服务.容器负责将这些联系在一起. 其原理是 ...
- 详解 Spring 框架的依赖注入
本篇主要介绍 Spring 的依赖注入.依赖注入是 Spring 协调不同 Bean 实例之间的合作而提供的一种工作机制,在确保 Bean 实例之间合作的同时,并能保持每个 Bean 的相对独立性.通 ...
- spring源码依赖注入的核心方法populateBean(beanName, mbd, instanceWrapper)分析
spring源码依赖注入的核心方法populateBean(beanName, mbd, instanceWrapper)分析:通过源码我们发现在分析这个方法之前,此对象已经创建完成实例,内存开辟了空 ...
- Spring Boot 单例模式中依赖注入问题
在日常项目开发中,单例模式可以说是最常用到的设计模式,项目也常常在单例模式中需要使用 Service 逻辑层的方法来实现某些功能.通常可能会使用 @Resource 或者 @Autowired 来自动 ...
最新文章
- 8张图让你一步步看清 async/await 和 promise 的执行顺序
- oracle密码加密工具下载,oracle加密工具wrap
- 移动重定位表到新增节
- ListView已到底部和顶部的判断
- Steps to developing Metro style apps 第一章-Creat a UI(2)(4)
- 自由轴法 matlab,一种自由轴法RLC测量电路设计
- IDEA开发工具的学习
- mysql8默认字符编码_mysql默认字符编码问题
- windows10重装后锁定其他盘_电脑重装Windows10系统步骤
- webstorm配置scss自动编译路径
- 昨天要成为反弹一日游?关键看下午了
- 手机浏览器哪个好用,UC、多御和QQ浏览器对比
- centos系统下安装daemontools详细指南
- INSERT INTO SELECT FROM 的用法
- 【2017级面向对象程序设计】第3、4次成绩及排名
- ipad html文件,ipad HTML文件怎么打开
- 原来我是水瓶座。。。
- pycharm无法关闭的高亮显示原因
- android 打开网页的两种方式.
- python通过Excel表格读取存储数据