一:控制反转(IOC):就是实例化对象的控制权发生了转变,以前是我们自己new,现在交给spring这个工厂去实例化,如果我现在要用对象,就直接向spring这个工厂索取就可以了。
两种方式:set方式和构造器方式。
二:构造器方式注入
构造器参数类型的匹配
要求构造参数非常明确,即参数列表不会有同类型的参数。
以水果service层为例:
service层需要持有Dao层对象,才能调用Dao层方法。
//Dao层接口:
package com.spring.chapter4.dao;
public interface FruitDao {
public void create();
}
//Dao层实现类:
package com.spring.chapter4.dao.impl;
import com.spring.chapter4.dao.FruitDao;
public class FruitDaoImpl implements FruitDao {
public void create() {
System.out.println("Dao层方法create被调用");
}
}
//服务层接口:
package com.spring.chapter4.service;
public interface FruitService {
public void create();
}
//服务层实现类:
package com.spring.chapter4.service.impl;
import com.spring.chapter4.dao.FruitDao;
import com.spring.chapter4.service.FruitService;
public class FruitServiceImpl implements FruitService {
private FruitDao fruitDao;
public FruitServiceImpl(FruitDao fruitDao) {
super();
this.fruitDao = fruitDao;
}
public void create() {
fruitDao.create();
}
}
这里和我们前面set注入的不同,提供的时我们熟悉的构造方法。
//配置文件(chapter4.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-2.5.xsd">
<bean id="fruitDao" class="com.spring.chapter4.dao.impl.FruitDaoImpl"/>
<bean id="fruitService" class="com.spring.chapter4.service.impl.FruitServiceImpl">
<constructor-arg type="com.spring.chapter4.dao.FruitDao" ref="fruitDao"/>
</bean>
</beans>
//测试类
package com.spring.chapter4.service.impl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.spring.chapter4.service.FruitService;
public class Test {
public static void main(String[] args) {
ApplicationContext act = new ClassPathXmlApplicationContext(
"chapter4.xml");
FruitService fruitService = (FruitService) act.getBean("fruitService");
fruitService.create();
}
}
三:构造参数索引:
可以解决参数同类型问题,并且配置时不用去维护参数顺序的问题,如果使用构造器注入(推荐使用这种方式),或者将前两者结合起来一起使用。
例如:给服务层添加两个属性
package com.spring.chapter4.service.impl;
import com.spring.chapter4.dao.FruitDao;
import com.spring.chapter4.service.FruitService;
public class FruitServiceImpl implements FruitService {
private FruitDao fruitDao;
private String name;
private String address;
public FruitServiceImpl(FruitDao fruitDao) {
super();
this.fruitDao = fruitDao;
}
public FruitServiceImpl(FruitDao fruitDao, String name, String address) {
super();
this.fruitDao = fruitDao;
this.name = name;
this.address = address;
}
public void create() {
fruitDao.create();
}
public FruitDao getFruitDao() {
return fruitDao;
}
public void setFruitDao(FruitDao fruitDao) {
this.fruitDao = fruitDao;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
//配置文件(chapter4.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-2.5.xsd">
<bean id="fruitDao" class="com.spring.chapter4.dao.impl.FruitDaoImpl"/>
<bean id="fruitService" class="com.spring.chapter4.service.impl.FruitServiceImpl">
<constructor-arg index="0" ref="fruitDao" />
<constructor-arg index="1" value="桔子" />
<constructor-arg index="2" value="中国" />
</bean>
</beans>
//测试类:
package com.spring.chapter4.service.impl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.spring.chapter4.service.FruitService;
public class Test {
public static void main(String[] args) {
ApplicationContext act = new ClassPathXmlApplicationContext("chapter4.xml");
FruitService fruitService = (FruitService) act.getBean("fruitService");
fruitService.create();
System.out.println(((FruitServiceImpl)fruitService).getName());
System.out.println(((FruitServiceImpl)fruitService).getAddress());
}
}
四:集合注入
Set集合、list集合、properties集合、map集合
package com.spring.chapter4.service.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class CollectionService {
private Set<String> sets = new HashSet<String>();
private List<String> lists = new ArrayList<String>();
private Properties properties = new Properties();
private Map<String,String> maps = new HashMap<String, String>();
public Set<String> getSets() {
return sets;
}
public void setSets(Set<String> sets) {
this.sets = sets;
}
public List<String> getLists() {
return lists;
}
public void setLists(List<String> lists) {
this.lists = lists;
}
public Properties getProperties() {
return properties;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
public Map<String, String> getMaps() {
return maps;
}
public void setMaps(Map<String, String> maps) {
this.maps = maps;
}
}
//配置文件(collection.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-2.5.xsd">
<bean id="collectionService" class="com.spring.chapter4.service.impl.CollectionService">
<property name="sets">
<set>
<value>set1</value>
<value>set2</value>
<value>set3</value>
</set>
</property>
<property name="lists">
<list>
<value>list1</value>
<value>list2</value>
<value>list3</value>
</list>
</property>
<property name="properties">
<props>
<prop key="key1">properties1</prop>
<prop key="key2">properties2</prop>
<prop key="key3">properties3</prop>
</props>
</property>
<property name="maps">
<map>
<entry key="key1" value="maps1"/>
<entry key="key2" value="maps2"/>
<entry key="key3" value="maps3"/>
</map>
</property>
</bean>
</beans>
//测试类:
package com.spring.chapter4.service.impl;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestDemo {
public static void main(String[] args) {
ApplicationContext act = new ClassPathXmlApplicationContext("collection.xml");
CollectionService collectionService = (CollectionService) act.getBean("collectionService");
Set<String> set = collectionService.getSets();
for(String s:set){
System.out.println(s);
}
List<String> lists = collectionService.getLists();
for (String s : lists) {
System.out.println(s);
}
Properties properties = collectionService.getProperties();
for (Object key : properties.keySet()) {
System.out.println(key + ":" + properties.getProperty((String) key));
}
Map<String, String> mpas = collectionService.getMaps();
for(String key : mpas.keySet()){
System.out.println(key + ":" + mpas.get((String) key));
}
}
}
五:自动装配
(1). byName
<?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-2.5.xsd">
<bean id="fruitDao" class="dao.impl.FruitDaoImpl" />
<bean id="fruitService" class="service.impl.FruitServiceImpl"
autowire="byName" />
</beans>
需要注意的地方: <bean id="fruitDao" class="dao.impl.FruitDaoImpl" />
id="fruitDao"一定要和服务层的属性名称对应,即FruitDaoImpl类里面一定要有一个名称为fruitDao的属性.
(2). byType
<?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-2.5.xsd">
<bean id="fruitDao" class="dao.impl.FruitDaoImpl" />
<bean id="fruitService" class="service.impl.FruitServiceImpl"
autowire="byType" />
</beans>
需要保证FruitServiceImpl类中有一个属性类型是FruitDao类型即可.
尽量不要用自动装配的特性,因为会产生二异性,特别是按类型装配