- 目标
- 设计
- 实现
- BeanDefinition 的定义
- 单例注册接口的定义与实现
- 定义bean工厂 BeanFactory
- 抽象类定义模板方法 AbstractBeanFactory
- 实例化Bean类 AbstractAutowireCapableBeanFactory
- 核心类实现(DefaultListableBeanFactory)
- 测试
此文中实现了spring容器的粗略的版本
https://javaweixin6.blog.csdn.net/article/details/124256888
此节要实现bean容器关于对象的注册和获取 .
Bean的创建交给容器, 而不是在调用的时候, 传递一个实例化好的bean对象.
并且对对象进行单例模式的处理. 完善类的结构, 使其容易扩展.
在spring的bean注册的时候, 只注册一个类的信息, 而不会直接把实例化的信息注册到spring容器中去.则BeanDefinition 的属性为Class.
在获取bean对象的时候, 处理bean对象的实例化操作, 以及判断当前单例对象在容器中是否已经缓存起来了.
- 定义BeanFactory 这样的工厂, 提供Bean的获取方法, 这个Bean工厂接口由抽象类AbstractBeanFactory实现, 这个抽象类定义了模板方法模式的写法, 定义了标准, 控制了后续的实现者不用关心调用逻辑, 按照统一的方式执行即可, 类的继承者, 只需要关心具体方法的逻辑实现.
实现的uml图如下
属性为Class
public class BeanDefinition {
private Class beanClass;
// bean的实例化,是在BeanDefinition 的构造函数
public BeanDefinition(Class beanClass) {
this.beanClass = beanClass;
}
public Class getBeanClass() {
return beanClass;
}
public void setBeanClass(Class beanClass) {
this.beanClass = beanClass;
}
}
bean的实例化操作是放在初始化调用阶段传递给BeanDefinition的构造函数的.
单例注册接口的定义与实现SingletonBeanRegistry
public interface SingletonBeanRegistry {
Object getSingleton(String beanName);
}
单例的实现类DefaultSingletonBeanRegistry
public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry {
// 单例对象的缓存
private final Map singletonObjects = new HashMap<>();
public Object getSingleton(String beanName) {
return singletonObjects.get(beanName);
}
protected void addSingleton(String beanName, Object singletonObject) {
singletonObjects.put(beanName, singletonObject);
}
}
定义bean工厂 BeanFactory
public interface BeanFactory {
Object getBean(String name) throws BeansException;
}
抽象类定义模板方法 AbstractBeanFactory
public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements BeanFactory {
@Override
public Object getBean(String name) throws BeansException {
Object bean = super.getSingleton(name);
if (bean != null) {
// 从单例池中获取的不为null 则直接返回
return bean;
}
// 单例池中没有, 则创建bean 先获取bean 的定义信息
BeanDefinition beanDefinition = getBeanDefinition(name);
// 创建bean
return createBean(name, beanDefinition);
}
protected abstract Object createBean(String name, BeanDefinition beanDefinition) throws BeansException;
// 模板方法 获取bean 的定义信息
protected abstract BeanDefinition getBeanDefinition(String name) throws BeansException;
}
对于接口BeanFactory的实现, 做的处理是先从单例池中获取, 如果获取不到, 则去获取bean的定义信息, 并去创建bean. 但获取bean的信息和创建bean ,定义了抽象方法, 由其子类实现.
实例化Bean类 AbstractAutowireCapableBeanFactorypublic abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory {
@Override
protected Object createBean(String beanName, BeanDefinition beanDefinition) throws BeansException {
Object bean;
try {
// 获取bean 的class 反射去创建对象 此处的不足是只能构建无参构造的对象
bean = beanDefinition.getBeanClass().newInstance();
} catch (Exception e) {
e.printStackTrace();
throw new BeansException("Instantiation of bean failed", e);
}
addSingleton(beanName, bean);
return bean;
}
}
对于无参构造, 实例化了bean对象. 后续会优化有参构造.
核心类实现(DefaultListableBeanFactory)public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements BeanDefinitionRegistry {
private final Map beanDefinitionMap = new HashMap<>();
@Override
protected BeanDefinition getBeanDefinition(String beanName) throws BeansException {
BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
if (beanDefinition == null) throw new BeansException("no bean named " + beanName + " is defined");
return beanDefinition;
}
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {
beanDefinitionMap.put(beanName, beanDefinition);
}
}
测试
测试用的业务类
public class UserService {
public void queryUserInfo() {
System.out.println("查询用户信息");
}
}
测试类
public class ApiTest {
@Test
public void test_BeanFactory() {
// 1. 初始化BeanFactory
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
//2 . 注入bean Bean 的实例化操作是放在初始化调用阶段传递给 BeanDefinition 构造函数的。
BeanDefinition beanDefinition = new BeanDefinition( UserService.class);
beanFactory.registerBeanDefinition("userService", beanDefinition);
//3 . 第一次获取bean
UserService userService = (UserService) beanFactory.getBean("userService");
userService.queryUserInfo();
// 第二次获取bean
userService = (UserService) beanFactory.getBean("userService");
userService.queryUserInfo();
}
}
打印如下
查询用户信息
查询用户信息
重要的代码的设计思想 而不要成为码农



