spring-beans 一切都是围绕 bean 展开的。
BeanFactory 负责对 bean 进行生命周期的相关管理,本节展示第一小节的简单实现流程。
Spring IoC 主要是以下几个步骤。
初始化 IoC 容器。
读取配置文件。
将配置文件转换为容器识别对的数据结构(这个数据结构在Spring中叫做 BeanDefinition)
利用数据结构依次实例化相应的对象
注入对象之间的依赖关系
BeanDefinition 是 spring 对 java bean 属性的一个抽象,经过这一层抽象,配置文件可以是 xml/json/properties/yaml 等任意一种,甚至包括注解扫包。
为 spring 的拓展带来极大的灵活性。
本框架考虑到实现的简单性,初步只实现了 json 和基于注解扫包两种方式。
后期如果有时间可以考虑添加 xml 的实现,其实更多是 xml 的解析工作量,核心流程已经全部实现。
包含了对于 java bean 的基本信息抽象。
其默认实现为 DefaultBeanDefinition.java,就是对接口实现的最基本的 java POJO
/**
* 对象定义属性
* @author binbin.hou
* @since 0.0.1
*/
public interface BeanDefinition {
/**
* 名称
* @return 名称
* @since 0.0.1
*/
String getName();
/**
* 设置名称
* @param name 名称
* @since 0.0.1
*/
void setName(final String name);
/**
* 类名称
* @return 类名称
*/
String getClassName();
/**
* 设置类名称
* @param className 类名称
* @since 0.0.1
*/
void setClassName(final String className);
}
/**
* bean 工厂接口
* @author binbin.hou
* @since 0.0.1
*/
public interface BeanFactory {
/**
* 根据名称获取对应的实例信息
* @param beanName bean 名称
* @return 对象信息
* @since 0.0.1
*/
Object getBean(final String beanName);
/**
* 获取指定类型的实现
* @param beanName 属性名称
* @param tClass 类型
* @param <T> 泛型
* @return 结果
* @since 0.0.1
*/
<T> T getBean(final String beanName, final Class<T> tClass);
}
为接口最基础的实现,源码如下:
/**
* bean 工厂接口
* @author binbin.hou
* @since 0.0.1
*/
public class DefaultBeanFactory implements BeanFactory {
/**
* 对象信息 map
* @since 0.0.1
*/
private Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();
/**
* 对象 map
* @since 0.0.1
*/
private Map<String, Object> beanMap = new ConcurrentHashMap<>();
/**
* 注册对象定义信息
* @since 0.0.1
*/
protected void registerBeanDefinition(final String beanName, final BeanDefinition beanDefinition) {
// 这里可以添加监听器
this.beanDefinitionMap.put(beanName, beanDefinition);
}
@Override
public Object getBean(String beanName) {
Object bean = beanMap.get(beanName);
if(ObjectUtil.isNotNull(bean)) {
// 这里直接返回的是单例,如果用户指定为多例,则每次都需要新建。
return bean;
}
// 获取对应配置信息
BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
if(ObjectUtil.isNull(beanDefinition)) {
throw new IocRuntimeException(beanName + " not exists in bean define.");
}
// 直接根据
Object newBean = createBean(beanDefinition);
// 这里可以添加对应的监听器
beanMap.put(beanName, newBean);
return newBean;
}
/**
* 根据对象定义信息创建对象
* @param beanDefinition 对象定义信息
* @return 创建的对象信息
* @since 0.0.1
*/
private Object createBean(final BeanDefinition beanDefinition) {
String className = beanDefinition.getClassName();
Class clazz = ClassUtils.getClass(className);
return ClassUtils.newInstance(clazz);
}
@Override
@SuppressWarnings("unchecked")
public <T> T getBean(String beanName, Class<T> tClass) {
Object object = getBean(beanName);
return (T)object;
}
}
其中 ClassUtils 是基于 class 的反射工具类
基于 json 配置文件实现的基本实现,使用方式见开始种的例子代码。
至此,一个最基本的 spring ioc 就基本实现了。
全部评论