1. IOC 的介绍
IOC:Inversion of Control,控制反转。指的是对象的创建权反转(交给)给Spring,其作用是实现了程序的解耦合。也可这样解释:++获取对象的方式变了++。对象创建的控制权不是“使用者”,而是“框架”或者“容器”。
用更通俗的话来说,IOC就是指对象的创建,并不是在代码中用new操作new出来的,而是通过Spring进行配置创建的。其底层实现原理是XML配置文件+SAX解析+工厂设计模式。
2. 举例
就拿我们在前面讲JavaWeb入门中的MVC结构的持久层 [ 也即dao(data access object,数据访问对象)层 ] 的开发来说,官方推荐做法是先创建一个接口,然后再创建接口对应的实现类。
1. 先创建一个Userdao接口
public interface UserDao {
public void add();
}
2. 再创建Userdao接口的UserDaoImpl实现类
public class UserDaoImpl implements UserDao {
public void add() {
balabala......
}
}
3. 接着我们在service层调用dao层,核心代码如下:
// 接口 实例变量 = new 实现类
UserDao dao = new UserDaoImpl();
dao.add();
可发现缺点:service层和dao层耦合度太高了。解决方法是使用工厂模式进行解耦合操作。
4. 创建一个工厂类,在工厂类中提供一个方法,返回实现类的对象。
public class Factory {
// 提供返回实现类对象的方法
public static UserDao getUserDaoImpl() {
return new UserDaoImpl();
}
}
5. 然后在service层调用dao层的核心代码就变为:
UserDao dao = Factory.getUserDaoImpl();
dao.add();
如若这样做,会发现又产生了一个缺点:service层和工厂类又耦合了。所以使用工厂模式进行解耦合也只是一种权宜之计。
Spring的 IOC 入门案例: 我们修改上面的代码,利用Spring框架,来让Service层和Dao层彻底解耦合
1. 创建 maven 项目
2. 引入依赖
pom.xml
<dependencies>
<!-- Spring Context -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<!-- commons-logging -->
<!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>
3. 在 service 层写一个 main 方法(自己写一个 User POJO类)
public class TestIOC {
public static void main(String[] args) {
//传统的类和方法的使用:new对象,对象.方法()
// User user = new User();
// user.setUsername("xq");
// user.setPassword("12346");
// UserDao dao = new UserDaoImpl();
// dao.add(user);
//Spring的 3 步骤,获取类的对象
//1. 创建 spring 的 ioc(控制反转)的容器对象
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
//2. 从 ioc 容器中获取对象
UserDao userDao = ctx.getBean(UserDao.class);
User user = ctx.getBean(User.class);
//3. 使用获取的对象,以及调用他们的方法
userDao.add(user);
}
}
4. 创建 Spring 配置文件
注意:Spring配置文件的名称和位置没有固定要求,一般建议把该文件放到src下面,名称可随便写,官方建议写成applicationContext.xml。
5. 在配置文件中配置对象的创建
<bean id="userDao" class="www.xq.spring.dao.UserDaoImpl"></bean>
<bean id="user" class="www.xq.spring.bean.User">
<property name="username" value="xq"></property>
<property name="password" value="123456"></property>
</bean>
注意:如果 main 方法中只剩下:
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
我们加一些输出语句,看看 Spring IOC 容器的帮我们做了什么?
UserDaoImpl 的无参构造器被调用...
User 的无参构造器...
User 的 setUsername 方法被调用: xq