IOC作为Spring的核心功能其核心思想:
帮用户管理对象,对象的创建不需要再由应用实现,而是交给了spring来管理。也就是对象的控制交给了第三方,也就是控制反转的由来。
下面是Spring IOC核心工厂类的结构图
从这个类结构图我们可以看出DefaultListableBeanFactory实现了哪些功能
1、 是一个BeanDefinition注册器
2、 最重要的它是一个bean工厂
3、 它是一个别名注册器
4、 他是一个单例对象注册器
BeanDefinition
通过解析Xml或者注解扫描获取到的目标对象的属性,spring根据这个对象通过反射机制来创建目标对象。我们可以看看BeanDefinition接口的一个重要方法
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
String getBeanClassName();
void setBeanClassName(String beanClassName);
}
实现这个接口的肯定会提供类全限定名属性,spring可以通过全限定名反射并实例化对象。
Alias
spring可以实现一个Bean对象有多个别名
<bean id="pos" class="com.yanlink.chapter4.alias.Pos">
<property name="name" value="密码键盘"/>
</bean>
<alias name="pos" alias="pax"/>
<alias name="pos" alias="box"/>
Pos pos1 = (Pos) beanFactory.getBean("pax");
pos1 = (Pos) beanFactory.getBean("box");
两次获取的对象是同一个对象。
我们看看别名的实现类
public class SimpleAliasRegistry implements AliasRegistry {
/** Map from alias to canonical name */
private final Map<String, String> aliasMap = new ConcurrentHashMap<String, String>(16);
public void registerAlias(String name, String alias) {
if (alias.equals(name)) {
// 如果别名和本名一样,则不需要添加别名机制
this.aliasMap.remove(alias);
}
else {
this.aliasMap.put(alias, name);
}
}
我们看到了注册别名的时候其实就是往一个Map对象中添加别名映射的实际对象名。在使用的时候会再根据别名找到实际对象名。
BeanFactory
我们看看BeanFactory接口
public interface BeanFactory {
Object getBean(String name) throws BeansException;
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
<T> T getBean(Class<T> requiredType) throws BeansException;
Object getBean(String name, Object... args) throws BeansException;
}
这里接口定义了通过各种方式获取Bean的方法,这里面的细节单独需要一个章节来讲解,这里我们只要知道DefaultListableBeanFactory是一个工厂就可以了,这里使用了工厂方法的设计模式,定义创建产品的方法,具体实现交给子类处理。
SingletonBeanRegistry
spring管理的主要还是Scope为Singleton类型的Bean,这个接口就是针对创建的Singleton的bean对象的管理。
先来看看其接口
public interface SingletonBeanRegistry {
// 注册singleton对象
void registerSingleton(String beanName, Object singletonObject);
// 获取singleton对象
Object getSingleton(String beanName);
boolean containsSingleton(String beanName);
String[] getSingletonNames();
int getSingletonCount();
}
从这个接口可以看出来,spring创建的bean如果是singleton是需要被管理起来的,我们来看看其实现
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
/**
* Internal marker for a null singleton object:
* used as marker value for concurrent Maps (which don't support null values).
*/
protected static final Object NULL_OBJECT = new Object();
/** Cache of singleton objects: bean name --> bean instance */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(64);
/** Cache of singleton factories: bean name --> ObjectFactory */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16);
/** Cache of early singleton objects: bean name --> bean instance */
private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);
/** Set of registered singletons, containing the bean names in registration order */
private final Set<String> registeredSingletons = new LinkedHashSet<String>(64);
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
addSingleton(beanName, singletonObject);
}
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
// 向singletonObjects中添加对象,如果添加的是null,则向singletonObjects中添加NULL_OBJECT
this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 从singletonObjects获取对象
Object singletonObject = this.singletonObjects.get(beanName);
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
protected void removeSingleton(String beanName) {
synchronized (this.singletonObjects) {
this.singletonObjects.remove(beanName);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.remove(beanName);
}
}
}
从这个实现看出来spring创建的对象如果是singleton的,将会保存在一个ConcurrentHashMap中缓存起来,多次获取同一名称的对象spring返回的是同一个对象,所以Singleton在spring中表现为单例形式的对象。
singleton相关的可不仅仅是缓存单例对象,它还解决了一个比较重要的问题循环依赖,这个我也分一个小章节来讲解。
总结:
今天这篇文章简单地介绍了Spring的核心类DefaultListableBeanFactory是什么
1、它是一个BeanDefinition注册器
2、它是一个Bean工厂
3、它是一个别名注册器
4、它是一个Singleton注册器