Spring框架的核心功能之一就是通过依赖注入的方式来管理Bean之间的依赖关系。
依赖注入
特点:增加类重用的可能性
假设你有一个包含文本编辑器组件的应用程序,并且你想要提供拼写检查。标准代码看起来是这样的:
public class TextEditor {
private SpellChecker spellChecker;
public TextEditor() {
spellChecker = new SpellChecker();
}
}
在这里我们所做的就是创建一个 TextEditor 和 SpellChecker 之间的依赖关系。而在控制反转IoC的场景中,我们会这样做:
public class TextEditor {
private SpellChecker spellChecker;
public TextEditor(SpellChecker spellChecker) {
this.spellChecker = spellChecker;
}
}
在这里,TextEditor 不应该担心 SpellChecker 的实现。SpellChecker 将会独立实现,并且在 TextEditor 实例化的时候将提供给 TextEditor,整个过程是由 Spring 框架的控制。
基于构造函数的依赖注入
例:
构造User类
public class User {
private Integer uid;
private String username;
private Integer age;
public User(Integer uid,String username){
super();
this.uid = uid;
this.username = username;
System.out.println("uid:"+uid+",usernaem:"+username);
}
public User(String username,Integer age){
super();
this.username = username;
this.age = age;
System.out.println("username:"+username+",age:"+age);
}
}
spring-config.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 构造方法注入
* <constructor-arg> 用于配置构造方法一个参数argument
name :参数的名称
value:设置普通数据
ref:引用数据,一般是另一个bean id值
index :参数的索引号,从0开始 。如果只有索引,匹配到了多个构造方法时,默认使用第一个。
type :确定参数类型
例如:使用名称name
<constructor-arg name="username" value="jack"></constructor-arg>
<constructor-arg name="age" value="18"></constructor-arg>
例如2:【类型type 和 索引 index】
<constructor-arg index="0" type="java.lang.String" value="1"></constructor-arg>
<constructor-arg index="1" type="java.lang.Integer" value="2"></constructor-arg>
-->
<bean id="user1" class="User" lazy-init="true">
<constructor-arg type="java.lang.Integer" value="1"></constructor-arg>
<constructor-arg type="java.lang.String" value="李四"></constructor-arg>
</bean>
<bean id="user2" class="User" lazy-init="true">
<constructor-arg name="uid" value="1"></constructor-arg>
<constructor-arg name="username" value="张三"></constructor-arg>
</bean>
<bean id="user3" class="User" lazy-init="true">
<constructor-arg index="0" value="1"></constructor-arg>
<constructor-arg index="1" value="5"></constructor-arg>
</bean>
</beans>
测试类调用spring-config.xml
public class SpringTest {
public static void main(String[] args){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml");
User user = applicationContext.getBean("user1",User.class);
}
}
运行
uid:1,usernaem:李四
Process finished with exit code 0
例2:
public class SpringTest {
public static void main(String[] args){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml");
User user = applicationContext.getBean("user2",User.class);
}
}
uid:1,usernaem:张三
Process finished with exit code 0
例3:
public class SpringTest {
public static void main(String[] args){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml");
User user = applicationContext.getBean("user3",User.class);
}
}
uid:1,usernaem:5
基于设值函数的依赖注入(setter方法)
配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- setter方法注入
* 普通数据
<property name="" value="值">
等效
<property name="">
<value>值
* 引用数据
<property name="" ref="另一个bean">
等效
<property name="">
<ref bean="另一个bean"/>
-->
<bean id="person" class="com.demo.dao.Person">
<property name="name" value="张三"></property>
<property name="age" value="25"></property>
<property name="homeAddr" ref="homeAddr"></property>
<property name="companyAddr" ref="companyAddr"></property>
</bean>
<bean id="homeAddr" class="com.demo.dao.Address">
<property name="addr" value="福建"></property>
<property name="tel" value="13205068888"></property>
</bean>
<bean id="companyAddr" class="com.demo.dao.Address">
<property name="addr" value="厦门"></property>
<property name="tel" value="13205068888"></property>
</bean>
</beans>
Person
package com.demo.dao;
public class Person {
private String name;
private Integer age;
private Address homeAddr;
private Address companyAddr;
get set.....
}
Address
package com.demo.dao;
public class Address {
private String addr;
private String tel;
public String getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
@Override
public String toString() {
return "Address{" +
"addr='" + addr + '\'' +
", tel='" + tel + '\'' +
'}';
}
}
测试类
public class SpringTest {
public static void main(String[] args){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml");
Person person = applicationContext.getBean("person",Person.class);
System.out.println(person.getName());
System.out.println(person.getAge());
System.out.println(person.getHomeAddr());
System.out.println(person.getCompanyAddr());
}
}
运行
张三
25
Address{addr='福建', tel='13205068888'}
Address{addr='厦门', tel='13205068888'}
注入内部 Beans
配置格式
<bean id="outerBean" class="...">
<property name="target">
<bean id="innerBean" class="..."/>
</property>
</bean>
配置
<bean id="person" class="com.demo.dao.Person">
<property name="name" value="张三"></property>
<property name="age" value="25"></property>
<property name="homeAddr" >
<bean id="homeAddr" class="com.demo.dao.Address">
<property name="addr" value="福建"></property>
<property name="tel" value="13205068888"></property>
</bean>
</property>
<property name="companyAddr">
<bean id="companyAddr" class="com.demo.dao.Address">
<property name="addr" value="厦门"></property>
<property name="tel" value="13205068888"></property>
</bean>
</property>
</bean>
测试类
public class SpringTest {
public static void main(String[] args){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml");
Person person = applicationContext.getBean("person",Person.class);
System.out.println(person.getName());
System.out.println(person.getAge());
System.out.println(person.getHomeAddr());
System.out.println(person.getCompanyAddr());
}
}
运行结果
张三
25
Address{addr='福建', tel='13205068888'}
Address{addr='厦门', tel='13205068888'}
注入集合
public class JavaCollection {
List addressList;
Set addressSet;
Map addressMap;
Properties addressProp;
get set ...
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!-- Definition for javaCollection -->
<bean id="javaCollection" class="com.tutorialspoint.JavaCollection">
<!-- results in a setAddressList(java.util.List) call -->
<property name="addressList">
<list>
<value>INDIA</value>
<value>Pakistan</value>
<value>USA</value>
<value>USA</value>
</list>
</property>
<!-- results in a setAddressSet(java.util.Set) call -->
<property name="addressSet">
<set>
<value>INDIA</value>
<value>Pakistan</value>
<value>USA</value>
<value>USA</value>
</set>
</property>
<!-- results in a setAddressMap(java.util.Map) call -->
<property name="addressMap">
<map>
<entry key="1" value="INDIA"/>
<entry key="2" value="Pakistan"/>
<entry key="3" value="USA"/>
<entry key="4" value="USA"/>
</map>
</property>
<!-- results in a setAddressProp(java.util.Properties) call -->
<property name="addressProp">
<props>
<prop key="one">INDIA</prop>
<prop key="two">Pakistan</prop>
<prop key="three">USA</prop>
<prop key="four">USA</prop>
</props>
</property>
</bean>
</beans>
package com.tutorialspoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context =
new ClassPathXmlApplicationContext("Beans.xml");
JavaCollection jc=(JavaCollection)context.getBean("javaCollection");
jc.getAddressList();
jc.getAddressSet();
jc.getAddressMap();
jc.getAddressProp();
}
}
运行
List Elements :[INDIA, Pakistan, USA, USA]
Set Elements :[INDIA, Pakistan, USA]
Map Elements :{1=INDIA, 2=Pakistan, 3=USA, 4=USA}
Property Elements :{two=Pakistan, one=INDIA, three=USA, four=USA}