资讯专栏INFORMATION COLUMN

Spring源码之BeanDefinition类分析

HelKyle / 1883人阅读

摘要:但是这些对象在容器中,到底是以什么形式存在,具有哪些属性行为呢今天我们进入到源码来一探究竟。只对注解有效,配置文件中可以通过显示注入配置为主要候选。至于各属性的详细使用和注意事项,后续会有多带带的文章来解析,尽情期待

Spring版本为5.1.5
简述

用过spring的人都知道,我们将对象注入到spring容器中,交给spring来帮我们管理。这种对象我们称之为bean对象。但是这些bean对象在spring容器中,到底是以什么形式存在,具有哪些属性、行为呢?今天我们进入到spring源码来一探究竟。

bean的创建工厂BeanFactory有个默认实现类DefaultListableBeanFactory,内部有个存放所有注入bean对象信息的Map

/** Map of bean definition objects, keyed by bean name. */
private final Map beanDefinitionMap = new ConcurrentHashMap<>(256);

Map的value对象BeanDefinition就是spring中对bean的定义和描述,具体概述如下:

属性 行为 解释
parentName String getParentName();
void setParentName(@Nullable String parentName);
bean定义对象的父类定义对象名称
beanClassName String getBeanClassName();
void setBeanClassName(@Nullable String beanClassName);
bean对象的实际class类
scope String getScope();
void setScope(@Nullable String scope);
bean对象是否为单例
lazyInit boolean isLazyInit();
void setLazyInit(boolean lazyInit);
是否懒加载
dependsOn String[] getDependsOn();
void setDependsOn(@Nullable String... dependsOn);
设置依赖的bean对象,被依赖的bean对象总是会比当前bean对象先创建
autowireCandidate boolean isAutowireCandidate();
void setAutowireCandidate(boolean autowireCandidate);
设置是否可以自动注入。只对@Autowired注解有效,配置文件中可以通过property显示注入
primary boolean isPrimary();
void setPrimary(boolean primary);
配置bean为主要候选bean。当同一个接口的多个实现类或者一个类多次注入到spring容器时,通过该属性来配置某个bean为主候选bean,通过类型来注入时,默认为使用主候选bean注入
factoryBeanName String getFactoryBeanName();
void setFactoryBeanName(@Nullable String factoryBeanName);
设置创建bean的工厂名称
factoryMethodName String getFactoryMethodName();
void setFactoryMethodName(@Nullable String factoryMethodName);
设置创建bean的工厂中,创建bean的具体方法
initMethodName String getInitMethodName();
void setInitMethodName(@Nullable String initMethodName);
设置创建bean时,默认初始化的方法
destroyMethodName String getDestroyMethodName();
void setDestroyMethodName(@Nullable String destroyMethodName);
设置销毁bean时调用的方法名称。注意需要调用context的close()方法才会调用
role int getRole();
void setRole(int role);
设置bean的分类。
APPLICATION:用户
INFRASTRUCTURE:完全内部使用,与用户无关
SUPPORT:某些复杂配置的一部分
description String getDescription();
void setDescription(@Nullable String description);
对bean对象的描述
ConstructorArgumentValues getConstructorArgumentValues(); 记录构造函数注入属性,通过bean的水性constructor-arg来注入
MutablePropertyValues getPropertyValues(); 普通属性集合
注意:BeanDefinition是一个接口,内部只定义了bean对象的一些基本行为。上表中的属性在BeanDefinition中并不是真实存在的,只是通过set、get方法来设置和获取。以下抽取出部分BeanDefinition源代码供大家感知下
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
    /**
     * Override the target scope of this bean, specifying a new scope name.
     * @see #SCOPE_SINGLETON
     * @see #SCOPE_PROTOTYPE
     */
    void setScope(@Nullable String scope);

    /**
     * Return the name of the current target scope for this bean,
     * or {@code null} if not known yet.
     */
    @Nullable
    String getScope();
}
实际使用

假设有以下两个bean,Java代码如下

MyTestBean
package com.yuanweiquan.learn.bean;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Description;

public class MyTestBean {
    @Autowired
    private AutowireCandidateBean autowireCandidateBean;

    public void init() {
        System.out.println("inti MyTestBean");
    }

    public AutowireCandidateBean getAutowireCandidateBean() {
        return autowireCandidateBean;
    }
    public void setAutowireCandidateBean(AutowireCandidateBean bean) {
        this.autowireCandidateBean = bean;
    }
}
AutowireCandidateBean
package com.yuanweiquan.learn.bean;

public class AutowireCandidateBean {
    public void initBean() {
        System.out.println("init AutowireCandidateBean");
    }

    public void destroyBean() {
        System.out.println("destroy AutowireCandidateBean");
    }
}

下面看如何在配置文件applicationContext.xml来进行配置

   
         
   
      autowireCandidateBean description
   

接下来就是测试代码

FileSystemXmlApplicationContext factory = 
        new FileSystemXmlApplicationContext("classpath:applicationContext.xml");
