1 简介
InstantiationStrategy 定义了Spring的实例化策略,共有3个策略
- 无参构造方法
- 工厂方法
- 有参构造方法
InstantiationStrategy接口有两个实现类:SimpleInstantiationStrategy和CglibSubclassingInstantiationStrategy。其中SimpleInstantiationStrategy对以上三个方法都做了简单的实现
源码奉上
public interface InstantiationStrategy {
/**
* 默认构造方法
*/
Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner)
throws BeansException;
/**
* 有参构造方法
*/
Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
Constructor<?> ctor, @Nullable Object... args) throws BeansException;
/**
* 工厂方法
*/
Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
@Nullable Object factoryBean, Method factoryMethod, @Nullable Object... args)
throws BeansException;
}
2 子接口SimpleInstantiationStrategy
2.1 工厂方法
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
@Nullable Object factoryBean, final Method factoryMethod, Object... args) {
try {
// 设置 Method 为可访问,主要是类修饰符,方法修饰符等
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
ReflectionUtils.makeAccessible(factoryMethod);
return null;
});
} else {
ReflectionUtils.makeAccessible(factoryMethod);
}
// 获得原 Method 对象,主要是为了后面再回复原值
Method priorInvokedFactoryMethod = currentlyInvokedFactoryMethod.get();
try {
// 设置新的 Method 对象,到 currentlyInvokedFactoryMethod 中
currentlyInvokedFactoryMethod.set(factoryMethod);
// 创建 Bean 对象
Object result = factoryMethod.invoke(factoryBean, args);
// 未创建,则创建 NullBean 对象
if (result == null) {
result = new NullBean();
}
return result;
} finally {
// 设置老的 Method 对象,到 currentlyInvokedFactoryMethod 中
if (priorInvokedFactoryMethod != null) {
currentlyInvokedFactoryMethod.set(priorInvokedFactoryMethod);
} else {
currentlyInvokedFactoryMethod.remove();
}
}
// 一大堆 catch 异常
} catch (IllegalArgumentException ex) {
//一大堆异常代码省略
}
}
2.2 带参构造方法
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
final Constructor<?> ctor, Object... args) {
// 没有覆盖,直接使用反射实例化即可
if (!bd.hasMethodOverrides()) {
if (System.getSecurityManager() != null) {
// 设置构造方法,可访问
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
ReflectionUtils.makeAccessible(ctor);
return null;
});
}
// 通过 BeanUtils 直接使用构造器对象实例化 Bean 对象
return BeanUtils.instantiateClass(ctor, args);
} else {
// 生成 CGLIB 创建的子类对象
return instantiateWithMethodInjection(bd, beanName, owner, ctor, args);
}
}
2.4 无参构造
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// 没有覆盖,直接使用反射实例化即可
if (!bd.hasMethodOverrides()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
// 获得构造方法 constructorToUse
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
final Class<?> clazz = bd.getBeanClass();
// 如果是接口,抛出 BeanInstantiationException 异常
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
// 从 clazz 中,获得构造方法
if (System.getSecurityManager() != null) { // 安全模式
constructorToUse = AccessController.doPrivileged(
(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
} else {
constructorToUse = clazz.getDeclaredConstructor();
}
// 标记 resolvedConstructorOrFactoryMethod 属性
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
} catch (Throwable ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
// 通过 BeanUtils 直接使用构造器对象实例化 Bean 对象
return BeanUtils.instantiateClass(constructorToUse);
} else {
// Must generate CGLIB subclass.
// 生成 CGLIB 创建的子类对象
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
3CglibSubclassingInstantiationStrategy
CglibSubclassingInstantiationStrategy 是SimpleInstantiationStrategy的子接口,主要实现了instantiateWithMethodInjection 方法,源码如下
CglibSubclassingInstantiationStrategy 的实例化策略是通过其子类CglibSubclassCreator 实现的,最终是调用CglibSubclassCreator.instantiate 方法
@Override
protected Object instantiateWithMethodInjection(RootBeanDefinition bd, String beanName, BeanFactory owner) {
return instantiateWithMethodInjection(bd, beanName, owner, null);
}
@Override
protected Object instantiateWithMethodInjection(RootBeanDefinition bd, String beanName, BeanFactory owner,
Constructor<?> ctor, Object... args) {
// 通过 CGLIB 派生一个子类
return new CglibSubclassCreator(bd, owner).instantiate(ctor, args);
}
/**
* An inner class created for historical reasons to avoid external CGLIB dependency
* in Spring versions earlier than 3.2.
*/
private static class CglibSubclassCreator {
private static final Class<?>[] CALLBACK_TYPES = new Class<?>[]
{NoOp.class, LookupOverrideMethodInterceptor.class, ReplaceOverrideMethodInterceptor.class};
private final RootBeanDefinition beanDefinition;
private final BeanFactory owner;
CglibSubclassCreator(RootBeanDefinition beanDefinition, BeanFactory owner) {
this.beanDefinition = beanDefinition;
this.owner = owner;
}
public Object instantiate(Constructor<?> ctor, Object... args) {
// <x> 通过 Cglib 创建一个代理类
Class<?> subclass = createEnhancedSubclass(this.beanDefinition);
Object instance;
//没有构造器,通过 BeanUtils 使用默认构造器创建一个bean实例
if (ctor == null) {
instance = BeanUtils.instantiateClass(subclass);
}
else {
try {
//获取代理类对应的构造器对象,并实例化 bean
Constructor<?> enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());
instance = enhancedSubclassConstructor.newInstance(args);
} catch (Exception ex) {
throw new BeanInstantiationException(this.beanDefinition.getBeanClass(),
"Failed to invoke constructor for CGLIB enhanced subclass [" + subclass.getName() + "]", ex);
}
}
//直接在 bean 实例上设置回调对象
Factory factory = (Factory) instance;
factory.setCallbacks(new Callback[] {NoOp.INSTANCE,
new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),
new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});
return instance;
}
private Class<?> createEnhancedSubclass(RootBeanDefinition beanDefinition) {
// 创建 Enhancer 对象
Enhancer enhancer = new Enhancer();
// 设置 Bean 类
enhancer.setSuperclass(beanDefinition.getBeanClass());
// 设置 Spring 的命名策略
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
// 设置生成策略
if (this.owner instanceof ConfigurableBeanFactory) {
ClassLoader cl = ((ConfigurableBeanFactory) this.owner).getBeanClassLoader();
enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(cl));
}
enhancer.setCallbackFilter(new MethodOverrideCallbackFilter(beanDefinition));
enhancer.setCallbackTypes(CALLBACK_TYPES);
return enhancer.createClass();
}
}
4 注册表BeanDefinitionRegistry
BeanDefinitionRegistry 将bean的资源文件解析成BeanDefinition,并且注入到容器中
4.1 别名管理通用接口AliasRegistry
public interface AliasRegistry {
void registerAlias(String name, String alias);
void removeAlias(String alias);
boolean isAlias(String name);
String[] getAliases(String name);
}
4.2 BeanDefinitionRegistry
BeanDefinitionRegistry 是 Spring 的 Bean 工厂包中唯一封装 BeanDefinition 注册的接口。该接口定义了关于 BeanDefinition 注册、注销、查询等一系列的操作。
public interface BeanDefinitionRegistry extends AliasRegistry {
// 往注册表中注册一个新的 BeanDefinition 实例
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException;
// 移除注册表中已注册的 BeanDefinition 实例
void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
// 从注册中取得指定的 BeanDefinition 实例
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
// 判断 BeanDefinition 实例是否在注册表中(是否注册)
boolean containsBeanDefinition(String beanName);
// 取得注册表中所有 BeanDefinition 实例的 beanName(标识)
String[] getBeanDefinitionNames();
// 返回注册表中 BeanDefinition 实例的数量
int getBeanDefinitionCount();
// beanName(标识)是否被占用
boolean isBeanNameInUse(String beanName);
}
4.3 实现接口
4.3.1 SimpleBeanDefinitionRegistry
SimpleBeanDefinitionRegistry 是BeanDefinitionRegistry 一个简单的实现,仅仅提供注册功能,无工厂功能,SimpleBeanDefinitionRegistry 使用 ConcurrentHashMap 来存储注册的 BeanDefinition。
public class SimpleBeanDefinitionRegistry extends SimpleAliasRegistry implements BeanDefinitionRegistry {
/** Map of bean definition objects, keyed by bean name */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(64);
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
Assert.hasText(beanName, "'beanName' must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
this.beanDefinitionMap.put(beanName, beanDefinition);
}
@Override
public void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
if (this.beanDefinitionMap.remove(beanName) == null) {
throw new NoSuchBeanDefinitionException(beanName);
}
}
@Override
public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
BeanDefinition bd = this.beanDefinitionMap.get(beanName);
if (bd == null) {
throw new NoSuchBeanDefinitionException(beanName);
}
return bd;
}
@Override
public boolean containsBeanDefinition(String beanName) {
return this.beanDefinitionMap.containsKey(beanName);
}
@Override
public String[] getBeanDefinitionNames() {
return StringUtils.toStringArray(this.beanDefinitionMap.keySet());
}
@Override
public int getBeanDefinitionCount() {
return this.beanDefinitionMap.size();
}
@Override
public boolean isBeanNameInUse(String beanName) {
return isAlias(beanName) || containsBeanDefinition(beanName);
}
}
4.3.2DefaultListableBeanFactory
DefaultListableBeanFactory 同时实现了ConfigurableListableBeanFactory和 BeanDefinitionRegistry 是一个基于 BeanDefinition 元数据的完整 bean 工厂。DefaultListableBeanFactory 是一个具有注册功能的完整 Bean 工厂。它同样是用 ConcurrentHashMap 数据结构来存储注册的 BeanDefinition 。
// 注册表,由 BeanDefinition 的标识 (beanName) 与其实例组成
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, bean>(64);
// 标识(beanName)集合
private final List<String> beanDefinitionNames = new ArrayList<String>(64);
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
// ... 省略其他代码
// 如果未存在
} else {
// 检测创建 Bean 阶段是否已经开启,如果开启了则需要对 beanDefinitionMap 进行并发控制
if (hasBeanCreationStarted()) {
// beanDefinitionMap 为全局变量,避免并发情况
synchronized (this.beanDefinitionMap) {
// 添加到 BeanDefinition 到 beanDefinitionMap 中。
this.beanDefinitionMap.put(beanName, beanDefinition);
// 添加 beanName 到 beanDefinitionNames 中
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
// 从 manualSingletonNames 移除 beanName
if (this.manualSingletonNames.contains(beanName)) {
Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
updatedSingletons.remove(beanName);
this.manualSingletonNames = updatedSingletons;
}
}
} else {
// Still in startup registration phase
// 添加到 BeanDefinition 到 beanDefinitionMap 中。
this.beanDefinitionMap.put(beanName, beanDefinition);
// 添加 beanName 到 beanDefinitionNames 中
this.beanDefinitionNames.add(beanName);
// 从 manualSingletonNames 移除 beanName
this.manualSingletonNames.remove(beanName);
}
this.frozenBeanDefinitionNames = null;
}
// 重新设置 beanName 对应的缓存
if (existingDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
}
- 注册的核心代码时
this.beanDefinitionMap.put(beanName, beanDefinition); - 销毁的核心代码是
beanDefinitionMap.remove(beanName)
4.4 GenericApplicationContext
GenericApplicationContext 的注册和销毁其实都是委托DefaultListableBeanFactory实现的
private final DefaultListableBeanFactory beanFactory;
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {
this.beanFactory.registerBeanDefinition(beanName, beanDefinition);
}
@Override
public void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
this.beanFactory.removeBeanDefinition(beanName);
}