IOC:控制反转,原本我们创建一个对象是我们手动new出来的,这样导致耦合度高。现在将对象创建的权利交给工厂,由工厂来创建对象,从而达到解耦合的作用。
1.没有使用IOC的时候
①我们在Vip类中引用UserService 的时候是使用new的方式
UserService userService = new UserServiceImpl() 如果我们修改了UserServiceImpl名称,那 时我们还要到该类中去修改对应的名称,这样代码的耦合度就很高,开发效率低下。我们想要的效果是我们在Vip中只要引用实现类的接口,至于实现类如何修改我们不在乎。
// 接口
public interface UserSerice{
public void login(String name);
public void register(String name);
}
// 实现类
public Class UserServiceImpl{
public void login(String name){
System.out.println(name + "登录成功了")
}
public void register(String name){
System.out.println(name + "注册成功了")
}
}
// 引用UserService
public Class Vip{
private String name;
UserService userService = new UserServiceImpl();
userService.register(name);
userService.login(name);
}
②创建通用的BeanFactory用来创建bean
如果不使用new的方式,那就只能使用反射了,反射获取类的方式有很多种,我们采用的是根据全类名的方式。
Class clazz = Class.forName("包名+类名");
此时我们再次实现之前的功能,会发现还是有耦合并且很麻烦每次创建对象还要使用反射,还要使用全类名,强转等,更加的繁琐。但是如果我们把反射的代码抽象出来,只要遇到创建对象的场景都是用这段被抽象的代码即可。
public Class Vip{
private String name;
UserService userSerivce = null;
// 创建类
Class clazz = Class.forName("com.gy.service.UserServiceImpl");
// 实例化
userSerivce = (UserServiec)Class.newInstance();
userService.login(name);
}
抽象反射代码,不过这段代码现在Spring已经帮我们集成好了,所以在创建对象的时候不用在写下面的代码,都有Spring来进行完成。这也就是SpringIOC的简单实现原理。
public Class BeanFactory{
private static Properties env = new Properties();
static{
try {
//第一步 获得IO输入流 全类名在properties文件中维护
InputStream inputStream =
BeanFactory.class.getResourceAsStream("/applicationContext.properties");
//第二步 文件内容 封装 Properties集合中key = userService
//value = com.xxxx.UserServiceImpl
env.load(inputStream);
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
public static Object getBean(String key){
Object ret = null;
// 创建类,全类名从properties文件中获取
Clss clazz = Class.forName(env.getProperty(key));
// 实例化
ret = Class.newInstance();
return ret;
}
}