BeanDefinition myTestBeanDefinition = 
        factory.getBeanFactory().getBeanDefinition("autowireCandidateBean");
//输出
System.out.println("bean description:" + myTestBeanDefinition.getDescription());
System.out.println("bean class name:" + myTestBeanDefinition.getBeanClassName());
System.out.println("parent name:" + myTestBeanDefinition.getParentName());
System.out.println("scope:" + myTestBeanDefinition.getScope());
System.out.println("is lazyinit:" + myTestBeanDefinition.isLazyInit());
System.out.println("depends On:" + myTestBeanDefinition.getDependsOn());
System.out.println("is autowireCandidate:" + myTestBeanDefinition.isAutowireCandidate());
System.out.println("is primary:" + myTestBeanDefinition.isPrimary());
System.out.println("factory bean name:"+myTestBeanDefinition.getFactoryBeanName());
System.out.println("factory bean method name:" + myTestBeanDefinition.getFactoryMethodName());
System.out.println("init method name:" + myTestBeanDefinition.getInitMethodName());
System.out.println("destory method name:" + myTestBeanDefinition.getDestroyMethodName());
System.out.println("role:" + myTestBeanDefinition.getRole());
//关闭context,否则不会调用bean的销毁方法
factory.close();

控制台输出如下

init AutowireCandidateBean
inti MyTestBean
bean description:autowireCandidateBean description
bean class name:com.yuanweiquan.learn.bean.AutowireCandidateBean
parent name:myTestBean
scope:singleton
is lazyinit:false
depends On:null
is autowireCandidate:true
is primary:true
factory bean name:null
factory bean method name:null
init method name:initBean
destory method name:destroyBean
role:0
destroy AutowireCandidateBean

到此为止,通过上面的信息,我们能清晰的看到各属性对应的值。上述测试代码的目的是让我们大家能看到bean在spring容器中,以什么样子的形式存在,具体有哪些属性,属性的值以及默认值是多少。也算初步的揭开了spring容器中bean的面纱,其实并没有我们想象中的那么神秘。至于各属性的详细使用和注意事项,后续会有多带带的文章来解析,尽情期待!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/73856.html

相关文章

  • Spring专题IOC源码分析

    摘要:前言以下源码基于版本解析。实现源码分析对于的实现,总结来说就是定位加载和注册。定位就是需要定位配置文件的位置,加载就是将配置文件加载进内存注册就是通过解析配置文件注册。下面我们从其中的一种使用的方式一步一步的分析的实现源码。 前言 以下源码基于Spring 5.0.2版本解析。 什么是IOC容器? 容器,顾名思义可以用来容纳一切事物。我们平常所说的Spring IOC容器就是一个可以容...

    不知名网友 评论0 收藏0
  • 【Dubbo源码阅读系列】 Dubbo XML 配置加载

    摘要:在介绍自定义标签解析前,先放一张图帮助大家理解以下是如何从文件中解析并加载的。自定义标签比如的值为根据获取到的,获取对应的对象。关于和加载先后顺序的问题最后再集合一个小例子总结下吧当我们先解析了元素时,我们会遍历所有已经注册注册表中。 今天我们来谈谈 Dubbo XML 配置相关内容。关于这部分内容我打算分为以下几个部分进行介绍: Dubbo XML Spring 自定义 XML 标...

    wangshijun 评论0 收藏0
  • Spring IOC 容器源码分析 - 获取单例 bean

    摘要:简介为了写容器源码分析系列的文章,我特地写了一篇容器的导读文章。在做完必要的准备工作后,从本文开始,正式开始进入源码分析的阶段。从缓存中获取单例。返回以上就是和两个方法的分析。 1. 简介 为了写 Spring IOC 容器源码分析系列的文章,我特地写了一篇 Spring IOC 容器的导读文章。在导读一文中,我介绍了 Spring 的一些特性以及阅读 Spring 源码的一些建议。在...

    lufficc 评论0 收藏0
  • Srping源码XMLBeanFactory

    摘要:本文是针对的来进行解析并将解析后的信息使用作为载体进行注册已经在中被标记为不建议使用,但是我们分析源码不影响,因为源码并未改变,并依旧使用和进行的解析和注册工作,本篇博客是跟源码一步步看怎么实现的注册,源码为源码已经在每一行上加了注释,方便 本文是针对Srping的XMLBeanFactory来进行解析xml并将解析后的信息使用GenericBeanDefinition作为载体进行注册...

    ckllj 评论0 收藏0
  • Spring源码一(容器的基本实现2)

    摘要:进一步解析其他所有属性并统一封装至类型的实例中。是一个接口,在中存在三种实现以及。通过将配置文件中配置信息转换为容器的内部表示,并将这些注册到中。容器的就像是配置信息的内存数据库,主要是以的形式保存。而代码的作用就是实现此功能。 前言:继续前一章。 一、porfile 属性的使用 如果你使用过SpringBoot, 你一定会知道porfile配置所带来的方便, 通过配置开发环境还是生产...

    yagami 评论0 收藏0

发表评论

0条评论

HelKyle

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<