1、概述
IOC和DI的概念:
* IOC -- Inverse of Control,控制反转,将对象的创建权反转给Spring!!
* DI -- Dependency Injection,依赖注入,在Spring框架负责创建Bean对象时,动态的将依赖对象注入到Bean组件中!!
如果UserServiceImpl的实现类中有一个属性,那么使用Spring框架的IOC功能时,可以通过依赖注入把该属性的值传入进来!!
2、构造方法注入
构造方法注入就是利用bean的构造方法完成对bean中属性的赋值
创建Car实体类,提供有参构造方法Car.java
package com.day01.domain;
import java.io.Serializable;
/**
* @ Author :ShaoWei Sun.
* @ Date :Created in 10:34 2018/11/8
*/
public class Car implements Serializable {
private String name;
private Double price;
public Car(String name, Double price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
@Override
public String toString() {
return "Car{" +
"name='" + name + '\'' +
", price=" + price +
'}';
}
}
创建applicationContext2.xml配置Car
<?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">
<!--构造方法注入-->
<bean id="car" class="com.day01.domain.Car">
<constructor-arg name="name" value="保时捷"></constructor-arg>
<constructor-arg name="price" value="2000000.0"></constructor-arg>
</bean>
</beans>
TestIoc.java测试类
package com.day01.test;
import com.day01.dao.AddrDao;
import com.day01.dao.UserDao;
import com.day01.domain.Car;
import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
/**
* @ Author :ShaoWei Sun.
* @ Date :Created in 19:30 2018/11/7
*/
public class TestIoC {
@Test
public void test6(){
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext2.xml");
Car car = (Car) ac.getBean("car");
System.out.println("car = " + car);
}
}
3、set方法注入
set方法注入就是利用bean中属性的set方法对属性赋值。实体类中不用写getXXX方法
创建People.java实体类、提供属性的set方法、不用提供有参构造
package com.day01.domain;
import java.io.Serializable;
/**
* @ Author :ShaoWei Sun.
* @ Date :Created in 10:46 2018/11/8
*/
public class People implements Serializable {
private String name;//提供对应的set方法
private String address;
private Car car;//对象属性
public void setName(String name) {
this.name = name;
}
// public String getName(){
// return this.name;
// }
public void setAddress(String address) {
this.address = address;
}
public void setCar(Car car) {
this.car = car;
}
@Override
public String toString() {
return "People{" +
"name='" + name + '\'' +
", address='" + address + '\'' +
", car=" + car +
'}';
}
}
applicationContext2.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">
<!--构造方法注入-->
<bean id="car" class="com.day01.domain.Car">
<constructor-arg name="name" value="保时捷"></constructor-arg>
<constructor-arg name="price" value="2000000.0"></constructor-arg>
</bean>
<!--set方法注入-->
<bean id="people" class="com.day01.domain.People">
<property name="name" value="小刚"></property>
<property name="address" value="上海"></property>
<property name="car" ref="car"></property>
</bean>
</beans>
TestIoc.java测试类
package com.day01.test;
import com.day01.dao.AddrDao;
import com.day01.dao.UserDao;
import com.day01.domain.Car;
import com.day01.domain.People;
import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import java.time.Period;
/**
* @ Author :ShaoWei Sun.
* @ Date :Created in 19:30 2018/11/7
*/
public class TestIoC {
@Test
public void test7(){
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext2.xml");
People people = (People) ac.getBean("people");
System.out.println("people = " + people);
}
}
4、set方法注入其它写法
1)、p命名空间的写法
语法:p:属性名=”值“
p:对象属性名-ref = "bean的id"
applicationContext2.xml
约束:加这行:xmlns:p="http://www.springframework.org/schema/p"
<?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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--构造方法注入-->
<bean id="car" class="com.day01.domain.Car">
<constructor-arg name="name" value="保时捷"></constructor-arg>
<constructor-arg name="price" value="2000000.0"></constructor-arg>
</bean>
<!--set方法注入-->
<!--<bean id="people" class="com.day01.domain.People">-->
<!--<property name="name" value="小刚"></property>-->
<!--<property name="address" value="上海"></property>-->
<!--<property name="car" ref="car"></property>-->
<!--</bean>-->
<!--p命名空间写法-->
<bean id="people" class="com.day01.domain.People" p:name="小刚" p:address="北京" p:car-ref="car">
</bean>
</beans>
@Test
public void test7(){
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext2.xml");
People people = (People) ac.getBean("people");
System.out.println("people = " + people);
}
2)、SpEL的写法
SpEL:Spring Expression Language
语法:
注入字符串:#{‘字符串’}
注入数字:#{数字}
注入其它对象:#{对象id}
applicationContext2.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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--构造方法注入-->
<bean id="car" class="com.day01.domain.Car">
<constructor-arg name="name" value="保时捷"></constructor-arg>
<constructor-arg name="price" value="2000000.0"></constructor-arg>
</bean>
<!--set方法注入-->
<!--<bean id="people" class="com.day01.domain.People">-->
<!--<property name="name" value="小刚"></property>-->
<!--<property name="address" value="上海"></property>-->
<!--<property name="car" ref="car"></property>-->
<!--</bean>-->
<!--p命名空间写法-->
<!--<bean id="people" class="com.day01.domain.People" p:name="小刚" p:address="北京" p:car-ref="car">-->
<!--</bean>-->
<!--SpEL方法注入-->
<bean id="people" class="com.day01.domain.People">
<property name="name" value="#{'小刚'}"></property>
<property name="address" value="#{'北京'}"></property>
<property name="car" value="#{car}"></property>
</bean>
</beans>
测试
@Test
public void test7(){
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext2.xml");
People people = (People) ac.getBean("people");
System.out.println("people = " + people);
}
《》《》《》《》《》
5、数组或List注入(重点)
当bean中的属性是List或数组类型。那么该怎么给List或数组注入值呢?数组和list注入的写法是一样的。
新建bean类、InfoBean.java
package com.day01.domain;
import java.util.List;
/**
* @ Author :ShaoWei Sun.
* @ Date :Created in 11:18 2018/11/8
*/
public class InfoBean {
private List<String> list;
public void setList(List<String> list){
this.list = list;
}
@Override
public String toString() {
return "InfoBean{" +
"list=" + list +
'}';
}
}
applicationContext2.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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--构造方法注入-->
<bean id="car" class="com.day01.domain.Car">
<constructor-arg name="name" value="保时捷"></constructor-arg>
<constructor-arg name="price" value="2000000.0"></constructor-arg>
</bean>
<!--set方法注入-->
<!--<bean id="people" class="com.day01.domain.People">-->
<!--<property name="name" value="小刚"></property>-->
<!--<property name="address" value="上海"></property>-->
<!--<property name="car" ref="car"></property>-->
<!--</bean>-->
<!--p命名空间写法-->
<!--<bean id="people" class="com.day01.domain.People" p:name="小刚" p:address="北京" p:car-ref="car">-->
<!--</bean>-->
<!--SpEL方法注入-->
<bean id="people" class="com.day01.domain.People">
<property name="name" value="#{'小刚'}"></property>
<property name="address" value="#{'北京'}"></property>
<property name="car" value="#{car}"></property>
</bean>
<!--list注入-->
<bean id="listId" class="com.day01.domain.InfoBean">
<property name="list">
<list>
<value>大罗</value>
<value>小罗</value>
<value>小小罗</value>
</list>
</property>
</bean>
</beans>
测试类
TestIoc.java
package com.day01.test;
import com.day01.dao.AddrDao;
import com.day01.dao.UserDao;
import com.day01.domain.Car;
import com.day01.domain.InfoBean;
import com.day01.domain.People;
import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import javax.sound.sampled.Line;
import java.time.Period;
/**
* @ Author :ShaoWei Sun.
* @ Date :Created in 19:30 2018/11/7
*/
public class TestIoC {
@Test
public void test8(){
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext2.xml");
InfoBean infoBean = (InfoBean) ac.getBean("listId");
System.out.println("infoBean = " + infoBean);
}
}
6、Set集合的注入
有的时候,bean中的属性是Set类型。那么该怎么给Set类型的属性注入值呢?
修改InfoBean、在其中添加一个Set类型的属性并提供set方法
实体类:InfoBean.java
package com.day01.domain;
import java.util.List;
import java.util.Set;
/**
* @ Author :ShaoWei Sun.
* @ Date :Created in 11:18 2018/11/8
*/
public class InfoBean {
private List<String> list;
private Set<String> set;
public void setList(List<String> list){
this.list = list;
}
public void setSet(Set<String> set) {
this.set = set;
}
@Override
public String toString() {
return "CollectionBean{" +
"list=" + list +
", set=" + set +
'}';
}
}
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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--构造方法注入-->
<bean id="car" class="com.day01.domain.Car">
<constructor-arg name="name" value="保时捷"></constructor-arg>
<constructor-arg name="price" value="2000000.0"></constructor-arg>
</bean>
<!--set方法注入-->
<!--<bean id="people" class="com.day01.domain.People">-->
<!--<property name="name" value="小刚"></property>-->
<!--<property name="address" value="上海"></property>-->
<!--<property name="car" ref="car"></property>-->
<!--</bean>-->
<!--p命名空间写法-->
<!--<bean id="people" class="com.day01.domain.People" p:name="小刚" p:address="北京" p:car-ref="car">-->
<!--</bean>-->
<!--SpEL方法注入-->
<bean id="people" class="com.day01.domain.People">
<property name="name" value="#{'小刚'}"></property>
<property name="address" value="#{'北京'}"></property>
<property name="car" value="#{car}"></property>
</bean>
<bean id="listId" class="com.day01.domain.InfoBean">
<!--list注入-->
<property name="list">
<list>
<value>大罗</value>
<value>小罗</value>
<value>小小罗</value>
</list>
</property>
<!--set集合注入-->
<property name="set">
<set>
<value>鸠摩智</value>
<value>天山童姥</value>
<value>无崖子</value>
</set>
</property>
</bean>
</beans>
测试
@Test
public void test8(){
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext2.xml");
InfoBean infoBean = (InfoBean) ac.getBean("listId");
System.out.println("infoBean = " + infoBean);
}
7、Map集合的注入
有的时候,bean中的属性是Map类型。那么该怎么给Map类型的属性注入值呢?
修改InfoBean,在其中添加一个Map类型的属性并提供set方法:
语法:
<entry>表示map中的一个键值对;
<entry>的key表示键,value表示值;
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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--构造方法注入-->
<bean id="car" class="com.day01.domain.Car">
<constructor-arg name="name" value="保时捷"></constructor-arg>
<constructor-arg name="price" value="2000000.0"></constructor-arg>
</bean>
<!--set方法注入-->
<!--<bean id="people" class="com.day01.domain.People">-->
<!--<property name="name" value="小刚"></property>-->
<!--<property name="address" value="上海"></property>-->
<!--<property name="car" ref="car"></property>-->
<!--</bean>-->
<!--p命名空间写法-->
<!--<bean id="people" class="com.day01.domain.People" p:name="小刚" p:address="北京" p:car-ref="car">-->
<!--</bean>-->
<!--SpEL方法注入-->
<bean id="people" class="com.day01.domain.People">
<property name="name" value="#{'小刚'}"></property>
<property name="address" value="#{'北京'}"></property>
<property name="car" value="#{car}"></property>
</bean>
<bean id="listId" class="com.day01.domain.InfoBean">
<!--list注入-->
<property name="list">
<list>
<value>大罗</value>
<value>小罗</value>
</list>
</property>
<!--set集合注入-->
<property name="set">
<set>
<value>鸠摩智</value>
<value>无崖子</value>
</set>
</property>
<!--map集合注入-->
<property name="map">
<map>
<entry key="id" value="1"></entry>
<entry key="username" value="张三"></entry>
</map>
</property>
</bean>
</beans>
InfoBean.java实体类
package com.day01.domain;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @ Author :ShaoWei Sun.
* @ Date :Created in 11:18 2018/11/8
*/
public class InfoBean {
private List<String> list;
private Set<String> set;
private Map<String,String> map;
public void setList(List<String> list){
this.list = list;
}
public void setSet(Set<String> set) {
this.set = set;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
@Override
public String toString() {
return "CollectionBean{" +
"list=" + list +
", set=" + set +
", map=" + map +
'}';
}
}
测试
@Test
public void test8(){
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext2.xml");
InfoBean infoBean = (InfoBean) ac.getBean("listId");
System.out.println("infoBean = " + infoBean);
}
8、Properties的注入(重点)
有的时候,bean中的属性是Properties类型。那么该怎么给Properties类型的属性注入值呢?
Properties语法:
<prop>:表示一个键值对;
<prop>中的key表示键,在<prop></prop>中写的是值;
修改InfiBean.java,在其中添加一个Properties类型的属性并提供set方法:
package com.day01.domain;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
/**
* @ Author :ShaoWei Sun.
* @ Date :Created in 11:18 2018/11/8
*/
public class InfoBean {
private List<String> list;
private Set<String> set;
private Map<String,String> map;
private Properties properties;
public void setList(List<String> list){
this.list = list;
}
public void setSet(Set<String> set) {
this.set = set;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
@Override
public String toString() {
return "CollectionBean{" +
"list=" + list +
", set=" + set +
", map=" + map +
", properties=" + properties +
'}';
}
}
applicationContext2.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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--构造方法注入-->
<bean id="car" class="com.day01.domain.Car">
<constructor-arg name="name" value="保时捷"></constructor-arg>
<constructor-arg name="price" value="2000000.0"></constructor-arg>
</bean>
<!--set方法注入-->
<!--<bean id="people" class="com.day01.domain.People">-->
<!--<property name="name" value="小刚"></property>-->
<!--<property name="address" value="上海"></property>-->
<!--<property name="car" ref="car"></property>-->
<!--</bean>-->
<!--p命名空间写法-->
<!--<bean id="people" class="com.day01.domain.People" p:name="小刚" p:address="北京" p:car-ref="car">-->
<!--</bean>-->
<!--SpEL方法注入-->
<bean id="people" class="com.day01.domain.People">
<property name="name" value="#{'小刚'}"></property>
<property name="address" value="#{'北京'}"></property>
<property name="car" value="#{car}"></property>
</bean>
<bean id="listId" class="com.day01.domain.InfoBean">
<!--list注入-->
<property name="list">
<list>
<value>大罗</value>
<value>小罗</value>
</list>
</property>
<!--set集合注入-->
<property name="set">
<set>
<value>鸠摩智</value>
<value>无崖子</value>
</set>
</property>
<!--map集合注入-->
<property name="map">
<map>
<entry key="id" value="1"></entry>
<entry key="username" value="张三"></entry>
</map>
</property>
<!--preperties注入-->
<property name="properties">
<props>
<prop key="id">2</prop>
<prop key="name">小明</prop>
</props>
</property>
</bean>
</beans>
测试
@Test
public void test8(){
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext2.xml");
InfoBean infoBean = (InfoBean) ac.getBean("listId");
System.out.println("infoBean = " + infoBean);
}
9、配置文件的分离
方式一:
在整个工程中有applicationContext.xml和applicationContext2.xml两个配置文件。可以把aplicationContext.xml看成一个总的配置文件,在其中包含applicaitonContext2.xml文件。修改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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userDao" class="com.day01.dao.impl.UserDaoImpl" init-method="init" destroy-method="destroy"></bean>
<bean id="factory" class="com.day01.factory.Factory"></bean>
<bean id="deptDao" factory-bean="factory" factory-method="create"></bean>
<import resource="applicationContext2.xml"/>
</beans>
此时,创建IOC容器时,只需要加载applicationContext.xml即可,因为在applicationContext.xml引入了applicationContext2.xml文件,所以,applicationContext2.xml也会加载
方式二:
@Test
public void test4(){
//创建Spring工厂(创建IOC容器)
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml","applicationContext2.xml");
DeptDao deptDao = (DeptDao) ac.getBean("deptDao");
deptDao.save();
}