简介
在Spring框架中,SimpleInstantiationStrategy类是一个实例化策略类,它负责处理bean实例的创建过程。该类是InstantiationStrategy接口的一个简单实现,用于通过调用bean的构造函数来实例化bean。
SimpleInstantiationStrategy的主要职责是:
- 调用构造函数:它根据BeanDefinition中指定的类名,使用反射调用该类的无参构造函数或带有参数的构造函数来创建bean的实例。
- 处理依赖:在创建bean实例的过程中,Spring会处理bean之间的依赖关系。这包括通过自动装配(Autowiring)将其他bean注入到新创建的bean中。
- 支持循环依赖处理:Spring在处理bean的创建和装配时,会检查和处理循环依赖的情况。SimpleInstantiationStrategy可能会与Spring的其他组件协同工作,以确保在循环依赖的情况下能够正确地创建和装配bean。
- 提供扩展点:虽然SimpleInstantiationStrategy提供了基本的实例化逻辑,但Spring框架的设计也允许开发者通过实现自定义的InstantiationStrategy接口来扩展或修改实例化过程。这给了开发者更大的灵活性,以适应特定的需求或集成其他框架。
在Spring的IoC容器中,SimpleInstantiationStrategy通常是默认的实例化策略。当容器需要创建bean的实例时,它会使用这个策略或根据BeanDefinition中指定的策略来实例化bean。
源码
public class SimpleInstantiationStrategy implements InstantiationStrategy {
//存储当前线程所要创建bean的工厂方法本地线程
private static final ThreadLocal<Method> currentlyInvokedFactoryMethod = new ThreadLocal<>();
/**
* Return the factory method currently being invoked or {@code null} if none.
* <p>Allows factory method implementations to determine whether the current
* caller is the container itself as opposed to user code.
*/
@Nullable
public static Method getCurrentlyInvokedFactoryMethod() {
return currentlyInvokedFactoryMethod.get();
}
//这里是通过无参构造方法创建bean实例
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
if (!bd.hasMethodOverrides()) {//没有重写方法,则不能使用CGLIB创建子类,这里使用反射创建bean实例
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
final Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface()) {//是接口 则抛出异常
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(
(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
}
else {//获取构造方法
constructorToUse = clazz.getDeclaredConstructor();
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Throwable ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
//反射创建
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// Must generate CGLIB subclass.
//这里使用CGLIB 创建子类 初始化bean
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
/**
* Subclasses can override this method, which is implemented to throw
* UnsupportedOperationException, if they can instantiate an object with
* the Method Injection specified in the given RootBeanDefinition.
* Instantiation should use a no-arg constructor.
*/
protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
throw new UnsupportedOperationException("Method Injection not supported in SimpleInstantiationStrategy");
}
//这里是通过有参构造方法创建bean实例
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
final Constructor<?> ctor, Object... args) {
if (!bd.hasMethodOverrides()) {
if (System.getSecurityManager() != null) {
// use own privileged to change accessibility (when security is on)
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
ReflectionUtils.makeAccessible(ctor);
return null;
});
}
return BeanUtils.instantiateClass(ctor, args);
}
else {
return instantiateWithMethodInjection(bd, beanName, owner, ctor, args);
}
}
/**
* Subclasses can override this method, which is implemented to throw
* UnsupportedOperationException, if they can instantiate an object with
* the Method Injection specified in the given RootBeanDefinition.
* Instantiation should use the given constructor and parameters.
*/
protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName,
BeanFactory owner, @Nullable Constructor<?> ctor, Object... args) {
throw new UnsupportedOperationException("Method Injection not supported in SimpleInstantiationStrategy");
}
//这里是通过工厂方法创建bean实例
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
@Nullable Object factoryBean, final Method factoryMethod, Object... args) {
try {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
ReflectionUtils.makeAccessible(factoryMethod);
return null;
});
}
else {
ReflectionUtils.makeAccessible(factoryMethod);
}
Method priorInvokedFactoryMethod = currentlyInvokedFactoryMethod.get();
try {
currentlyInvokedFactoryMethod.set(factoryMethod);
Object result = factoryMethod.invoke(factoryBean, args);
if (result == null) {
result = new NullBean();
}
return result;
}
finally {
if (priorInvokedFactoryMethod != null) {
currentlyInvokedFactoryMethod.set(priorInvokedFactoryMethod);
}
else {
currentlyInvokedFactoryMethod.remove();
}
}
}
catch (IllegalArgumentException ex) {
throw new BeanInstantiationException(factoryMethod,
"Illegal arguments to factory method '" + factoryMethod.getName() + "'; " +
"args: " + StringUtils.arrayToCommaDelimitedString(args), ex);
}
catch (IllegalAccessException ex) {
throw new BeanInstantiationException(factoryMethod,
"Cannot access factory method '" + factoryMethod.getName() + "'; is it public?", ex);
}
catch (InvocationTargetException ex) {
String msg = "Factory method '" + factoryMethod.getName() + "' threw exception";
if (bd.getFactoryBeanName() != null && owner instanceof ConfigurableBeanFactory &&
((ConfigurableBeanFactory) owner).isCurrentlyInCreation(bd.getFactoryBeanName())) {
msg = "Circular reference involving containing bean '" + bd.getFactoryBeanName() + "' - consider " +
"declaring the factory method as static for independence from its containing instance. " + msg;
}
throw new BeanInstantiationException(factoryMethod, msg, ex.getTargetException());
}
}
}
org.springframework.beans.BeanUtils#instantiateClass
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
Assert.notNull(ctor, "Constructor must not be null");
try {
ReflectionUtils.makeAccessible(ctor);
return (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ?
KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args));
}
catch (InstantiationException ex) {
throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
}
catch (IllegalAccessException ex) {
throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
}
catch (IllegalArgumentException ex) {
throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
}
catch (InvocationTargetException ex) {
throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
}
}
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#instantiateBean
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
try {
Object beanInstance;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged(
(PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(mbd, beanName, this),
getAccessControlContext());
}
else {
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
需要注意的是,虽然SimpleInstantiationStrategy是Spring框架中的一个重要组件,但在大多数应用开发中,开发者通常不需要直接与之交互。Spring容器会自动处理bean的创建和装配过程,开发者只需要关注bean的定义和配置即可。