0
点赞
收藏
分享

微信扫一扫

Spring IoC基础详解

春意暖洋洋 2022-02-14 阅读 85
spring

1.Spring IoC简介

IoC:控制反转(Inversion of Control),在传统开发模式下,都是由开发人员自行创建对象,并管理对象,当使用了Spring框架后,这些事情都交给框架来完成,可以理解“将开发人员对对象的管理权交给了框架”,所以,就出现了“管理权”的移交,则称之为“控制反转”。

DI:依赖注入(Dependency Injection),具体表现为通过框架为对象的属性赋值。

IoC与DI:Spring框架通过DI实现了IoC,DI是实现手段,而IoC是希望实现的目标。

关于Spring IoC,就是要掌握:如何通过Spring框架确实某个类的对象的属性值。

2. 通过SET方式注入属性的值

假设存在User类,其中有String password属性,希望Spring在创建User类的对象时,还能为password属性注入值(赋值),则先准备好User类,例如:

package cn.tedu.spring;

public class User {
	
	private String password;

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		System.out.println("User.setPassword()");
		this.password = password;
	}

}

然后,在Spring的配置文件中进行配置:

<bean id="user" class="cn.tedu.spring.User">
		<!-- property节点:用于配置属性的值 -->
		<!-- name属性:需要配置值的属性名称,实际是set方法对应的名称 -->
		<!-- value属性:需要配置值的属性的值 -->
		<property name="password" value="000111"/>
</bean>

最后,运行时,当获取对象后就可以直接输出属性值,可以看到,该属性已经存在所配置的值。

注意:在<property>属性中,name属性其实是SET方法对应的名称,例如以上配置为name="password",则Spring框架会基于这个配置值,将首字母大写,并在左侧拼上set,得到setPassword,以此为方法名称,结合value属性值,调用了setPassword("000111"),从而使得password属性被赋值。所以,本质是要求name属性的值与类的SET方法是对应的。但是,规范的SET方法名称与Spring组织出SET方法的方式是完全相同的,所以,也可以简单的理解为name属性指的就是属性名称。

2.1注入List集合类型的值

如果需要注入List集合类型的值,例如存在:

// David, Lucy, Tom, Lily, Alex
private List<String> names;

则需要配置为:

<bean id="sampleBean" class="cn.tedu.spring.SampleBean">
		<property name="names">
			<list>
				<value>David</value>
				<value>Lucy</value>
				<value>Tom</value>
				<value>Lily</value>
				<value>Alex</value>
			</list>
		</property>
</bean>

2.2注入数组类型的值

如果需要注入的是数组类型的,例如存在:

// 9, 5, 2, 7
private int[] numbers;

则配置为:

<property name="numbers">
			<array>
				<value>9</value>
				<value>5</value>
				<value>2</value>
				<value>7</value>
			</array>
</property>

2.3注入Set集合类型的值

如果需要注入的是Set集合类型的数据,假如存在:

// Beijing, Shanghai, Guangzhou, Shenzhen
private Set<String> cities;

则需要配置为:

<property name="cities">
			<set>
				<value>Beijing</value>
				<value>Shanghai</value>
				<value>Guangzhou</value>
				<value>Shenzhen</value>
			</set>
</property>

2.4注入Map类型的值

如果需要注入的是Map类型的数据,假如存在:

// {username:root, password:1234, from:Beijing}
private Map<String, String> session;

则需要配置为:

<property name="session">
			<map>
				<entry key="username" value="root"/>
				<entry key="password" value="1234"/>
				<entry key="from" value="Beijing"/>
			</map>
</property>

2.5注入Properties类型的值

如果需要注入的是java.util.Properties类型的数据,假如存在:

// name:Jack, age:25, gender:Male
private Properties profile;

则配置为:

<property name="profile">
			<props>
				<prop key="name">Jack</prop>
				<prop key="age">25</prop>
				<prop key="gender">Male</prop>
			</props>
</property>

当然,Properties类型的数据也可以从.properties类型的文件中读取。可以先在src/main/resources下创建jdbc.properties文件,并在其中进行属性与值的配置:

url=jdbc:mysql://localhost:3306/database_name
driver=com.mysql.jdbc.Driver
username=root
password=root
initialSize=2
maxActive=10

在Spring的配置文件中,需要使用<util:properties>节点来读取这个文件,这个节点与<bean>节点是同一个级别的节点,不要将这个节点写在<bean>的子级。

在配置时:

<!-- util:properties节点:用于读取.properties文件中的配置信息 -->
<!-- location属性:需要读取的文件的位置 -->
<!-- classpath:指的就是resources文件夹 -->
<util:properties id="jdbc" location="classpath:jdbc.properties"></util:properties>

如果这些数据需要被读取到SampleBeanProperties jdbc属性中,先在SampleBean中添加:

// 数据来自于jdbc.properties文件
private Properties jdbc;

并且,在Spring的配置文件中,在配置SampleBean<bean>节点子级添加:

<property name="jdbc" ref="jdbc"/>

小结:如果某个类中的某个属性需要被注入值,首先,需要为这个属性添加匹配的SET方法,在Spring的配置文件中,在该类对应的<bean>节点的子级,添加<property>节点,用于为属性注入值,如果有多个属性都需要注入值,则同一个<bean>节点的子级应该有多个<property>节点,在每个<property>节点中,都通过name属性指定需要注入值的属性名称,假设需要注入值的属性叫password,则应该配置为name="password",如果该属性的值是可以直接写出来的(例如数值、字符串、布尔值),则在<property>节点中添加value属性来配置值,如果该属性的值是另一个Bean对象,则在<property>节点添加ref属性来引用另一个<bean>节点或等同节点的id值,如果该属性的值是集合类型的,则需要在<property>节点的子级添加<list> / <set> / <array> / <map> / <props>进行配置,具体配置方式参考以上笔记中的示例代码。

3. 通过构造方法注入属性的值(用得少)

如果某个类没有无参数的构造方法,并且,希望通过构造方法为某些属性注入值,例如:

package cn.tedu.spring;

// 使用构造方法注入属性的值
// 使用构造方法注入时,并不要求每个属性都有SET/GET方法
public class Person {
	
	// Zoe
	private String username;
	// 26
	private int age;

	public Person(String username, int age) {
		super();
		this.username = username;
		this.age = age;
	}

	@Override
	public String toString() {
		return "Person [username=" + username + ", age=" + age + "]";
	}

}

在Spring的配置文件中,需要配置为:

<bean id="person" class="cn.tedu.spring.Person">
		<!-- constructor-arg节点:配置构造方法的参数 -->
		<!-- index属性:参数的位置,即第几个参数 -->
		<constructor-arg index="0" value="Zoe"/>
		<constructor-arg index="1" value="26"/>
</bean>

所以 ,如果构造方法中有多个参数,在<bean>节点的子级就需要添加多个<constructor-arg>节点进行配置,在<constructor-arg>节点中,index属性表示参数的位置,是从0开始顺序编号,也就是:第1个参数的index值是0,第2个参数的index值是1,以此类推,如果对应的参数值是数值、字符串、布尔值,就通过value属性进行配置,如果对应的参数值是另一个Bean对象,就需要通过ref属性引用到另一个<bean>节点的id值,如果对应的参数值是某种集合类型的,则需要在<constructor-arg>的子级添加集合节点进行配置。

举报

相关推荐

0 条评论