学习地址
链接: lite-spring
欢迎点赞,关注,分享
前言
在上一节中,基于Spring容器的模型以HashMap作为容器进行对象的存储和获取。并且对象是通过new
关键字创建的对象
在本节中,我们将以非new
关键字进行创建对象,并且按照Spring类结构编织类之间的关系,主要分为以下步骤:
1、实现Bean的定义并且注册定义好的Bean注册到Bean定义容器
2、获取Bean分为2种情形,一是Bean在单例容器中不存在,走一遍Bean注册流程,另一个是Bean在单例容器中已存在时,直接获取
3、在Spring容器获取Bean时,将实例化Bean,以及默认当前Bean是单例的,将Bean注册到单例对象容器中
设计
Bean的定义、注册
BeanDefinition类
在BeanDefinition中使用 Class类型来接收要注册的类,后续会在实例化的时候通过反射的方式创建需要的对象
public class BeanDefinition {
private Class beanClass;
public BeanDefinition(Class beanClass) {
this.beanClass = beanClass;
}
public Class getBeanClass() {
return beanClass;
}
public void setBeanClass(Class beanClass) {
this.beanClass = beanClass;
}
}
BeanDefinition容器类:
接口:BeanDefinitionRegistry
定义了如何将BeanDefinition注册到BeanDefinition容器的行为方式
单例Bean容器,用于获取单例Bean和注册单例Bean
接口:SingletonBeanRegistry
public interface SingletonBeanRegistry {
Object getSingleton(String name);
}
容器类:DefaultSingletonBeanRegistry
public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry {
private final Map<String, Object> singletonObjects = new HashMap<>();
@Override public Object getSingleton(String name) {
return singletonObjects.get(name);
}
protected void addSingleton(String beanName, Object singletonObject) {
singletonObjects.put(beanName, singletonObject);
}
}
Bean的获取、创建
在获取Bean的过程中,会进行Bean是否已存在的判读,如果不存在,需要走创建流程并将创建好的对象放到单例对象容器池中
首先、我们需要创建工厂类的接口BeanFactory
,用于对外提供工厂类的统一行为,目前主要是获取Bean的方法
public interface BeanFactory {
Object getBean(String name) throws SpringBeansException;
}
其次、创建实现了工厂类接口的抽象类AbstractBeanFactory
,是获取Bean的具体实现类,但在获取Bean的过程中,Bean如果没有创建,需要获取Bean的定义,并且创建Bean
public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements BeanFactory {
@Override
public Object getBean(String beanName) {
Object bean = getSingleton(beanName);
if (bean != null) {
System.out.println("无需创建,从缓存获取");
return bean;
}
BeanDefinition definition = getBeanDefinition(beanName);
return createBean(beanName, definition);
}
protected abstract BeanDefinition getBeanDefinition(String beanName) throws SpringBeansException;
protected abstract Object createBean(String beanName, BeanDefinition beanDefinition) throws SpringBeansException;
}
然后、为了实现职责分工以及对于创建Bean可以支持多实现,实现一个创建Bean的抽象类AbstractAutowireCapableBeanFactory
,使用反射的方式创建Bean
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory {
@Override protected Object createBean(String beanName, BeanDefinition beanDefinition) throws SpringBeansException {
Object bean;
try {
bean = beanDefinition.getBeanClass().newInstance();
} catch (Exception e) {
throw new SpringBeansException("Instantiation of bean failed", e);
}
addSingleton(beanName, bean);
return bean;
}
}
最后、定义一个实现类用于实现抽象工厂类和BeanDefinition容器类的最终实现类DefaultListableBeanFactory
,以及对外提供BeanDefinition
注册的行为和获取行为
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements BeanDefinitionRegistry {
private final Map<String, BeanDefinition> beanDefinitionMap = new HashMap<>();
@Override public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {
beanDefinitionMap.put(beanName, beanDefinition);
}
@Override protected BeanDefinition getBeanDefinition(String beanName) throws SpringBeansException {
BeanDefinition definition = beanDefinitionMap.get(beanName);
if (definition == null)
throw new SpringBeansException("No Bean Named '" + beanName + "' is defined");
return definition;
}
}
示例、单元测试
定义一个Bean
public class UserService {
public void getUser() {
System.out.println("获取用户对象");
}
}
测试Bean的定义、注册、获取、创建
@Test
public void test_bean_factory() {
//1.初始化Bean工厂
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
//2.注册Bean
BeanDefinition beanDefinition = new BeanDefinition(UserService.class);
beanFactory.registerBeanDefinition("userService", beanDefinition);
//3.第一次获取Bean
UserService userService = (UserService) beanFactory.getBean("userService");
userService.getUser();
//4.第二次获取Bean,且是Singleton类型
UserService userService_singleton = (UserService) beanFactory.getBean("userService");
userService_singleton.getUser();
}