1.0手写spring-IOC
IOC容器的介绍
IOC容器的设计
Bean工厂的抽象
Bean定义注册的设计
Bean定义的设计
Bean定义接口
Bean工厂,Bean定义,Bean定义注册总结
Bean工厂实现
默认工厂实现
@Override
public Object getBean(String name) throws Exception {
return this.doGetBean(name);
}
protected Object doGetBean(String beanName) throws Exception {
Objects.requireNonNull(beanName, "beanName不能为空");
Object instance = beanMap.get(beanName);
if (instance != null) {
return instance;
}
BeanDefinition bd = this.getBeanDefinition(beanName);
Objects.requireNonNull(bd, "beanDefinition不能为空");
Class<?> type = bd.getBeanClass();
if (type != null) {
if (StringUtils.isBlank(bd.getFactoryMethodName())) {
instance = this.createInstanceByConstructor(bd);
} else {
instance = this.createInstanceByStaticFactoryMethod(bd);
}
} else {
instance = this.createInstanceByFactoryBean(bd);
}
this.doInit(bd, instance);
if (bd.isSingleton()) {
beanMap.put(beanName, instance);
}
return instance;
}
获得bean的三种方法
private Object createInstanceByConstructor(BeanDefinition bd)
throws InstantiationException, IllegalAccessException {
try {
return bd.getBeanClass().newInstance();
} catch (SecurityException e1) {
logger.error("创建bean的实例异常,beanDefinition:" + bd, e1);
throw e1;
}
}
private Object createInstanceByStaticFactoryMethod(BeanDefinition bd) throws Exception {
Class<?> type = bd.getBeanClass();
Method m = type.getMethod(bd.getFactoryMethodName(), null);
return m.invoke(type, null);
}
private Object createInstanceByFactoryBean(BeanDefinition bd) throws Exception {
Object factoryBean = this.doGetBean(bd.getFactoryBeanName());
Method m = factoryBean.getClass().getMethod(bd.getFactoryMethodName(), null);
return m.invoke(factoryBean, null);
}
提前初始化单例Bean
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionRegistException {
super.registerBeanDefinition(beanName, beanDefinition);
synchronized (beanNames) {
beanNames.add(beanName);
}
}
public void preInstantiateSingletons() throws Exception {
synchronized (beanNames) {
for (String name : beanNames) {
BeanDefinition bd = this.getBeanDefinition(name);
if (bd.isSingleton()) {
this.doGetBean(name);
if (logger.isDebugEnabled()) {
logger.debug("preInstantiate: name=" + name + " " + bd);
}
}
}
}
}