一、IoC的基本概念
1、IoC是随着近年来轻量级容器的兴起而逐渐被很多人提到的一个名词,他的全称是Inversion of Control,中文意思为“控制反转”,它还有一个别名叫依赖注入(Dependency Injection),依赖注入的核心理念是:你需要什么我就送给你什么,不需要自己去拿。
2、依赖注入的三种方式:
a、构造方法注入:被注入对象可以通过在其构造方法中声明依赖对象的参数列表,让外部(通常是IoC容器)知道它需要的依赖对象。这种方法的优点是,在对象构造完后,就可以马上使用。缺点在于在依赖对象比较多时,通过反射在构造对象时,对参数的处理比较困难,在维护上和使用上也比较麻烦。
public class UserService {
private UserDao userDao; //UserDao为一个接口
public UserService(UserDao userDao){//构造函数
this.userDao=userDao;
}
}
b、setter方法注入:为当前对象所依赖的对象所对应的属性加入setter方法,就可以通过setter方法将相应的依赖对象设置到被注入的对象中。这个方式在三种方式里面是最好的一种,是目前使用最多的一种方式。
public class UserService {
private UserDao userDao; //UserDao为一个接口
public UserDao getUserDao() {
return userDao;
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}
c、接口注入:这种方法想通过IoC Service Provider为其注入依赖对象,必须要实现某个接口。这个接口提供一个方法,用来为其注入依赖对象,IoC Service Provider通过这些接口来了解为被注入对象注入什么对象。接口注入是现在不甚提倡的一种方法,因为它强制被注入的对象实现不必要的接口。
二、掌管大局的IoC SerVice Provider
1、IoC SerVice Provider的作用:a、对业务对象的构建管理。被注入的对象,不需要知道依赖对象是如何实例化。这个实例化的过程都交给IoC SerVice Provider来完成;b、业务对象间的依赖绑定:将被注入的对象与依赖对象进行绑定。
2、IoC SerVice Provider如何管理对象间的依赖关系,在spring中,Spring Ioc 就是一个IoC SerVice Provider ,主要通过xml配置文件来配置相应的依赖关系。
<bean id="userService" class="....UserService">
<property name="userDao" ref="UserDaoImpl"></property>
</bean>
<bean id="UserDaoImpl" class="...impl.UserDaoImpl"></bean>
这里UserDaoImpl为一个UserDao接口的实现类。
三、Spring的IoC容器之BeanFactory
1、BeanFactory:基础类型的IoC 容器,如果没有特殊指定,默认采用延迟初始化策略(lazy-load)。只有当客户端对象需要访问容器中的某个受管对象时,才对该对象进行实例化以及依赖注入操作,这个容器启动的速度比较快。BeanFactory它是一个bean的工厂,可以完成对象的初始化、依赖注入。下面是一个Spring IoC的基本实现过程:
a、首先定义一个 UserDao 接口:
import java.util.List;
import com.spring.domain.User;
public interface UserDao {
public void addUser(User user);
}
b、定义一个UserDao接口的实现类UserDaoImpl
import com.spring.dao.UserDao;
public class UserDaoImpl implements UserDao {
@Override
public void addUser(User user) {
// TODO Auto-generated method stub
System.out.println("add user success" + user);
}
}
c、定义一个UserService接口
package com.spring.service;
import java.util.List;
import com.spring.domain.User;
public interface UserService {
public void addUser(User user);
}
d、定义一个UserService接口的实现类UserServiceImpl
package com.spring.service.impl;
import java.util.List;
import org.springframework.stereotype.Component;
import com.spring.dao.UserDao;
import com.spring.dao.impl.UserDaoImpl;
import com.spring.domain.User;
import com.spring.service.UserService;
public class UserServiceImpl implements UserService {
private UserDao userDao;
@Override
public void addUser(User user) {
userDao.addUser(user);
}
//set与get方法
public UserDao getUserDao () {
return userDao;
}
public void setUserDao (UserDao userDao) {
this.userDao = userDao;
}
}
e、创建一个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-3.0.xsd
">
<bean id=”userDaoImpl” class=”com.spring.dao.impl.UserDaoImpl” scope=”prototype”></bean>
<bean id=”userServiceImpl” class=”com.spring.service.impl.UserServiceImpl”>
<property name=”userDao” ref=”userDaoImpl”></property>
</bean>
</beans>
f、测试是否注入成功
public class UserServiceTest {
public static void main(String[] args) {
ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
UserService UserService=context.getBean("userServiceImpl",UserService.class);
User user=new User();
UserService.addUser(user);
}
}
这是一种xml配置文件实现方式,在spring2.5以后提供了一中更加方便的注解实现方式。关于注解方式此处不做详解。
2、在BeanFactory中bean 的scope属性
a、singleton:表示一个容器中只存在一个共享实例,所有对该类型bean的依赖都引用这一单一的实例。从容器启动,到它第一次被请求而实例化开始,只要容器不销毁或者退出,该类型bean的单一实例就一直会存活。
b、prototype:声明为prototype的bean,容器在接到该类型对象的请求时候,会每次重新生成一个新的对象实例给对方。每个对象被实例化以后都是自生自灭的。