spring学习(六)——5.2 Bean实例化策略

参考文章:

http://www.iocoder.cn/

 

bean的实例化过程

AbstractAutowireCapableBeanFactory#doCreateBean(...) 方法。在这个方法中有 Bean 的实例化、属性注入和初始化过程。主要是createBeanInstance方法

  • createBeanInstance(...) 方法中,如果 Supplier 不为空,则调用 #obtainFromSupplier(...) 实例化 bean
  • 如果 factory 不为空,则调用 #instantiateUsingFactoryMethod(...) 方法来实例化 Bean
  • 如果都不是,则调用 #instantiateBean(...) 方法来实例化 Bean 

InstantiationStrategy

InstantiationStrategy 接口定义了 Spring Bean 实例化的策略

三种策略:

  • 无参构造方法
  • 有参构造方法
  • 工厂方法
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, Object... args) throws BeansException;

	/**
	 * 工厂方法
	 */
	Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
			@Nullable Object factoryBean, Method factoryMethod, Object... args)
			throws BeansException;

}

InstantiationStrategy的实现类

InstantiationStrategy 接口有两个实现类:SimpleInstantiationStrategy 和 CglibSubclassingInstantiationStrategy

SimpleInstantiationStrategy

默认的构造方法

	@Override
	public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
		// Don't override the class with CGLIB if no overrides.
		// 没有覆盖,直接使用反射实例化即可
		if (!bd.hasMethodOverrides()) {
			// 获得构造方法 constructorToUse
			Constructor constructorToUse;
			synchronized (bd.constructorArgumentLock) {
				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>) 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);
		}
	}

判断bd.hasMethodOverrides()如果没有者直接使用反射,否则需要CGLIB 实例化对象来实例化bean

工厂方法

@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) () -> {
					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);
				// bean不存在则创建nullbean
				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());
		}
	}

直接通过反射获得对象

 

CglibSubclassingInstantiationStrategy

 CglibSubclassingInstantiationStrategy 为 Spring 实例化 Bean 的默认实例化策略,其主要功能还是对父类功能进行补充

@Override
	protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
			@Nullable Constructor ctor, Object... args) {

		// Must generate CGLIB subclass...
		// 通过CGLIB生成一个子类对象
		return new CglibSubclassCreator(bd, owner).instantiate(ctor, args);
	}

CglibSubclassingInstantiationStrategy 实例化 Bean 策略,是通过其内部类 CglibSubclassCreator 来实现的

public Object instantiate(@Nullable Constructor ctor, Object... args) {
			// 通过 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);
				}
			}
			// SPR-10785: set callbacks directly on the instance instead of in the
			// enhanced class (via the Enhancer) in order to avoid memory leaks.
			Factory factory = (Factory) instance;
			// 为了避免 memory leaks 异常,直接在 bean 实例上设置回调对象
			factory.setCallbacks(new Callback[] {NoOp.INSTANCE,
					new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),
					new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});
			return instance;
		}

createEnhancedSubclass-bean的增强子类

private Class createEnhancedSubclass(RootBeanDefinition beanDefinition) {
			// 创建Enhancer对象
			Enhancer enhancer = new Enhancer();
			// 设置bean类
			enhancer.setSuperclass(beanDefinition.getBeanClass());
			// 设置命名方式
			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();
		}

      

回调过滤

enhancer.setCallbackFilter(new MethodOverrideCallbackFilter(beanDefinition));

CallbackFilter 是 CGLIB 的一个回调过滤器,MethodOverrideCallbackFilter 实现 CallbackFilter 的 #accept(Method method) 方法

private static class MethodOverrideCallbackFilter extends CglibIdentitySupport implements CallbackFilter {

		private static final Log logger = LogFactory.getLog(MethodOverrideCallbackFilter.class);

		public MethodOverrideCallbackFilter(RootBeanDefinition beanDefinition) {
			super(beanDefinition);
		}

		@Override
		public int accept(Method method) {
			MethodOverride methodOverride = getBeanDefinition().getMethodOverrides().getOverride(method);
			if (logger.isTraceEnabled()) {
				logger.trace("Override for '" + method.getName() + "' is [" + methodOverride + "]");
			}
			if (methodOverride == null) {
				return PASSTHROUGH;
			}
			else if (methodOverride instanceof LookupOverride) {
				return LOOKUP_OVERRIDE;
			}
			else if (methodOverride instanceof ReplaceOverride) {
				return METHOD_REPLACER;
			}
			throw new UnsupportedOperationException("Unexpected MethodOverride subclass: " +
					methodOverride.getClass().getName());
		}
	}

回调类别

     enhancer.setCallbackTypes(CALLBACK_TYPES);   

对应着三种类的数组

		private static final Class[] CALLBACK_TYPES = new Class[]
				{NoOp.class, LookupOverrideMethodInterceptor.class, ReplaceOverrideMethodInterceptor.class};

其中有了两个拦截器。来实现方法替换

  • LookupOverrideMethodInterceptor 
  • ReplaceOverrideMethodInterceptor

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(源码,#,Spring源码)