初步理解 Spring IOC 思想
Spring IOC
最近跟着B站的狂神学习了Spring的大概,以前有过写传统JavaWeb的经验,现在也算是进阶学习框架吧,这篇博客主要记录一下Spirng中的两个重要思想之一——IOC,控制反转
大体思想
在开发的过程中,当体量较小时,用户需求的变更我们只需要修改几行源代码,目标代码容易找到,且容易修改,逻辑也更容易理解。但当项目的体量逐渐增大,乃至上万行时,每次用户需求的变更,如果按照以往的开发模式,我们需要修改几万行源代码,这明显是不合理的,如何减少需求变更时对源代码的修改,而采用注入的方法来达到目的,这就是IOC的用处。
示例说明并辅助理解
示例一(摘自狂神的视频):
JavaWeb开发中的Dao层接口:
package com.kuang.dao;
public interface UserDao {
void getUser();
}
Dao接口的几个实现类:
package com.kuang.dao;
public class UserDaoImpl implements UserDao {
public void getUser() {
System.out.println("默认获取用户的数据");
}
}
package com.kuang.dao;
public class UserDaoMysqlImpl implements UserDao{
@Override
public void getUser() {
System.out.println("Mysql获取用户数据!");
}
}
```java
package com.kuang.dao;
public class UserDaoOracleImpl implements UserDao{
@Override
public void getUser() {
System.out.println("Oracle获取用户数据!");
}
}
package com.kuang.dao;
public class UserDaoSqlserverImpl implements UserDao{
@Override
public void getUser() {
System.out.println("Sqlserver获取用户数据!");
}
}
接下来说Service层的接口,一般都是通过Service层(业务层)去调用Dao层,来完成相关操作:
package com.kuang.service;
public interface UserService {
void getUser();
}
业务层接口的实现类:
package com.kuang.service;
import com.kuang.dao.UserDao;
import com.kuang.dao.UserDaoImpl;
public class UserServiceImpl implements UserService {
// private UserDao userDao = new UserDaoImpl();
private UserDao userDao;
//利用set进行动态实现值的注入!
public void setUserDao(UserDao userDao){
this.userDao = userDao;
}
public void getUser() {
userDao.getUser();
}
}
编写的测试类:
import com.kuang.dao.UserDao;
import com.kuang.dao.UserDaoMysqlImpl;
import com.kuang.dao.UserDaoOracleImpl;
import com.kuang.service.UserService;
import com.kuang.service.UserServiceImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
public static void main(String[] args) {
//用户实际调用的是业务层,dao层他们不需要直接接触。
// UserService userService = new UserServiceImpl();
// UserDao userService = new UserDaoMysqlImpl();
// UserDao userService = new UserDaoOracleImpl();
/*UserService userService = new UserServiceImpl();
((UserServiceImpl) userService).setUserDao(new UserDaoMysqlImpl());
((UserServiceImpl) userService).setUserDao(new UserDaoOracleImpl());
userService.getUser();*/
//获取ApplicationContext:拿到Spring的容器
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
//容器在手,天下我有,需要什么,就直接get什么!
UserServiceImpl userServiceImpl = (UserServiceImpl) context.getBean("UserServiceImpl");
userServiceImpl.getUser();
}
}
示例二(买果汁):
传统思想
主动创造橙汁,需要我们实现自己可能不太然悉的工作——如何搅拌橙汁, 显然这不是一个好的办法。
IOC思想
在现实中,一个复杂的系统面对着成百上千种情况,如果都需要这样维护,那么会分复杂,更多的时候,我们并不希望了解这类过程,因为有些东西我们并不需要知道过程只需要获得最后的结果。正如果汁的例子那样,现实生活中我们更加希望的是通过对对象的描述就可以得到果汁,只想对结果进行描述,得到我们所需要的东西,这就是被动创建象了。
抽取思想
从以上两个示例我们可以看到,从主动修改源代码去创建对象,到提交系统一定的参数,让系统自动的,被动的帮我们去创建对象,实现控制反转。这——就是IOC,这一思想,是主动到被动的转变,我们通过使用Spring,向Spring的配置文件——ApplicationContext.xml中配置bean(给系统所需要的参数,Spring就会帮我们自动的生成相应参数的对象,需要什么我们就通过context.getBean("")*去获取什么,Spring会帮助我们自动的获取到相应的对象,从而大幅度减少了对源代码的修改,当有新需求的时候,我们只需要在bean中配置即可
总结
其实我们在以前编写代码的时候已经有意无意中使用了IOC思想,只不过一直没有将他很好的提取。Spring正是将这种思想提取后,进行优化,最后形成了一整套系统的体系,从而改变饿了传统的JavaWeb的开发思想,但这种通过配置的做法也有相应的缺点,配置的复制性随着开发的进行越来越严重,优点也逐渐成为了缺点,所以最后诞生了SpringBoot。