文章目录
拓展bean的作用域以及实现FactoryBean.
在之前实现的bean中获取bean默认都是单例的也就是只创建一个bean对象,这次拓展beanDefinition添加单例实现和prototype实现
bean作用域
beanDefinition添加字段
String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
private boolean singleton = true;
private boolean prototype = false;
public void setScope(String scope){
this.scope = scope;
this.singleton = SCOPE_SINGLETON.equals(scope);
this.prototype = SCOPE_PROTOTYPE.equals(scope);
}
registry bean时添加bean的scope
// 如果配置了scope设置scope..
if(StrUtil.isNotEmpty(beanScope)){
beanDefinition.setScope(beanScope);
}
创建bean时进行判断
@Override
protected Object createBean(String beanName, BeanDefinition beanDefinition, Object[] args) throws BeansException {
Object bean = null;
try {
bean = createBeanInstance(beanDefinition, beanName, args);
// 给 Bean 填充属性
applyPropertyValues(beanName, bean, beanDefinition);
// 执行 Bean 的初始化方法和 BeanPostProcessor 的前置和后置处理方法
bean = initializeBean(beanName, bean, beanDefinition);
} catch (Exception e) {
throw new BeansException("Instantiation of bean failed", e);
}
// 注册实现了 DisposableBean 接口的 Bean 对象
registerDisposableBeanIfNecessary(beanName, bean, beanDefinition);
// 判断 SCOPE_SINGLETON、SCOPE_PROTOTYPE
if(beanDefinition.isSingleton()){
addSingleton(beanName, bean);
}
// 如果不是单例则直接创建对象返回
return bean;
}
扩展FactoryBean
factoryBean本质也是一个bean对象,区别于普通的bean,它生成bean。
FactoryBean接口
public interface FactoryBean<T> {
T getObject() throws Exception;
Class<?> getObjectType();
boolean isSingleton();
}
FactoryBeanRegistrySupport FactoryBean注册
存放的都是通过FactoryBean 创建的对象
public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry{
private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<String, Object>();
// 从缓存中获取
protected Object getCachedObjectForFactoryBean(String beanName){
Object object = this.factoryBeanObjectCache.get(beanName);
return (object != NULL_OBJECT ? object : null);
}
// 从FactoryBean中获取.
protected Object getObjectFromFactoryBean(FactoryBean factory, String beanName) {
// 判断当前factory是单例吗
if (factory.isSingleton()) {
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
object = doGetObjectFromFactoryBean(factory, beanName);
this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
}
return (object != NULL_OBJECT ? object : null);
}else{
return doGetObjectFromFactoryBean(factory, beanName);
}
}
private Object doGetObjectFromFactoryBean(final FactoryBean factory, final String beanName){
try {
return factory.getObject();
}catch (Exception e){
throw new BeansException("FactoryBean threw exception on object[" + beanName + "] creation", e);
}
}
}
AbstractBeanFactory.GetBean方法
getBean时首先拿到当前bean对象判断是FactoryBean对象吗?如果是需要从上一步中FactoryBeanRegistry的map中来获取对象。 如果不是先创建FactoryBean对象还是继续去FactoryBean中去获取。
protected <T> T doGetBean(final String name, final Object[] args) {
Object sharedInstance = getSingleton(name);
if (sharedInstance != null) {
// 如果是 FactoryBean,则需要调用 FactoryBean#getObject
return (T) getObjectForBeanInstance(sharedInstance, name);
}
BeanDefinition beanDefinition = getBeanDefinition(name);
Object bean = createBean(name, beanDefinition, args);
return (T) getObjectForBeanInstance(bean, name);
}
getObjectForBeanInstance
如果拿到的不是FactoryBean类型的对象则直接返回
private Object getObjectForBeanInstance(Object beanInstance, String beanName) {
// 如果当前拿的对象不是FactoryBean 返回单例中存放的bean对象
if (!(beanInstance instanceof FactoryBean)) {
return beanInstance;
}
// 否则去factoryBean的缓存中去拿对象.
Object object = getCachedObjectForFactoryBean(beanName);
// 缓存中没有则通过FactoryBean去创建这个对象
if(object == null){
FactoryBean<?> factoryBean = (FactoryBean<?>) beanInstance;
object = getObjectFromFactoryBean(factoryBean,beanName);
}
return object;
}
getObjectFromFactoryBean
protected Object getObjectFromFactoryBean(FactoryBean factory, String beanName) {
// 判断当前factory是单例吗
if (factory.isSingleton()) {
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
object = doGetObjectFromFactoryBean(factory, beanName);
this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
}
return (object != NULL_OBJECT ? object : null);
}else{
return doGetObjectFromFactoryBean(factory, beanName);
}
}