首先说一点, 因为 Spring 中的对象默认为单例, 想要获取它默认 init_lazy 默认为 false.
下面的图是整个流程的流程图, 下面跟的源码解析就是按照这个流程来的.
至于基于 XML 依赖注入的过程, 首先要找一个比较合适的入口, 那就是 getBean. 那么具体是怎么实现的呢? 首先写个测试方法:
- ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("application-common.xml","application-beans.xml","application_jdbc.xml");
- Object obj = app.getBean("member");
第一句在我上篇文章 ---Spring-BeanFactory 基本工作流程中就用到了, 主要是作为一个初始化 IOC 容器的入口, 那么我们现在的场景是: IOC 容器已经创建好, 我们在 XML 文件中配置的信息已经加载到 BeanDefinition 中了, 那么我们现在的目的就是去获得它. 第二句就是我们本篇文章的入口: getBean.
- @Override
- public Object getBean(String name) throws BeansException {
- assertBeanFactoryActive();
- return getBeanFactory().getBean(name);
- }
首先执行的是 assertBeanFactoryActive 方法, 本人在上一篇分析 Spring 源码的时候就已经赞誉过 Spring 方法的命名, 我们可以通过这个名字来判断它到底有什么意思, 首先说明它是一个断言方法, 然后判断的事 BeanFactory 是不是 Active 的, 如果不是就直接抛异常了.
- protected void assertBeanFactoryActive() {
- if (!this.active.get()) {
- if (this.closed.get()) {
- throw new IllegalStateException(getDisplayName() + "has been closed already");
- }
- else {
- throw new IllegalStateException(getDisplayName() + "has not been refreshed yet");
- }
- }
- }
然后我们接着看 getBean 方法, 可以看到, 它会调 getBeanFactory 方法, 他返回的是一个 BeanFactory, 然后调 BeanFactory 中的 getBean 方法:
在之前的文章中提到过, Spring 中做实事的方法都是以 do 开头的, 我们可以看到, 在 getBean 方法中调用了一个 doGetBean 方法, 看名字可以了解到是真正拿到 Bean 的方法, 在 doGetBean 方法中, 首先先将我们传进来的指定的名字转化为管理 Bean 的名字, 然后再创建一个名为 bean 的 Object 对象, 作为我们要返回的实例. 由于我们依赖注入的对象为单例, 所以我们要做的就是首先在 cache 中检查有没有已经创建好的实例.(Spring 中从 BeanDefinition 创建的 Bean 不是存放在 IOC 中, 而是存放在 Cache 容器中, IOC 只是存放 Bean 关系), 如果有 Bean 存在, 就直接返回, 如果 Cache 中没有这个 Bean, 那么就要创建它.
在我们要自己创建 Bean 的时候, 首先先检查这个 Bean 有没有相关的 BeanDefinition, 首先要解析出 Bean 的原始名称, 然后现在当前 BeanFactory 里检查, 如果没有, 就去父 BeanFactory 里面找, 如果还是找不到则沿着容器的继承体系向父级容器查找. 当当前容器的父亲容器存在而且在当前容器中找不到这个 bean 时, 就开始在父容器里找, 会找父级 BeanFactory 的 getBean 方法.
如果在当前的 Bean 里面有, 则首先向容器中标记这个 Bean 已经被创建了, 然后根据指定 Bean 名称获取其父级的 Bean 定义, 主要解决 Bean 继承时子类合并父类公共属性问题. 接着获取该 Bean 所有依赖 Bean 的名称, 如果有依赖 Bean 存在, 那么就递归获取依赖 Bean, 并将依赖 Bean 注册给当前的 Bean.
针对于 Bean 的类型(单例还是原型),Spring 在创建 Bean 的过程都不一样, 先看如果创建单例 Bean 的方法, 首先看一下 Spring 在这是怎么处理的, 它先使用一个内部匿名类, 就是一个 SingletonFactory 类, 然后将 Bean 实际名, Bean 的 BeanDefinition 和 Bean 参数传入 createBean 方法(在下面会分析细节分析这个方法, 这边只是大致过一下 doGetBean 方法). 并返回创建出的 Bean 实例. 同样的, 如果是一个原型 Bean, 因为每次都会建立一个新的实例, 然后将获得的实例返回给之前创建的 bean. 如果 Bean 既不是单例, 也不是原型的话, 那么就要根据 Bean 定义资源中配置的生命周期范围来选择合适的实例化 Bean 方法(这种情况出现在 web 那块比较多, 如 session,reques 等).
最后要对创建好的 Bean 进行检查, 如果符合规范, 就认为创建好了并且返回.
- //AbstractBeanFactory.class
- // 获取 IOC 容器中指定名称的 Bean
- @Override
- public Object getBean(String name) throws BeansException {
- //doGetBean 才是真正向 IoC 容器获取被管理 Bean 的过程
- return doGetBean(name, null, null, false);
- }
- 1
- // 真正实现向 IOC 容器获取 Bean 的功能, 也是触发依赖注入功能的地方
- protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
- @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
- // 根据指定的名称获取被管理 Bean 的名称, 剥离指定名称中对容器的相关依赖
- // 如果指定的是别名, 将别名转换为规范的 Bean 名称
- final String beanName = transformedBeanName(name);
- Object bean;
- // Eagerly check singleton cache for manually registered singletons.
- // 先从缓存中取是否已经有被创建过的单态类型的 Bean
- // 对于单例模式的 Bean 整个 IOC 容器中只创建一次, 不需要重复创建
- Object sharedInstance = getSingleton(beanName);
- //IOC 容器创建单例模式 Bean 实例对象
- if (sharedInstance != null && args == null) {
- if (logger.isDebugEnabled()) {
- // 如果指定名称的 Bean 在容器中已有单例模式的 Bean 被创建
- // 直接返回已经创建的 Bean
- if (isSingletonCurrentlyInCreation(beanName)) {
- logger.debug("Returning eagerly cached instance of singleton bean'" + beanName +
- "'that is not fully initialized yet - a consequence of a circular reference");
- }
- else {
- logger.debug("Returning cached instance of singleton bean'" + beanName + "'");
- }
- }
- // 获取给定 Bean 的实例对象, 主要是完成 FactoryBean 的相关处理
- // 注意: BeanFactory 是管理容器中 Bean 的工厂, 而 FactoryBean 是
- // 创建创建对象的工厂 Bean, 两者之间有区别
- bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
- }
- else {
- // Fail if we're already creating this bean instance:
- // We're assumably within a circular reference.
- // 缓存没有正在创建的单例模式 Bean
- // 缓存中已经有已经创建的原型模式 Bean
- // 但是由于循环引用的问题导致实例化对象失败
- if (isPrototypeCurrentlyInCreation(beanName)) {
- throw new BeanCurrentlyInCreationException(beanName);
- }
- // Check if bean definition exists in this factory.
- // 对 IOC 容器中是否存在指定名称的 BeanDefinition 进行检查, 首先检查是否
- // 能在当前的 BeanFactory 中获取的所需要的 Bean, 如果不能则委托当前容器
- // 的父级容器去查找, 如果还是找不到则沿着容器的继承体系向父级容器查找
- BeanFactory parentBeanFactory = getParentBeanFactory();
- // 当前容器的父级容器存在, 且当前容器中不存在指定名称的 Bean
- if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
- // Not found -> check parent.
- // 解析指定 Bean 名称的原始名称
- String nameToLookup = originalBeanName(name);
- if (parentBeanFactory instanceof AbstractBeanFactory) {
- return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
- nameToLookup, requiredType, args, typeCheckOnly);
- }
- else if (args != null) {
- // Delegation to parent with explicit args.
- // 委派父级容器根据指定名称和显式的参数查找
- return (T) parentBeanFactory.getBean(nameToLookup, args);
- }
- else {
- // No args -> delegate to standard getBean method.
- // 委派父级容器根据指定名称和类型查找
- return parentBeanFactory.getBean(nameToLookup, requiredType);
- }
- }
- // 创建的 Bean 是否需要进行类型验证, 一般不需要
- if (!typeCheckOnly) {
- // 向容器标记指定的 Bean 已经被创建
- markBeanAsCreated(beanName);
- }
- try {
- // 根据指定 Bean 名称获取其父级的 Bean 定义
- // 主要解决 Bean 继承时子类合并父类公共属性问题
- final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
- checkMergedBeanDefinition(mbd, beanName, args);
- // Guarantee initialization of beans that the current bean depends on.
- // 获取当前 Bean 所有依赖 Bean 的名称
- String[] dependsOn = mbd.getDependsOn();
- // 如果当前 Bean 有依赖 Bean
- if (dependsOn != null) {
- for (String dep : dependsOn) {
- if (isDependent(beanName, dep)) {
- throw new BeanCreationException(mbd.getResourceDescription(), beanName,
- "Circular depends-on relationship between'" + beanName + "'and'" + dep + "'");
- }
- // 递归调用 getBean 方法, 获取当前 Bean 的依赖 Bean
- registerDependentBean(dep, beanName);
- // 把被依赖 Bean 注册给当前依赖的 Bean
- getBean(dep);
- }
- }
- // Create bean instance.
- // 创建单例模式 Bean 的实例对象
- if (mbd.isSingleton()) {
- // 这里使用了一个匿名内部类, 创建 Bean 实例对象, 并且注册给所依赖的对象
- sharedInstance = getSingleton(beanName, () -> {
- try {
- // 创建一个指定 Bean 实例对象, 如果有父级继承, 则合并子类和父类的定义
- return createBean(beanName, mbd, args);
- }
- catch (BeansException ex) {
- // Explicitly remove instance from singleton cache: It might have been put there
- // eagerly by the creation process, to allow for circular reference resolution.
- // Also remove any beans that received a temporary reference to the bean.
- // 显式地从容器单例模式 Bean 缓存中清除实例对象
- destroySingleton(beanName);
- throw ex;
- }
- });
- // 获取给定 Bean 的实例对象
- bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
- }
- //IOC 容器创建原型模式 Bean 实例对象
- else if (mbd.isPrototype()) {
- // It's a prototype -> create a new instance.
- // 原型模式 (Prototype) 是每次都会创建一个新的对象
- Object prototypeInstance = null;
- try {
- // 回调 beforePrototypeCreation 方法, 默认的功能是注册当前创建的原型对象
- beforePrototypeCreation(beanName);
- // 创建指定 Bean 对象实例
- prototypeInstance = createBean(beanName, mbd, args);
- }
- finally {
- // 回调 afterPrototypeCreation 方法, 默认的功能告诉 IOC 容器指定 Bean 的原型对象不再创建
- afterPrototypeCreation(beanName);
- }
- // 获取给定 Bean 的实例对象
- bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
- }
- // 要创建的 Bean 既不是单例模式, 也不是原型模式, 则根据 Bean 定义资源中
- // 配置的生命周期范围, 选择实例化 Bean 的合适方法, 这种在 Web 应用程序中
- // 比较常用, 如: request,session,application 等生命周期
- else {
- String scopeName = mbd.getScope();
- final Scope scope = this.scopes.get(scopeName);
- //Bean 定义资源中没有配置生命周期范围, 则 Bean 定义不合法
- if (scope == null) {
- throw new IllegalStateException("No Scope registered for scope name'" + scopeName + "'");
- }
- try {
- // 这里又使用了一个匿名内部类, 获取一个指定生命周期范围的实例
- Object scopedInstance = scope.get(beanName, () -> {
- beforePrototypeCreation(beanName);
- try {
- return createBean(beanName, mbd, args);
- }
- finally {
- afterPrototypeCreation(beanName);
- }
- });
- // 获取给定 Bean 的实例对象
- bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
- }
- catch (IllegalStateException ex) {
- throw new BeanCreationException(beanName,
- "Scope'" + scopeName + "'is not active for the current thread; consider" +
- "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
- ex);
- }
- }
- }
- catch (BeansException ex) {
- cleanupAfterBeanCreationFailure(beanName);
- throw ex;
- }
- }
- // Check if required type matches the type of the actual bean instance.
- // 对创建的 Bean 实例对象进行类型检查
- if (requiredType != null && !requiredType.isInstance(bean)) {
- try {
- T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
- if (convertedBean == null) {
- throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
- }
- return convertedBean;
- }
- catch (TypeMismatchException ex) {
- if (logger.isDebugEnabled()) {
- logger.debug("Failed to convert bean'" + name + "'to required type'" +
- ClassUtils.getQualifiedName(requiredType) + "'", ex);
- }
- throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
- }
- }
- return (T) bean;
- }
上面比较详细的介绍了 Bean 实例是如何创建的, 那么接下来主要是重点分析一下几个比较重要的方法的细节. 先说一下如果 Cache 容器中有之前已经创建过的该 Bean 的实例, 在 31 行, 我们进入 getObjectForBeanInstance 方法.
我们已经拿到了在 Cache 中拿到了该 Bean 的 FactoryBean, 在这说一下 FactoryBean 和 BeanFactory 的区别, FactoryBean 是用来创建生产 Bean 的工厂的 Bean(有点绕)而 BeanFactory 是管理 Bean 的工厂. 然后进入 getObjectForBeanInstance 方法, 首先我们会去判断这个 Bean 是不是一个工厂 Bean, 如果不是工厂 Bean, 或者说我们想要得到的就是一个工厂, 那么就直接返回它. 如果是工厂 Bean 并且我们要得到的是一个 Bean 实例, 那么首先看一下工厂 Bean 的缓存中有木有实例, 如果有就返回, 如果没有, 就会调用 getObjectFromFactoryBean 方法来获得 Bean 实例.
- protected Object getObjectForBeanInstance(
- Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
- // Don't let calling code try to dereference the factory if the bean isn't a factory.
- // 容器已经得到了 Bean 实例对象, 这个实例对象可能是一个普通的 Bean,
- // 也可能是一个工厂 Bean, 如果是一个工厂 Bean, 则使用它创建一个 Bean 实例对象,
- // 如果调用本身就想获得一个容器的引用, 则指定返回这个工厂 Bean 实例对象
- // 如果指定的名称是容器的解引用(dereference, 即是对象本身而非内存地址),
- // 且 Bean 实例也不是创建 Bean 实例对象的工厂 Bean
- if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
- throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
- }
- // Now we have the bean instance, which may be a normal bean or a FactoryBean.
- // If it's a FactoryBean, we use it to create a bean instance, unless the
- // caller actually wants a reference to the factory.
- // 如果 Bean 实例不是工厂 Bean, 或者指定名称是容器的解引用,
- // 调用者向获取对容器的引用, 则直接返回当前的 Bean 实例
- if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
- return beanInstance;
- }
- // 处理指定名称不是容器的解引用, 或者根据名称获取的 Bean 实例对象是一个工厂 Bean
- // 使用工厂 Bean 创建一个 Bean 的实例对象
- Object object = null;
- if (mbd == null) {
- // 从 Bean 工厂缓存中获取给定名称的 Bean 实例对象
- object = getCachedObjectForFactoryBean(beanName);
- }
- // 让 Bean 工厂生产给定名称的 Bean 对象实例
- if (object == null) {
- // Return bean instance from factory.
- FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
- // Caches object obtained from FactoryBean if it is a singleton.
- // 如果从 Bean 工厂生产的 Bean 是单态模式的, 则缓存
- if (mbd == null && containsBeanDefinition(beanName)) {
- // 从容器中获取指定名称的 Bean 定义, 如果继承基类, 则合并基类相关属性
- mbd = getMergedLocalBeanDefinition(beanName);
- }
- // 如果从容器得到 Bean 定义信息, 并且 Bean 定义信息不是虚构的,
- // 则让工厂 Bean 生产 Bean 实例对象
- boolean synthetic = (mbd != null && mbd.isSynthetic());
- // 调用 FactoryBeanRegistrySupport 类的 getObjectFromFactoryBean 方法,
- // 实现工厂 Bean 生产 Bean 对象实例的过程
- object = getObjectFromFactoryBean(factory, beanName, !synthetic);
- }
- return object;
- }
接下来我们看一看是怎么从 FactoryBean 里拿到 Bean 实例的, 先进入 getObjectFromFactoryBean 方法.
- //Bean 工厂生产 Bean 实例对象
- protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
- //Bean 工厂是单态模式, 并且 Bean 工厂缓存中存在指定名称的 Bean 实例对象
- if (factory.isSingleton() && containsSingleton(beanName)) {
- // 多线程同步, 以防止数据不一致
- synchronized (getSingletonMutex()) {
- // 直接从 Bean 工厂缓存中获取指定名称的 Bean 实例对象
- Object object = this.factoryBeanObjectCache.get(beanName);
- //Bean 工厂缓存中没有指定名称的实例对象, 则生产该实例对象
- if (object == null) {
- // 调用 Bean 工厂的 getObject 方法生产指定 Bean 的实例对象
- object = doGetObjectFromFactoryBean(factory, beanName);
- // Only post-process and store if not put there already during getObject() call above
- // (e.g. because of circular reference processing triggered by custom getBean calls)
- Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
- if (alreadyThere != null) {
- object = alreadyThere;
- }
- else {
- if (shouldPostProcess) {
- try {
- object = postProcessObjectFromFactoryBean(object, beanName);
- }
- catch (Throwable ex) {
- throw new BeanCreationException(beanName,
- "Post-processing of FactoryBean's singleton object failed", ex);
- }
- }
- // 将生产的实例对象添加到 Bean 工厂缓存中
- this.factoryBeanObjectCache.put(beanName, object);
- }
- }
- return object;
- }
- }
- // 调用 Bean 工厂的 getObject 方法生产指定 Bean 的实例对象
- else {
- Object object = doGetObjectFromFactoryBean(factory, beanName);
- if (shouldPostProcess) {
- try {
- object = postProcessObjectFromFactoryBean(object, beanName);
- }
- catch (Throwable ex) {
- throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
- }
- }
- return object;
- }
- }
由于我们现在创建的 Bean 为单例模式, 所以要保证线程安全, 首先先判断在 FactoryBean 里有没有该 Bean 的缓存, 如果没有就自己创建, 方法为 doGetBeanFromFactoryBean, 并且将创建好的 Bean 存到 Cache 里. 那么我们到现在又看到了一个做实事的方法, 看名字这个方法应该是生产 Bean 的方法.
- // 调用 Bean 工厂的 getObject 方法生产指定 Bean 的实例对象
- private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
- throws BeanCreationException {
- Object object;
- try {
- if (System.getSecurityManager() != null) {
- AccessControlContext acc = getAccessControlContext();
- try {
- // 实现 PrivilegedExceptionAction 接口的匿名内置类
- // 根据 JVM 检查权限, 然后决定 BeanFactory 创建实例对象
- object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () ->
- factory.getObject(), acc);
- }
- catch (PrivilegedActionException pae) {
- throw pae.getException();
- }
- }
- else {
- // 调用 BeanFactory 接口实现类的创建对象方法
- object = factory.getObject();
- }
- }
- catch (FactoryBeanNotInitializedException ex) {
- throw new BeanCurrentlyInCreationException(beanName, ex.toString());
- }
- catch (Throwable ex) {
- throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
- }
- // Do not accept a null value for a FactoryBean that's not fully
- // initialized yet: Many FactoryBeans just return null then.
- // 创建出来的实例对象为 null, 或者因为单态对象正在创建而返回 null
- if (object == null) {
- if (isSingletonCurrentlyInCreation(beanName)) {
- throw new BeanCurrentlyInCreationException(
- beanName, "FactoryBean which is currently in creation returned null from getObject");
- }
- object = new NullBean();
- }
- return object;
- }
通过这个方法, 我们就得到了单例 Bean 的实例(不管它有没有在 Cache 里存在).
同样, 如果缓存中没有被创建的 Bean, 那么在之前那段代码中(doGetBean), 就不会走 31 行那一块, 而是接着往下走, 到 101 行, 执行到 createBean 方法, 这里用到了 lamda 表达式, new 了一个内部类 objectFactory.
- //AbstractAutowireCapableBeanFactory.class
- // 创建 Bean 实例对象
- @Override
- protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
- throws BeanCreationException {
- if (logger.isDebugEnabled()) {
- logger.debug("Creating instance of bean'" + beanName + "'");
- }
- RootBeanDefinition mbdToUse = mbd;
- // Make sure bean class is actually resolved at this point, and
- // clone the bean definition in case of a dynamically resolved Class
- // which cannot be stored in the shared merged bean definition.
- // 判断需要创建的 Bean 是否可以实例化, 即是否可以通过当前的类加载器加载
- Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
- if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
- mbdToUse = new RootBeanDefinition(mbd);
- mbdToUse.setBeanClass(resolvedClass);
- }
- // Prepare method overrides.
- // 校验和准备 Bean 中的方法覆盖
- try {
- mbdToUse.prepareMethodOverrides();
- }
- catch (BeanDefinitionValidationException ex) {
- throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
- beanName, "Validation of method overrides failed", ex);
- }
- try {
- // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
- // 如果 Bean 配置了初始化前和初始化后的处理器, 则试图返回一个需要创建 Bean 的代理对象
- Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
- if (bean != null) {
- return bean;
- }
- }
- catch (Throwable ex) {
- throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
- "BeanPostProcessor before instantiation of bean failed", ex);
- }
- try {
- // 创建 Bean 的入口
- Object beanInstance = doCreateBean(beanName, mbdToUse, args);
- if (logger.isDebugEnabled()) {
- logger.debug("Finished creating instance of bean'" + beanName + "'");
- }
- return beanInstance;
- }
- catch (BeanCreationException ex) {
- // A previously detected exception with proper bean creation context already...
- throw ex;
- }
- catch (ImplicitlyAppearedSingletonException ex) {
- // An IllegalStateException to be communicated up to DefaultSingletonBeanRegistry...
- throw ex;
- }
- catch (Throwable ex) {
- throw new BeanCreationException(
- mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
- }
- }
在这里, 会调用 doCreateBean 方法
- //AbstractAutowireCapableBeanFactory.class
- // 真正创建 Bean 的方法
- protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
- throws BeanCreationException {
- // Instantiate the bean.
- // 封装被创建的 Bean 对象
- BeanWrapper instanceWrapper = null;
- if (mbd.isSingleton()) {
- instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
- }
- if (instanceWrapper == null) {
- instanceWrapper = createBeanInstance(beanName, mbd, args);
- }
- final Object bean = instanceWrapper.getWrappedInstance();
- // 获取实例化对象的类型
- Class<?> beanType = instanceWrapper.getWrappedClass();
- if (beanType != NullBean.class) {
- mbd.resolvedTargetType = beanType;
- }
- // Allow post-processors to modify the merged bean definition.
- // 调用 PostProcessor 后置处理器
- synchronized (mbd.postProcessingLock) {
- if (!mbd.postProcessed) {
- try {
- applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
- }
- catch (Throwable ex) {
- throw new BeanCreationException(mbd.getResourceDescription(), beanName,
- "Post-processing of merged bean definition failed", ex);
- }
- mbd.postProcessed = true;
- }
- }
- // Eagerly cache singletons to be able to resolve circular references
- // even when triggered by lifecycle interfaces like BeanFactoryAware.
- // 向容器中缓存单例模式的 Bean 对象, 以防循环引用
- boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
- isSingletonCurrentlyInCreation(beanName));
- if (earlySingletonExposure) {
- if (logger.isDebugEnabled()) {
- logger.debug("Eagerly caching bean'" + beanName +
- "'to allow for resolving potential circular references");
- }
- // 这里是一个匿名内部类, 为了防止循环引用, 尽早持有对象的引用
- addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
- }
- // Initialize the bean instance.
- //Bean 对象的初始化, 依赖注入在此触发
- // 这个 exposedObject 在初始化完成之后返回作为依赖注入完成后的 Bean
- Object exposedObject = bean;
- try {
- // 将 Bean 实例对象封装, 并且 Bean 定义中配置的属性值赋值给实例对象
- populateBean(beanName, mbd, instanceWrapper);
- // 初始化 Bean 对象
- exposedObject = initializeBean(beanName, exposedObject, mbd);
- }
- catch (Throwable ex) {
- if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
- throw (BeanCreationException) ex;
- }
- else {
- throw new BeanCreationException(
- mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
- }
- }
- if (earlySingletonExposure) {
- // 获取指定名称的已注册的单例模式 Bean 对象
- Object earlySingletonReference = getSingleton(beanName, false);
- if (earlySingletonReference != null) {
- // 根据名称获取的已注册的 Bean 和正在实例化的 Bean 是同一个
- if (exposedObject == bean) {
- // 当前实例化的 Bean 初始化完成
- exposedObject = earlySingletonReference;
- }
- // 当前 Bean 依赖其他 Bean, 并且当发生循环引用时不允许新创建实例对象
- else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
- String[] dependentBeans = getDependentBeans(beanName);
- Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
- // 获取当前 Bean 所依赖的其他 Bean
- for (String dependentBean : dependentBeans) {
- // 对依赖 Bean 进行类型检查
- if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
- actualDependentBeans.add(dependentBean);
- }
- }
- if (!actualDependentBeans.isEmpty()) {
- throw new BeanCurrentlyInCreationException(beanName,
- "Bean with name'" + beanName + "'has been injected into other beans [" +
- StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
- "] in its raw version as part of a circular reference, but has eventually been" +
- "wrapped. This means that said other beans do not use the final version of the" +
- "bean. This is often the result of over-eager type matching - consider using" +
- "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
- }
- }
- }
- }
- // Register bean as disposable.
- // 注册完成依赖注入的 Bean
- try {
- registerDisposableBeanIfNecessary(beanName, bean, mbd);
- }
- catch (BeanDefinitionValidationException ex) {
- throw new BeanCreationException(
- mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
- }
- return exposedObject;
- }
这里首先创建一个包装类, 用到了 BeanWrapper https://blog.csdn.net/zhiweianran/article/details/7919129 来包装 Bean, 然后到 createBeanInstance 方法使得生成一个 Bean 的 Wrapper 类. 并保证容器缓存中有此 Bean 对象的单例模式. 然后调用 populateBean 方法, 将 BeanDefinition 的属性赋值给实例对象, 并调用 initializeBean 方法初始化 Bean 对象. 并对 Bean 对象进行一系列的检查, 然后返回生成的 Bean.
首先我们先看一下 createBeanInstance 方法, 这个方法返回的是一个 BeanWrapper 对象, 首先确定 Bean 是可以实例化的, 然后就对 Bean 进行实例化. 实例化的方法有三种:(1)工厂方法 (2)容器自动装配 (3)Bean 的构造方法
- protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
- // Make sure bean class is actually resolved at this point.
- // 检查确认 Bean 是可实例化的
- Class<?> beanClass = resolveBeanClass(mbd, beanName);
- // 使用工厂方法对 Bean 进行实例化
- if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
- throw new BeanCreationException(mbd.getResourceDescription(), beanName,
- "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
- }
- Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
- if (instanceSupplier != null) {
- return obtainFromSupplier(instanceSupplier, beanName);
- }
- if (mbd.getFactoryMethodName() != null) {
- // 调用工厂方法实例化
- return instantiateUsingFactoryMethod(beanName, mbd, args);
- }
- // Shortcut when re-creating the same bean...
- // 使用容器的自动装配方法进行实例化
- boolean resolved = false;
- boolean autowireNecessary = false;
- if (args == null) {
- synchronized (mbd.constructorArgumentLock) {
- if (mbd.resolvedConstructorOrFactoryMethod != null) {
- resolved = true;
- autowireNecessary = mbd.constructorArgumentsResolved;
- }
- }
- }
- if (resolved) {
- if (autowireNecessary) {
- // 配置了自动装配属性, 使用容器的自动装配实例化
- // 容器的自动装配是根据参数类型匹配 Bean 的构造方法
- return autowireConstructor(beanName, mbd, null, null);
- }
- else {
- // 使用默认的无参构造方法实例化
- return instantiateBean(beanName, mbd);
- }
- }
- // Need to determine the constructor...
- // 使用 Bean 的构造方法进行实例化
- Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
- if (ctors != null ||
- mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
- mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
- // 使用容器的自动装配特性, 调用匹配的构造方法实例化
- return autowireConstructor(beanName, mbd, ctors, args);
- }
- // No special handling: simply use no-arg constructor.
- // 使用默认的无参构造方法实例化
- return instantiateBean(beanName, mbd);
- }
首先是工厂方法实例化 Bean, 调用的是 instantiateUsingFactoryMethod 方法, 这边不详细分析了.
之后是使用容器自动装配来进行实例化, 如果匹配了自动装配属性, 那么久使用容器自动装配实例化, 如果没有, 则用构造方法进行实例化, 这里说一下用构造方法进行实例化的过程
无参构造方法 instantiateBean 方法, 这里就是实例 Bean 的方法.
- // 使用默认的无参构造方法实例化 Bean 对象
- protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
- try {
- Object beanInstance;
- final BeanFactory parent = this;
- // 获取系统的安全管理接口, JDK 标准的安全管理 API
- if (System.getSecurityManager() != null) {
- // 这里是一个匿名内置类, 根据实例化策略创建实例对象
- beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
- getInstantiationStrategy().instantiate(mbd, beanName, parent),
- getAccessControlContext());
- }
- else {
- // 将实例化的对象封装起来
- beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
- }
- BeanWrapper bw = new BeanWrapperImpl(beanInstance);
- initBeanWrapper(bw);
- return bw;
- }
- catch (Throwable ex) {
- throw new BeanCreationException(
- mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
- }
- }
首先实例对象, 用到的是 instantiate 方法, 然后再将其包装成 BeanWrapper
然后到 instantiate 方法.
- // 使用初始化策略实例化 Bean 对象
- @Override
- public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
- // Don't override the class with CGLIB if no overrides.
- // 如果 Bean 定义中没有方法覆盖, 则就不需要 CGLIB 父类类的方法
- if (!bd.hasMethodOverrides()) {
- Constructor<?> constructorToUse;
- synchronized (bd.constructorArgumentLock) {
- // 获取对象的构造方法或工厂方法
- constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
- // 如果没有构造方法且没有工厂方法
- if (constructorToUse == null) {
- // 使用 JDK 的反射机制, 判断要实例化的 Bean 是否是接口
- final Class<?> clazz = bd.getBeanClass();
- if (clazz.isInterface()) {
- throw new BeanInstantiationException(clazz, "Specified class is an interface");
- }
- try {
- if (System.getSecurityManager() != null) {
- // 这里是一个匿名内置类, 使用反射机制获取 Bean 的构造方法
- 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);
- }
- }
- }
- // 使用 BeanUtils 实例化, 通过反射机制调用 "构造方法. newInstance(arg)" 来进行实例化
- return BeanUtils.instantiateClass(constructorToUse);
- }
- else {
- // Must generate CGLIB subclass.
- // 使用 CGLIB 来实例化对象
- return instantiateWithMethodInjection(bd, beanName, owner);
- }
- }
首先检查 Bean 中有没有覆盖父类方法, 如果没有的话, 就不用 CGLIB 父类类的方法, 然后通过反射获得 Bean 的构造方法, 之后通过 BeanUtils 使用构造方法进行实例化. 如果有覆盖方法, 那么就要使用 CGLIB 来进行实例化
然后调用 instantiateWithMethodInjection 方法
- @Override
- protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
- return instantiateWithMethodInjection(bd, beanName, owner, null);
- }
- @Override
- protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
- @Nullable Constructor<?> ctor, @Nullable Object... args) {
- // Must generate CGLIB subclass...
- return new CglibSubclassCreator(bd, owner).instantiate(ctor, args);
- }
到这里可以看到调用使用 CGLIB 的 instantiate 方法.
- public Object instantiate(@Nullable Constructor<?> ctor, @Nullable Object... args) {
- // 创建代理子类
- Class<?> subclass = createEnhancedSubclass(this.beanDefinition);
- Object instance;
- if (ctor == null) {
- instance = BeanUtils.instantiateClass(subclass);
- }
- else {
- try {
- 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;
- factory.setCallbacks(new Callback[] {NoOp.INSTANCE,
- new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),
- new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});
- return instance;
- }
然后调用 instantiateClass 方法
- public static <T> T instantiateClass(Class<T> clazz) throws BeanInstantiationException {
- Assert.notNull(clazz, "Class must not be null");
- if (clazz.isInterface()) {
- throw new BeanInstantiationException(clazz, "Specified class is an interface");
- }
- try {
- Constructor<T> ctor = (KotlinDetector.isKotlinType(clazz) ?
- KotlinDelegate.findPrimaryConstructor(clazz) : clazz.getDeclaredConstructor());
- if (ctor == null) {
- throw new BeanInstantiationException(clazz, "No default constructor found");
- }
- return instantiateClass(ctor);
- }
- catch (NoSuchMethodException ex) {
- throw new BeanInstantiationException(clazz, "No default constructor found", ex);
- }
- }
- 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.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());
- }
- }
回到 instantiateBean 方法, 我们得到了实例化的 Bean 对象, 那么接下来就是将他封装起来. 调用了 BeanWrapperImpl 的构造方法, 并初始化这个 BeanWrapper 然后将其返回.
之后回到 createBeanInstance 方法, 刚才介绍的是用无参构造函数方法将其进行实例化封装, 接下来如果有参数, 那么就会使用容器的自动装配特性, 调用匹配的构造方法进行实例化.
再回到之前调用 createBeanInstance 方法的时候, 也就是在 AbstractAutowireCapableBeanFactory 这个类里的 doCreateBean 方法中, 会调用 populateBean 方法, 这里就是真正的依赖注入.
- // 将 Bean 属性设置到生成的实例对象上
- protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
- if (bw == null) {
- if (mbd.hasPropertyValues()) {
- throw new BeanCreationException(
- mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
- }
- else {
- // Skip property population phase for null instance.
- return;
- }
- }
- // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
- // state of the bean before properties are set. This can be used, for example,
- // to support styles of field injection.
- boolean continueWithPropertyPopulation = true;
- if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
- for (BeanPostProcessor bp : getBeanPostProcessors()) {
- if (bp instanceof InstantiationAwareBeanPostProcessor) {
- InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
- if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
- continueWithPropertyPopulation = false;
- break;
- }
- }
- }
- }
- if (!continueWithPropertyPopulation) {
- return;
- }
- // 获取容器在解析 Bean 定义资源时为 BeanDefiniton 中设置的属性值
- PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
- // 对依赖注入处理, 首先处理 autowiring 自动装配的依赖注入
- if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
- mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
- MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
- // Add property values based on autowire by name if applicable.
- // 根据 Bean 名称进行 autowiring 自动装配处理
- if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
- autowireByName(beanName, mbd, bw, newPvs);
- }
- // Add property values based on autowire by type if applicable.
- // 根据 Bean 类型进行 autowiring 自动装配处理
- if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
- autowireByType(beanName, mbd, bw, newPvs);
- }
- pvs = newPvs;
- }
- // 对非 autowiring 的属性进行依赖注入处理
- boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
- boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
- if (hasInstAwareBpps || needsDepCheck) {
- if (pvs == null) {
- pvs = mbd.getPropertyValues();
- }
- PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
- if (hasInstAwareBpps) {
- for (BeanPostProcessor bp : getBeanPostProcessors()) {
- if (bp instanceof InstantiationAwareBeanPostProcessor) {
- InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
- pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
- if (pvs == null) {
- return;
- }
- }
- }
- }
- if (needsDepCheck) {
- checkDependencies(beanName, mbd, filteredPds, pvs);
- }
- }
- if (pvs != null) {
- // 对属性进行注入
- applyPropertyValues(beanName, mbd, bw, pvs);
- }
- }
首先会检查这个包装类是否为空, 在保证不为空的前提下, 首先获取 BeanDefinition 中的资源属性值, 然后对其进行自动装配处理, 最后对属性进行注入.
在 populateBean 方法的最后, 会对属性进行注入, 调用 applyPropertyValues 方法
- // 解析并注入依赖属性的过程
- protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
- if (pvs.isEmpty()) {
- return;
- }
- // 封装属性值
- MutablePropertyValues mpvs = null;
- List<PropertyValue> original;
- if (System.getSecurityManager() != null) {
- if (bw instanceof BeanWrapperImpl) {
- // 设置安全上下文, JDK 安全机制
- ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
- }
- }
- if (pvs instanceof MutablePropertyValues) {
- mpvs = (MutablePropertyValues) pvs;
- // 属性值已经转换
- if (mpvs.isConverted()) {
- // Shortcut: use the pre-converted values as-is.
- try {
- // 为实例化对象设置属性值
- bw.setPropertyValues(mpvs);
- return;
- }
- catch (BeansException ex) {
- throw new BeanCreationException(
- mbd.getResourceDescription(), beanName, "Error setting property values", ex);
- }
- }
- // 获取属性值对象的原始类型值
- original = mpvs.getPropertyValueList();
- }
- else {
- original = Arrays.asList(pvs.getPropertyValues());
- }
- // 获取用户自定义的类型转换
- TypeConverter converter = getCustomTypeConverter();
- if (converter == null) {
- converter = bw;
- }
- // 创建一个 Bean 定义属性值解析器, 将 Bean 定义中的属性值解析为 Bean 实例对象的实际值
- BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
- // Create a deep copy, resolving any references for values.
- // 为属性的解析值创建一个拷贝, 将拷贝的数据注入到实例对象中
- List<PropertyValue> deepCopy = new ArrayList<>(original.size());
- boolean resolveNecessary = false;
- for (PropertyValue pv : original) {
- // 属性值不需要转换
- if (pv.isConverted()) {
- deepCopy.add(pv);
- }
- // 属性值需要转换
- else {
- String propertyName = pv.getName();
- // 原始的属性值, 即转换之前的属性值
- Object originalValue = pv.getValue();
- // 转换属性值, 例如将引用转换为 IOC 容器中实例化对象引用
- Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
- // 转换之后的属性值
- Object convertedValue = resolvedValue;
- // 属性值是否可以转换
- boolean convertible = bw.isWritableProperty(propertyName) &&
- !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
- if (convertible) {
- // 使用用户自定义的类型转换器转换属性值
- convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
- }
- // Possibly store converted value in merged bean definition,
- // in order to avoid re-conversion for every created bean instance.
- // 存储转换后的属性值, 避免每次属性注入时的转换工作
- if (resolvedValue == originalValue) {
- if (convertible) {
- // 设置属性转换之后的值
- pv.setConvertedValue(convertedValue);
- }
- deepCopy.add(pv);
- }
- // 属性是可转换的, 且属性原始值是字符串类型, 且属性的原始类型值不是
- // 动态生成的字符串, 且属性的原始值不是集合或者数组类型
- else if (convertible && originalValue instanceof TypedStringValue &&
- !((TypedStringValue) originalValue).isDynamic() &&
- !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
- pv.setConvertedValue(convertedValue);
- // 重新封装属性的值
- deepCopy.add(pv);
- }
- else {
- resolveNecessary = true;
- deepCopy.add(new PropertyValue(pv, convertedValue));
- }
- }
- }
- if (mpvs != null && !resolveNecessary) {
- // 标记属性值已经转换过
- mpvs.setConverted();
- }
- // Set our (possibly massaged) deep copy.
- // 进行属性依赖注入
- try {
- bw.setPropertyValues(new MutablePropertyValues(deepCopy));
- }
- catch (BeansException ex) {
- throw new BeanCreationException(
- mbd.getResourceDescription(), beanName, "Error setting property values", ex);
- }
- }
在这里核心调用的是 resolveValueIfNecessary 方法, 将 BeanDefinition 里的一些属性解析出来, 通过反射 new 出来一个对象. BeanDefinition 相当于保存在内存中的配置文件, 保存着所有跟这个类属性相关的信息, 依赖注入就是把 BeanDefinition 这个信息读出来, 通过反射机制或者代理等机制创建对象. 一个 Bean 对应着一个 BeanDefinition
新创建的对象不会放在 IOC 容器里, 而是会存入到另外一个 cache 容器. IOC 容器存放的是一个关系.
- //BeanDefinitionValueResolver.class
- // 解析属性值, 对注入类型进行转换
- @Nullable
- public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
- // We must check each value to see whether it requires a runtime reference
- // to another bean to be resolved.
- // 对引用类型的属性进行解析
- if (value instanceof RuntimeBeanReference) {
- RuntimeBeanReference ref = (RuntimeBeanReference) value;
- // 调用引用类型属性的解析方法
- return resolveReference(argName, ref);
- }
- // 对属性值是引用容器中另一个 Bean 名称的解析
- else if (value instanceof RuntimeBeanNameReference) {
- String refName = ((RuntimeBeanNameReference) value).getBeanName();
- refName = String.valueOf(doEvaluate(refName));
- // 从容器中获取指定名称的 Bean
- if (!this.beanFactory.containsBean(refName)) {
- throw new BeanDefinitionStoreException(
- "Invalid bean name'" + refName + "'in bean reference for" + argName);
- }
- return refName;
- }
- // 对 Bean 类型属性的解析, 主要是 Bean 中的内部类
- else if (value instanceof BeanDefinitionHolder) {
- // Resolve BeanDefinitionHolder: contains BeanDefinition with name and aliases.
- BeanDefinitionHolder bdHolder = (BeanDefinitionHolder) value;
- return resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.getBeanDefinition());
- }
- else if (value instanceof BeanDefinition) {
- // Resolve plain BeanDefinition, without contained name: use dummy name.
- BeanDefinition bd = (BeanDefinition) value;
- String innerBeanName = "(inner bean)" + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR +
- ObjectUtils.getIdentityHexString(bd);
- return resolveInnerBean(argName, innerBeanName, bd);
- }
- // 对集合数组类型的属性解析
- else if (value instanceof ManagedArray) {
- // May need to resolve contained runtime references.
- ManagedArray array = (ManagedArray) value;
- // 获取数组的类型
- Class<?> elementType = array.resolvedElementType;
- if (elementType == null) {
- // 获取数组元素的类型
- String elementTypeName = array.getElementTypeName();
- if (StringUtils.hasText(elementTypeName)) {
- try {
- // 使用反射机制创建指定类型的对象
- elementType = ClassUtils.forName(elementTypeName, this.beanFactory.getBeanClassLoader());
- array.resolvedElementType = elementType;
- }
- catch (Throwable ex) {
- // Improve the message by showing the context.
- throw new BeanCreationException(
- this.beanDefinition.getResourceDescription(), this.beanName,
- "Error resolving array type for" + argName, ex);
- }
- }
- // 没有获取到数组的类型, 也没有获取到数组元素的类型
- // 则直接设置数组的类型为 Object
- else {
- elementType = Object.class;
- }
- }
- // 创建指定类型的数组
- return resolveManagedArray(argName, (List<?>) value, elementType);
- }
- // 解析 list 类型的属性值
- else if (value instanceof ManagedList) {
- // May need to resolve contained runtime references.
- return resolveManagedList(argName, (List<?>) value);
- }
- // 解析 set 类型的属性值
- else if (value instanceof ManagedSet) {
- // May need to resolve contained runtime references.
- return resolveManagedSet(argName, (Set<?>) value);
- }
- // 解析 map 类型的属性值
- else if (value instanceof ManagedMap) {
- // May need to resolve contained runtime references.
- return resolveManagedMap(argName, (Map<?, ?>) value);
- }
- // 解析 props 类型的属性值, props 其实就是 key 和 value 均为字符串的 map
- else if (value instanceof ManagedProperties) {
- Properties original = (Properties) value;
- // 创建一个拷贝, 用于作为解析后的返回值
- Properties copy = new Properties();
- original.forEach((propKey, propValue) -> {
- if (propKey instanceof TypedStringValue) {
- propKey = evaluate((TypedStringValue) propKey);
- }
- if (propValue instanceof TypedStringValue) {
- propValue = evaluate((TypedStringValue) propValue);
- }
- if (propKey == null || propValue == null) {
- throw new BeanCreationException(
- this.beanDefinition.getResourceDescription(), this.beanName,
- "Error converting Properties key/value pair for" + argName + ": resolved to null");
- }
- copy.put(propKey, propValue);
- });
- return copy;
- }
- // 解析字符串类型的属性值
- else if (value instanceof TypedStringValue) {
- // Convert value to target type here.
- TypedStringValue typedStringValue = (TypedStringValue) value;
- Object valueObject = evaluate(typedStringValue);
- try {
- // 获取属性的目标类型
- Class<?> resolvedTargetType = resolveTargetType(typedStringValue);
- if (resolvedTargetType != null) {
- // 对目标类型的属性进行解析, 递归调用
- return this.typeConverter.convertIfNecessary(valueObject, resolvedTargetType);
- }
- // 没有获取到属性的目标对象, 则按 Object 类型返回
- else {
- return valueObject;
- }
- }
- catch (Throwable ex) {
- // Improve the message by showing the context.
- throw new BeanCreationException(
- this.beanDefinition.getResourceDescription(), this.beanName,
- "Error converting typed String value for" + argName, ex);
- }
- }
- else if (value instanceof NullBean) {
- return null;
- }
- else {
- return evaluate(value);
- }
- }
同时, 在上个方法中(applyPropertyValues), 会调用到 bw.setPropertyValues 方法, 他的作用是为实例化的对象设置属性
- @Override
- public void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid)
- throws BeansException {
- List<PropertyAccessException> propertyAccessExceptions = null;
- List<PropertyValue> propertyValues = (pvs instanceof MutablePropertyValues ?
- ((MutablePropertyValues) pvs).getPropertyValueList() : Arrays.asList(pvs.getPropertyValues()));
- for (PropertyValue pv : propertyValues) {
- try {
- // This method may throw any BeansException, which won't be caught
- // here, if there is a critical failure such as no matching field.
- // We can attempt to deal only with less serious exceptions.
- setPropertyValue(pv);
- }
- catch (NotWritablePropertyException ex) {
- if (!ignoreUnknown) {
- throw ex;
- }
- // Otherwise, just ignore it and continue...
- }
- catch (NullValueInNestedPathException ex) {
- if (!ignoreInvalid) {
- throw ex;
- }
- // Otherwise, just ignore it and continue...
- }
- catch (PropertyAccessException ex) {
- if (propertyAccessExceptions == null) {
- propertyAccessExceptions = new LinkedList<>();
- }
- propertyAccessExceptions.add(ex);
- }
- }
- // If we encountered individual exceptions, throw the composite exception.
- if (propertyAccessExceptions != null) {
- PropertyAccessException[] paeArray =
- propertyAccessExceptions.toArray(new PropertyAccessException[propertyAccessExceptions.size()]);
- throw new PropertyBatchUpdateException(paeArray);
- }
- }
主要一点是弄清楚 wrapper 是怎么来的. Wrapper 对原生对象进行包装, 通过构造方法存储原始对象, 然后放入 cache 的是 Wrapper.
考虑一下为什么要用到包装模式: 减少代码侵入, 能够在原生的基础之上再进行扩展, 他可以覆盖, 调用方法, 甚至可以在原来的方法之上增加监听器, 回调函数等. 包装模式相当于静态代理的一种额外模式.
到这儿, Bean 的依赖注入就搞定了. 总结一下, 在我们之前操作的 IOC 容器初始化后, 将 XML 上的内容转化为 BeanDefinition 中的内容, 然后通过传入指定 Bean 的名字, 首先判断 Chache 中有没有, 也要查看其父级 BeanFactory, 如果有, 就通过限定名字得到实例, 如果没有, 就去创建, 创建的方式也分单例和原型两种.
来源: https://www.cnblogs.com/Jolivan/p/9226289.html