Spring IoC依赖注入
控制反转(Inversion of Control,IoC),也被称为依赖注入(Dependency Injection,DI),是面向对象编程中的一种设计理念,用来降低程序代码之间的耦合度。在使用Spring IoC之前呢,需要先配置Spring,导入相关jar包,至于哪些包这里就不多说了。
IoC依赖注入:
使用<bean>元素来定义Bean的实例(也可成为组件)。这个元素有两个常用属性:一个是id,表示定义的Bean
实例的名称,注意,id并不是必须的哦^_^,后面会讲到;另一个是class,表示定义的Bean实例的类型。
经验:使用<bean>元素定义一个组件时,通常需要使用id属性为其指定一个用来访问的唯一的名称。
如果想为Bean指定更多的别名,可以通过name属性指定,名字之间使用逗号、分号或空格进行分隔。
IoC依赖注入方式一: 设值注入
User类
package com.entity;
public class User {
//用户的姓名
private String name;
//用户的年龄
private int age;
//用户的类型
private Type type;
//提供setter方法
public void setName(String name) {
this.name = name;
}
//提供setter方法
public void setAge(int age) {
this.age = age;
}
//提供setter方法
public void setType(){
this.type=type;
}
}
Type类
package com.entity;
public class Type {
//用户的类型名称
private String typeName;
//提供setter方法
public void setTypeName(String typeName) {
this.typeName = typeName;
}
}
applicationContext.xml代码:
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
">
<bean id="type" class="com.entity.Type">
<property name="typeName" value="普通用户"/>
</bean>
<bean id="user" class="com.entity.User">
<property name="name" value="张三"/>
<property name="age" value="20"/>
<property name="type" ref="type"/>
</bean>
</beans>
这里id属性表示user这个实例的名称
这里class属性表示引用com.entity.User这个类
<property>元素用来配置user这个实例的属性
name表示属性名称,注意name的值和setter方法名有关,如果setter的方法名为setName1,那么这里name的值就应该是name1,
所以在提供setter访问器命名时,一定要注意遵循JavaBean的命名规范。
value表示给属性设置的值。
当引用的是一个定义好的bean的时候,则需要用ref指定引用
IoC依赖注入方式二: 构造注入
User类
package com.entity;
public class User {
//用户的姓名
private String name;
//用户的年龄
private int age;
//用户的类型
private Type type;
//提供有参构造方法
public User(String name,int age,Type type){
this.name=name;this.age=age;
this.type=type;
}
}
Type类
package com.entity;
public class Type {
//用户的类型名称
private String typeName;
//提供有参构造函数
public Type(String typeName){
this.typeName=typeName;
}
}
applicationContext.xml代码:
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
">
<bean id="type" class="com.entity.Type">
<constructor-arg index="0" type="java.lang.String" name="typeName" value="张三"/>
</bean>
<bean id="user" class="com.entity.User">
<constructor-arg index="0" type="java.lang.String" name="name" value="张三"/>
<constructor-arg index="1" type="java.lang.Integer" name="age" value="22"/>
<constructor-arg index="2" type="java.lang.String" name="type" value="22">
<ref bean="type"/>
</constructor-arg>
</bean>
</beans>
这里id和class同方式一
<constructor-arg>元素用于配置user实例的构造函数
这里的index属性指定该参数的位置索引,位置从0开始;还提供了type属性用来指定参数的类型,避免字符串和基本数据类型的混淆。index和type属性可省略。
<ref>同方式一,引用定义好的bean
IoC依赖注入方式三: p命名空间注入
User类
package com.entity;
public class User {
//用户的姓名
private String name;
//用户的年龄
private int age;
//用户的类型
private Type type;
//提供setter方法
public void setName(String name) {
this.name = name;
}
//提供setter方法
public void setAge(int age) {
this.age = age;
}
//提供setter方法
public void setType(){
this.type=type;
}
}
Type类
package com.entity;
public class Type {
//用户的类型名称
private String typeName;
//提供setter方法
public void setTypeName(String typeName) {
this.typeName = typeName;
}
}
applicationContext.xml代码:
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
">
<bean id="type" class="com.entity.Type" p:typeName="普通用户"/>
<bean id="user" class="com.entity.User" p:name="张三" p:age="20" p:type-ref="type"/>
</beans>
使用P命名空间注入一定要引入
xmlns:p="http://www.springframework.org/schema/p"
这里id和class同方式一
对于直接量(基本数据类型、字符串)属性的语法:
p:属性名=“属性值”
对于引用Bean的属性的语法
p:属性名-ref=“Bean的id”
当然注入方式还有很多,这里是常见的三种注入方式。
下面介绍一下如何注入不同数据类型
对于直接量,使用<value>子元素进行注入
<bean id="user" class="com.entity.User">
<property name="name">
<value>张三</value>
</property>
</bean>
②对于特殊字符(&、<、>、"、')
方法一:使用<![CDATA[ ]]>进行标记
<bean id="user" class="com.entity.User">
<property name="name">
<value>张<![CDATA[&]]>三</value>
</property>
</bean>
方法二:使用XML的预定义的实体引用
符号实体 引用
< <
> >
& &
' '
" "
严格的来讲,在XML中仅有字符“<”和“&”是非法的,其他3个字符是合法的,但是把它们替换为实体引用是个好习惯。
引用其他Bean组件
①<ref bean="type"> 上述示例演示过
②<ref local="type"> 用法和①一样
两种方式的区别:Spring的配置文件是可以拆分成多个的,使用local属性只能在同一个配置文件中检索Bean的id,而使用bean属性可以
在其他配置文件中检索id。
使用内部Bean
如果一个Bean组件仅在一处需要使用,可以把它定义为内部Bean
<bean id="user" class="com.entity.User">
<property name="type">
<!--定义type对象-->
<bean class="com.entity.Type"/>
</property>
</bean>
注入泛型类型的属性
<bean id="user" class="com.entity.User">
<property name="hobbies">
<list>
<!--定义list或数组中的元素-->
<value>足球</value>
<value>篮球</value>
</list>
</property>
</bean>
set类型的属性
<bean id="user" class="com.entity.User">
<property name="hobbies">
<set>
<!--定义set中的元素-->
<value>足球</value>
<value>篮球</value>
</set>
</property>
</bean>
Map类型的属性
<bean id="user" class="com.entity.User">
<property name="hobbies">
<map>
<!--定义Map中的键值对-->
<entry>
<key><value>football</value></key>
<value>足球</value>
</entry>
<entry>
<key><value>basketball</value></key>
<value>篮球</value>
</entry>
</map>
</property>
</bean>
Properties类型的属性
<bean id="user" class="com.entity.User">
<property name="hobbies">
<props>
<!--定义Properties中的键值对-->
<prop key="football">足球</prop>
<prop key="basketball">篮球</prop>
</props>
</property>
</bean>
注入null和空字符串值
<!--注入空字符串值-->
<bean id="user" class="com.entity.User">
<property name="email">
<value></value>
</property>
</bean>
<!--注入null值-->
<bean id="user" class="com.entity.User">
<property name="email">
<null/>
</property>
</bean>