IoC
IoC(控制反转),是指在程序的设计中,实例不再由调用者来创建,而是由Spring容器来创建。
Spring容器会负责控制程序之间的关系,而不是由程序代码直接控制,这样控制权由应用代码转移到了外部容器,控制权发生了反转,也就是Spring的IoC(控制反转)思想。
Spring为我们提供了两种IoC容器,分别是BeanFactory(用的不多)和ApplicationContext。
需求:提供UserService接口和实现类,获得实现类的实例。
之前的做法,直接new一个对象即可。
学习了spring之后,将由Spring创建对象实例。这个过程叫IoC(Inverse of Control),控制反转。之后需要实例对象时,从spring工厂(容器)中获得,需要将实现类的全限定名称配置到xml文件中。
创建一个接口
public interface UserService {
void addUser();
}
创建一个实现类
public class UserServiceImpl implements UserService {
@Override
public void addUser() {
System.out.println("a_ico add user");
}
}
配置文件,位置和名称任意。一般在classpath下(src)。名称,一般为applicationContext.xml。添加schema约束。约束文件位置:spring-framework-3.2.0.RELEASE\docs\spring-framework-reference\html\xsd-config.html
<?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">
<!-- 配置service
<bean> 配置需要创建的对象
id :用于之后从spring容器获得实例时使用的
class :需要创建实例的全限定类名
-->
<bean id="userServiceId" class="com.itheima.a_ioc.UserServiceImpl"></bean>
</beans>
测试类
public class TestIoC {
@Test
public void demo01(){
//之前的做法
//UserService userService=new UserServiceImpl();
//userService.addUser();
//1 获得容器
String xmlPath="/spring/src/applicationContext.xml";
ApplicationContext applicationContext=new ClassPathXmlApplicationContext(xmlPath);
//2.获得对象
UserService userService = (UserService) applicationContext.getBean("userServiceId");
userService.addUser();
}
}
DI
DI,Dependency Injection,依赖注入。它与控制反转的含义相同,只不过这两个称呼是从两个角度描述的同一个概念。可以这样理解DI的概念:如果一个对象A需要使用另一个对象B才能实现某个功能,这时就可以说A对象依赖于B对象,而Spring容器在创建A对象时,会自动将A对象需要的B对象注入到A对象中,此过程就是依赖注入。依赖注入的作用就是在使用Spring框架创建对象时,动态地将其所依赖的对象注入到Bean组件中。
is a:是一个,继承,猫是一个动物。
has a:有一个,成员变量,依赖。
class A{
private B b;//A类依赖B类
}
依赖注入存在三种实现方式
- 属性setter注入
- 构造方法注入
- 接口注入:Spring容器不支持
定义一个dao层的接口
public interface BookDao {
void addBook();
}
定义一个dao层的实现类
public class BookDaoImpl implements BookDao {
@Override
public void addBook() {
System.out.println("di add book");
}
}
定义一个Service层的接口
public interface BookService {
void addBook();
}
定义一个Service层的实现类
public class BookServiceImpl implements BookService {
// 方式1:之前的方式,接口=实现类
//private BookDao bookDao = new BookDaoImpl();
// 方式2: setter
//使用BookDao接口声明一个对象
private BookDao bookDao;
//添加BookDao对象的set方法,用于依赖注入
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
@Override
public void addBook(){
this.bookDao.addBook();
}
}
配置文件
<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">
<!--
模拟spring执行过程
创建service实例:BookService bookService = new BookServiceImpl() IoC <bean>
创建dao实例:BookDao bookDao = new BookDaoImpl() IoC
将dao设置给service:bookService.setBookDao(bookDao); DI <property>
<property> 用于进行属性注入
name: bean的属性名,通过setter方法获得
setBookDao ##> BookDao ##> bookDao
ref :另一个bean的id值的引用
-->
<!-- 创建service -->
<bean id="bookServiceId" class="com.itheima.b_di.BookServiceImpl">
<property name="bookDao" ref="bookDaoId"></property>
</bean>
<!-- 创建dao实例 -->
<bean id="bookDaoId" class="com.itheima.b_di.BookDaoImpl"></bean>
</beans>
测试类
public class TestIoC {
@Test
public void demo01(){
//1 获得容器
String xmlPath="/spring/src/applicationContext.xml";
ApplicationContext applicationContext=new ClassPathXmlApplicationContext(xmlPath);
//2.获得对象
UserService userService = (UserService) applicationContext.getBean("bookServiceId");
userService.addUser();
}
}