Spring的核心思想其中之一就是IOC,也就是依赖倒转
通俗的解释起来就是,我们将自己所需要的Bean对象在配置文件中写好其定义,配置好依赖注入等信息(他所需要的依赖)
由Spring负责创建该Bean,用的时候也直接从Spring来拿
这里记录一下简单的一个IOC容器的实现
Bean的定义
Spring的Bean定义一般通过Xml配置文件来实现,这里就不用Xml了,就用最简单的properties吧
userDao=UserDao
Key表示为bean的名字,Value表示为bean的全限定类名
另外再来一个对应的BeanDefinition类
public class BeanDefinition {
private String beanName;
private Class beanClass;
// 省略 getter setter
}
资源加载器
负责读取我们的配置文件,来加载bean信息入内存
public class ResourceLoader {
public static Map<String, BeanDefinition> loadBeans() {
Map<String, BeanDefinition> beanDefinitionMap = new HashMap<>(16);
Properties properties = new Properties();
try {
// 读取properties文件,获取所有的文字描述的bean definition
InputStream inputStream = ResourceLoader.class.getResourceAsStream("/beans.properties");
properties.load(inputStream);
Iterator<String> it = properties.stringPropertyNames().iterator();
while (it.hasNext()) {
String key = it.next();
String className = properties.getProperty(key);
// 创建bean definition
BeanDefinition beanDefinition = new BeanDefinition();
beanDefinition.setBeanName(key);
Class clazz = Class.forName(className);
beanDefinition.setBeanClass(clazz);
// 放入map中保存
beanDefinitionMap.put(key, beanDefinition);
}
inputStream.close();
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
}
return beanDefinitionMap;
}
}
Bean注册器
创建一个注册器,用来保存所有的单例Bean
public class BeanRegister {
// IOC容器
private Map<String, Object> iocContainer = new HashMap<>(32);
// 获取单例Bean
public Object getSingletonBean(String beanName) {
return iocContainer.get(beanName);
}
// 注册单例bean
public void registerSingletonBean(String beanName, Object bean) {
if (iocContainer.containsKey(beanName)) {
return;
}
iocContainer.put(beanName, bean);
}
}
BeanFactory
这里实现一个并夕夕版BeanFactory,用它来完成对Bean的获取与管理
它负责实现从配置文件读取bean definition信息,然后使用BeanRegister来注册bean到容器中
public class BeanFactory {
private Map<String, BeanDefinition> beanDefinitionMap;
private BeanRegister beanRegister;
public BeanFactory() {
beanRegister = new BeanRegister();
beanDefinitionMap = ResourceLoader.loadBeans();
}
public Object getBean(String beanName) {
// 从bean容器中获取
Object bean = beanRegister.getSingletonBean(beanName);
if (bean != null)
return bean;
// 如果没有的话, 就获取bean的定义信息, 创建bean后加入容器, 实现单例模式
createBean(beanDefinitionMap.get(beanName));
return beanRegister.getSingletonBean(beanName);
}
private void createBean(BeanDefinition beanDefinition) {
String beanName = beanDefinition.getBeanName();
Class beanClass = beanDefinition.getBeanClass();
try {
// 使用反射来创建bean, 并加入容器中
beanClass.newInstance();
beanRegister.registerSingletonBean(beanName, beanClass.newInstance());
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
}
}
测试一下
实体类
public class UserDao {
public void queryUserInfo(){
System.out.println("A good man.");
}
}
测试
public class Test {
public static void main(String[] args) {
BeanFactory beanFactory = new BeanFactory();
UserDao userDao = (UserDao) beanFactory.getBean("userDao");
UserDao userDao1 = (UserDao) beanFactory.getBean("userDao");
userDao.queryUserInfo();
System.out.println(userDao == userDao1);
}
}
最终打印结果
A good man.
true
可以发现实现了单例模式的并夕夕版IOC就已经实现成功了