概述
控制反转(Inversion of Control,IoC)也称为依赖注入(Dependency Injection,DI),是面向对象编程的一种设计理念,用来降低程序代码之间的耦合度。
简而言之: IoC的作用就是:解耦
什么是解耦
编译时不依赖,运行时依赖。
如:在B类的一个方法中,A a = new A()
实例化A类的对象并调用其他方法来完成特定的功能,这就是一种依赖关系,称:A类依赖于B类。
如何解决?
- 使用反射创建对象拒绝
new
对象 - 读取配置文件获取全限定类名字符串进行反射
使用工厂模式解决
利用简单工厂和工厂方法模式的思路解决此类问题。该例子采用饿汉模式
程序运行,直接将配置文件的提取,实例化对象之后放入map集合
中。
BeanFactory.java
package factory;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
public class BeanFactory {
private static Properties pros;
private static Map<String,Object> beans;
static {
// 实例化对象
pros = new Properties();
// 获取properties文件的流对象
InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
try {
pros.load(in);
} catch (IOException e) {
e.printStackTrace();
}
beans = new HashMap<String, Object>();
Enumeration keys = pros.keys();
while(keys.hasMoreElements()){
// 取key
String key = keys.nextElement().toString();
// 根据key获取value
String beanvalue = pros.getProperty(key);
// 反射得到对象
try {
Object object = Class.forName(beanvalue).newInstance();
// 存入数据
beans.put(key,object);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
public static Object getBean(String beanName){
// 返回对象
return beans.get(beanName);
}
}
Client.java
package ui;
import factory.BeanFactory;
import service.ICountMoney;
public class Client {
public static void main(String[] args) throws Exception {
for(int i = 0 ; i < 5;i++) {
ICountMoney iCountMoney = (ICountMoney) BeanFactory.getBean("usercountmoney");
iCountMoney.savemoney();
}
}
}
这种就是简单的控制反转思想。不再依靠自身的代码去获得具体对象,而是将这一项工作转交给了第三方:BeanFactory
,从而避免了具体实现类之间的耦合。
使用Spring框架进行实例化对象
- 编写
applicationContext.xml
配置文件 - 编写主函数
- 获取容器对象
- 根据id获取bean对象
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.xsd">
<!-- 键值对。id为:键。class为:值 -->
<bean id="user" class="dao.impl.User">
</bean>
<bean id="usercountmoney" class="service.impl.UserCountMoney">
</bean>
</beans>
Client.java
package ui;
import dao.IUserDao;
import dao.impl.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import service.ICountMoney;
import service.impl.UserCountMoney;
public class Client {
public static void main(String[] args) throws Exception {
// ICountMoney iCountMoney = new UserCountMoney();
// 1.获取容器对象..两种方法
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
// ApplicationContext applicationContext1 = new FileSystemXmlApplicationContext("磁盘路径");
// 2.根据id获取Bean对象..两种方法
IUserDao userDao = (User)applicationContext.getBean("user");
ICountMoney iCountMoney = applicationContext.getBean("usercountmoney",UserCountMoney.class);
System.out.println("userdao:" + userDao);
System.out.println("icountmongey:"+iCountMoney);
}
}