首页 > 编程语言 >spring源码基础

spring源码基础

时间:2024-08-17 13:37:56浏览次数:12  
标签:Return String Nullable spring 基础 see factory bean 源码

1.beanDefinition

查看代码
 public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {

    //单例
    String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;

    //原型
    String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;


    /**
     * Role hint indicating that a {@code BeanDefinition} is a major part
     * of the application. Typically corresponds to a user-defined bean.
     */
    int ROLE_APPLICATION = 0;

    /**
     * Role hint indicating that a {@code BeanDefinition} is a supporting
     * part of some larger configuration, typically an outer
     * {@link org.springframework.beans.factory.parsing.ComponentDefinition}.
     * {@code SUPPORT} beans are considered important enough to be aware
     * of when looking more closely at a particular
     * {@link org.springframework.beans.factory.parsing.ComponentDefinition},
     * but not when looking at the overall configuration of an application.
     */
    int ROLE_SUPPORT = 1;

    /**
     * Role hint indicating that a {@code BeanDefinition} is providing an
     * entirely background role and has no relevance to the end-user. This hint is
     * used when registering beans that are completely part of the internal workings
     * of a {@link org.springframework.beans.factory.parsing.ComponentDefinition}.
     */
    int ROLE_INFRASTRUCTURE = 2;


    // Modifiable attributes

    //设置父的BeanDefinition名称
    void setParentName(@Nullable String parentName);

    //获取父的BeanDefinition名称
    String getParentName();

    //设置beanClass名称
    void setBeanClassName(@Nullable String beanClassName);

    //获取beanClass名称
    @Nullable
    String getBeanClassName();

    //设置作用域
    void setScope(@Nullable String scope);

    //获取作用域
    @Nullable
    String getScope();

    //设置是否懒加载
    void setLazyInit(boolean lazyInit);

    //是懒加载
    boolean isLazyInit();

    //设置依赖,对应xmlDepend
    void setDependsOn(@Nullable String... dependsOn);

    /**
     * Return the bean names that this bean depends on.
     */
    @Nullable
    String[] getDependsOn();

    //设置自动装配
    void setAutowireCandidate(boolean autowireCandidate);

    /**
     * Return whether this bean is a candidate for getting autowired into some other bean.
     */
    boolean isAutowireCandidate();

    /**
     * Set whether this bean is a primary autowire candidate.
     * <p>If this value is {@code true} for exactly one bean among multiple
     * matching candidates, it will serve as a tie-breaker.
     * @see #setFallback
     */
    void setPrimary(boolean primary);

    /**
     * Return whether this bean is a primary autowire candidate.
     */
    boolean isPrimary();

    /**
     * Set whether this bean is a fallback autowire candidate.
     * <p>If this value is {@code true} for all beans but one among multiple
     * matching candidates, the remaining bean will be selected.
     * @since 6.2
     * @see #setPrimary
     */
    void setFallback(boolean fallback);

    /**
     * Return whether this bean is a fallback autowire candidate.
     * @since 6.2
     */
    boolean isFallback();

    /**
     * Specify the factory bean to use, if any.
     * This is the name of the bean to call the specified factory method on.
     * <p>A factory bean name is only necessary for instance-based factory methods.
     * For static factory methods, the method will be derived from the bean class.
     * @see #setFactoryMethodName
     * @see #setBeanClassName
     */
    void setFactoryBeanName(@Nullable String factoryBeanName);

    /**
     * Return the factory bean name, if any.
     * <p>This will be {@code null} for static factory methods which will
     * be derived from the bean class instead.
     * @see #getFactoryMethodName()
     * @see #getBeanClassName()
     */
    @Nullable
    String getFactoryBeanName();

    /**
     * Specify a factory method, if any. This method will be invoked with
     * constructor arguments, or with no arguments if none are specified.
     * The method will be invoked on the specified factory bean, if any,
     * or otherwise as a static method on the local bean class.
     * @see #setFactoryBeanName
     * @see #setBeanClassName
     */
    void setFactoryMethodName(@Nullable String factoryMethodName);

    /**
     * Return a factory method, if any.
     * @see #getFactoryBeanName()
     * @see #getBeanClassName()
     */
    @Nullable
    String getFactoryMethodName();

    /**
     * Return the constructor argument values for this bean.
     * <p>The returned instance can be modified during bean factory post-processing.
     * @return the ConstructorArgumentValues object (never {@code null})
     */
    ConstructorArgumentValues getConstructorArgumentValues();

    /**
     * Return if there are constructor argument values defined for this bean.
     * @since 5.0.2
     * @see #getConstructorArgumentValues()
     */
    default boolean hasConstructorArgumentValues() {
       return !getConstructorArgumentValues().isEmpty();
    }

    /**
     * Return the property values to be applied to a new instance of the bean.
     * <p>The returned instance can be modified during bean factory post-processing.
     * @return the MutablePropertyValues object (never {@code null})
     */
    MutablePropertyValues getPropertyValues();

    /**
     * Return if there are property values defined for this bean.
     * @since 5.0.2
     * @see #getPropertyValues()
     */
    default boolean hasPropertyValues() {
       return !getPropertyValues().isEmpty();
    }

    /**
     * Set the name of the initializer method.
     * @since 5.1
     */
    void setInitMethodName(@Nullable String initMethodName);

    /**
     * Return the name of the initializer method.
     * @since 5.1
     */
    @Nullable
    String getInitMethodName();

    /**
     * Set the name of the destroy method.
     * @since 5.1
     */
    void setDestroyMethodName(@Nullable String destroyMethodName);

    /**
     * Return the name of the destroy method.
     * @since 5.1
     */
    @Nullable
    String getDestroyMethodName();

    /**
     * Set the role hint for this {@code BeanDefinition}. The role hint
     * provides the frameworks as well as tools an indication of
     * the role and importance of a particular {@code BeanDefinition}.
     * @since 5.1
     * @see #ROLE_APPLICATION
     * @see #ROLE_SUPPORT
     * @see #ROLE_INFRASTRUCTURE
     */
    void setRole(int role);

    /**
     * Get the role hint for this {@code BeanDefinition}. The role hint
     * provides the frameworks as well as tools an indication of
     * the role and importance of a particular {@code BeanDefinition}.
     * @see #ROLE_APPLICATION
     * @see #ROLE_SUPPORT
     * @see #ROLE_INFRASTRUCTURE
     */
    int getRole();

    /**
     * Set a human-readable description of this bean definition.
     * @since 5.1
     */
    void setDescription(@Nullable String description);

    /**
     * Return a human-readable description of this bean definition.
     */
    @Nullable
    String getDescription();


    // Read-only attributes

    /**
     * Return a resolvable type for this bean definition,
     * based on the bean class or other specific metadata.
     * <p>This is typically fully resolved on a runtime-merged bean definition
     * but not necessarily on a configuration-time definition instance.
     * @return the resolvable type (potentially {@link ResolvableType#NONE})
     * @since 5.2
     * @see ConfigurableBeanFactory#getMergedBeanDefinition
     */
    ResolvableType getResolvableType();

    /**
     * Return whether this a <b>Singleton</b>, with a single, shared instance
     * returned on all calls.
     * @see #SCOPE_SINGLETON
     */
    boolean isSingleton();

    /**
     * Return whether this a <b>Prototype</b>, with an independent instance
     * returned for each call.
     * @since 3.0
     * @see #SCOPE_PROTOTYPE
     */
    boolean isPrototype();

    /**
     * Return whether this bean is "abstract", that is, not meant to be instantiated
     * itself but rather just serving as parent for concrete child bean definitions.
     */
    boolean isAbstract();

    /**
     * Return a description of the resource that this bean definition
     * came from (for the purpose of showing context in case of errors).
     */
    @Nullable
    String getResourceDescription();

    /**
     * Return the originating BeanDefinition, or {@code null} if none.
     * <p>Allows for retrieving the decorated bean definition, if any.
     * <p>Note that this method returns the immediate originator. Iterate through the
     * originator chain to find the original BeanDefinition as defined by the user.
     */
    @Nullable
    BeanDefinition getOriginatingBeanDefinition();

}

2.AbstractBeanDefinition:定义了默认常量与方法,服务BeanDefinition

查看代码
 public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
       implements BeanDefinition, Cloneable {

    //定义默认的常量
    public static final String SCOPE_DEFAULT = "";
    public static final int AUTOWIRE_NO = AutowireCapableBeanFactory.AUTOWIRE_NO;
    public static final int AUTOWIRE_BY_NAME = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME;
    public static final int AUTOWIRE_BY_TYPE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE;

    /**
     * Constant that indicates autowiring a constructor.
     * @see #setAutowireMode
     */
    public static final int AUTOWIRE_CONSTRUCTOR = AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR;

    /**
     * Constant that indicates determining an appropriate autowire strategy
     * through introspection of the bean class.
     * @see #setAutowireMode
     * @deprecated as of Spring 3.0: If you are using mixed autowiring strategies,
     * use annotation-based autowiring for clearer demarcation of autowiring needs.
     */
    @Deprecated
    public static final int AUTOWIRE_AUTODETECT = AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT;

    /**
     * Constant that indicates no dependency check at all.
     * @see #setDependencyCheck
     */
    public static final int DEPENDENCY_CHECK_NONE = 0;

    /**
     * Constant that indicates dependency checking for object references.
     * @see #setDependencyCheck
     */
    public static final int DEPENDENCY_CHECK_OBJECTS = 1;

    /**
     * Constant that indicates dependency checking for "simple" properties.
     * @see #setDependencyCheck
     * @see org.springframework.beans.BeanUtils#isSimpleProperty
     */
    public static final int DEPENDENCY_CHECK_SIMPLE = 2;

    /**
     * Constant that indicates dependency checking for all properties
     * (object references as well as "simple" properties).
     * @see #setDependencyCheck
     */
    public static final int DEPENDENCY_CHECK_ALL = 3;

    /**
     * The name of an attribute that can be
     * {@link org.springframework.core.AttributeAccessor#setAttribute set} on a
     * {@link org.springframework.beans.factory.config.BeanDefinition} so that
     * bean definitions can indicate one or more preferred constructors. This is
     * analogous to {@code @Autowired} annotated constructors on the bean class.
     * <p>The attribute value may be a single {@link java.lang.reflect.Constructor}
     * reference or an array thereof.
     * @since 6.1
     * @see org.springframework.beans.factory.annotation.Autowired
     * @see org.springframework.beans.factory.support.RootBeanDefinition#getPreferredConstructors()
     */
    public static final String PREFERRED_CONSTRUCTORS_ATTRIBUTE = "preferredConstructors";

    /**
     * The name of an attribute that can be
     * {@link org.springframework.core.AttributeAccessor#setAttribute set} on a
     * {@link org.springframework.beans.factory.config.BeanDefinition} so that
     * bean definitions can indicate the sort order for the targeted bean.
     * This is analogous to the {@code @Order} annotation.
     * @since 6.1.2
     * @see org.springframework.core.annotation.Order
     * @see org.springframework.core.Ordered
     */
    public static final String ORDER_ATTRIBUTE = "order";

3.包扫描

无非是有两种:

路径+类,通过反射获取到类。

字节码操作技术,直接在字节码中获取元数据,字节码包含这个类的一切信息。

以下代码就是将

private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
    Set<BeanDefinition> candidates = new LinkedHashSet<>();
    try {
       // 扫描包路径,classpath*:com/xxx/**/*.class   匹配这个包以及子包下的class文件
       String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
             resolveBasePackage(basePackage) + '/' + this.resourcePattern;
       // URL [jar:file:/D:/sourceStudy/spring-framework/spring-study/build/libs/spring-study-6.2.0-SNAPSHOT.jar!/com/ydlclass/bean/Dog.class]
       //Spring会将每一个定义的字节码文件加载成为一个Resource资源
       Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
       boolean traceEnabled = logger.isTraceEnabled();
       boolean debugEnabled = logger.isDebugEnabled();
       for (Resource resource : resources) {
          String filename = resource.getFilename();
          if (filename != null && filename.contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
             // Ignore CGLIB-generated classes in the classpath
             continue;
          }
          if (traceEnabled) {
             logger.trace("Scanning " + resource);
          }
          try {
             MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
             if (isCandidateComponent(metadataReader)) {
                ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
                sbd.setSource(resource);
                if (isCandidateComponent(sbd)) {
                   if (debugEnabled) {
                      logger.debug("Identified candidate component class: " + resource);
                   }
                   candidates.add(sbd);
                }
                else {
                   if (debugEnabled) {
                      logger.debug("Ignored because not a concrete top-level class: " + resource);
                   }
                }
             }
             else {
                if (traceEnabled) {
                   logger.trace("Ignored because not matching any filter: " + resource);
                }
             }
          }
          catch (FileNotFoundException ex) {
             if (traceEnabled) {
                logger.trace("Ignored non-readable " + resource + ": " + ex.getMessage());
             }
          }
          catch (ClassFormatException ex) {
             if (shouldIgnoreClassFormatException) {
                if (debugEnabled) {
                   logger.debug("Ignored incompatible class format in " + resource + ": " + ex.getMessage());
                }
             }
             else {
                throw new BeanDefinitionStoreException("Incompatible class format in " + resource +
                      ": set system property 'spring.classformat.ignore' to 'true' " +
                      "if you mean to ignore such files during classpath scanning", ex);
             }
          }
          catch (Throwable ex) {
             throw new BeanDefinitionStoreException("Failed to read candidate component class: " + resource, ex);
          }
       }
    }
    catch (IOException ex) {
       throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);
    }
    return candidates;
}

3.ApplicationContext与BeanFactory区别

ApplicationContext:可以理解成高级容器,具备相对符合的能力。

ListableBeanFactory(具备beanFactoryg管理能力)

HierarchicalBeanFactory 具备分层能力   MessageSource 国籍化能力   ApplicationEventPublisher 事件发送能力
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
       MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
       ...............
       ..............
4. refresh刷新过程
public void refresh() throws BeansException, IllegalStateException {
    this.startupShutdownLock.lock();
    try {
       // 启动关闭线程,这个线程用来表示启动当前容器使用的线程
       // 该成员变量在之前的版本中并不存在,也是为了支持后续的并发实例化bean的情况
       this.startupShutdownThread = Thread.currentThread();

       // StartupStep是个小工具,用来记录执行流程
       StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

       // 为当前上下文进行刷新前的准备
       prepareRefresh();

       // 此处是要初始化一个bean工厂,实时上beanFactory会在上下文构建的就创建了
       // 核心的目的是为了提供一种可以进行重复刷新的bean工厂的扩展,虽然我们不用
       ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

       // 为工厂做一些准备工作,完成一些核心的基础配置
       // 这是spring-framework需要做的工作
       // 注册几个和环境相关的bean,如:environment、systemProperties、systemEnvironment
       prepareBeanFactory(beanFactory);

       try {
          // 空方法,留给子类去实现,GenericXmlApplicationContext没有进行扩展
          // GenericWebApplicationContext进行了扩展,注册了新的作用域,处理了和servlet相关的一些工作
          // 此处是spring提供给第三方的框架如spring-mvc等在容器启动前做的配置性工作
          postProcessBeanFactory(beanFactory);

          // 记录新的步骤,post-process
          StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");

          // 调用所有beanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor的实现类,此时bean没有进行实例化
          // 我们可以在此处配置beanFactory,修改beanDefinition
          // 此处会处理BeanDefinitionRegistryPostProcessor
          // 执行流程会根据priorityOrdered  Ordered noOrdered进行排序
          // 单独添加了一个listener的探测器,会在bean实例化后判断是否是一个listener,如果是进行注册
          invokeBeanFactoryPostProcessors(beanFactory);

          // 注册beanPostProcessor,同样会根据priorityOrdered  Ordered noOrdered进行排序
          registerBeanPostProcessors(beanFactory);
          // 结束步骤
          beanPostProcess.end();

          // 初始化上下文的messageSource
          initMessageSource();

          // 初始化上下文的多播器
          initApplicationEventMulticaster();

          // 留出空方法,让子类扩展
          // ServletWebServerApplicationContext进行了扩展,创建一个webServer,启动tomcat
          onRefresh();

          // 注册监听器,此处listenerBean不会被实例化,会议beanName的方式注册
          // 还会处理一些早期事件
          registerListeners();

          // 核心:实例化所有的非懒加载的单例bean
          finishBeanFactoryInitialization(beanFactory);

          // 完成刷新,发布完成刷新的事件
          finishRefresh();
       }

       // 捕获运行时异常和错误
       catch (RuntimeException | Error ex ) {
          // 如果日志器支持警告级别,则记录异常信息
          if (logger.isWarnEnabled()) {
             logger.warn("Exception encountered during context initialization - " +
                   "cancelling refresh attempt: " + ex);
          }
          // 销毁已创建的单例,以避免资源泄露
          destroyBeans();
          // 重置'active'标志
          cancelRefresh(ex);
          // 将异常抛给调用者
          throw ex;
       }
       // 无论是否抛出异常,都会执行的代码块,用于清理工作
       finally {
          contextRefresh.end(); // 结束上下文刷新过程
       }
    }
    // 无论是否抛出异常,都会执行的代码块,用于释放资源
    finally {
       this.startupShutdownThread = null; // 重置启动/关闭线程
       this.startupShutdownLock.unlock(); // 解锁启动/关闭锁
    }

}
 

标签:Return,String,Nullable,spring,基础,see,factory,bean,源码
From: https://www.cnblogs.com/jichenghui/p/18364290

相关文章

  • springboot项目打包jar 并打包为exe启动
    springboot项目打包jar并打包为exe启动(在无jdk环境下运行)环境SpringBoot+Windows+IDEA实现1.springboot打包为可执行jar(这里使用maveninstall)maven工具栏选择项目->Plugins->install注:如果存在前端页面需同时打包(webapp下);需在pom.xml中进行配置<build>......
  • 004、Vue3+TypeScript基础,使用组合式API的写法
    01、App.vue代码如下:<template><divclass="app"><h1>好好学习,天天向上</h1><Person/></div></template><script>//JS或TSimportPersonfrom'./view/PersonNew.vue'exportdefault{......
  • Matlab基础
    整数浮点数复数逻辑类型字符串函数句柄单元数组cell()建立单元数组c=cell(3,2)即为建立三行两列的单元数组celldisp()显示单元数组的元素c={eye(2),'China';[1:4],100}celldisp(c)显示c中元素celldisp(c,'mycell')显示c中元素并显示c的名字为myce......
  • python基础
      Python安装国内的镜像包:pipconfigsetglobal.index-urlSimpleIndex豆瓣:http://pypi.douban.com/simple/pipinstall 库名 -i 国内镜像加速器地址。pip install 加库名 #安装库库一般安装在python下的scripts下d: #换盘pip list #显示安装的库p......
  • 前端基础知识
    前端基础知识应用软件1.C/S架构&解析:C:client(客户端)S:server(服务器)一.优点:有多重安全认证,适用于大型专业应用和对安全性要求较高的应用界面和操作可以很丰富由于只有一层交互,响应速度快二.缺点:1.需要安装2.偶尔需要更新3.不跨平台2.B/S架构&解析:B:browser(浏览器)......
  • 计算机毕业设计-基于Java的校园快递管理平台【源码+文档+PPT】
    精彩专栏推荐订阅:在下方主页......
  • 002、Vue3+TypeScript基础,调用子页面和简单效果
    01、App.vue代码:<template><divclass="app"><h1>好好学习,天天向上</h1><Person/></div></template><script>//JS或TSimportPersonfrom'./view/Person.vue'exportdefault{//Ap......
  • springboot基于springboot的社区团购系统设计
    运行环境开发语言:java框架:springboot,vueJDK版本:JDK1.8数据库:mysql5.7+(推荐5.7,8.0也可以)数据库工具:Navicat11+开发软件:idea/eclipse(推荐idea)系统的实现用户功能模块的实现用户注册界面没有账号的用户可进入注册界面进行注册操作,用户注册界面的运行效果用户......
  • MySQL数据库基础
    目录1.数据库的操作1.1  创建数据库1.2查看数据库1.3选中数据库1.4删除数据库2.常用数据类型2.1数值类型2.2字符串类型2.3日期类型3.表的操作3.1创建表3.2查看所有表3.3查看表的结构3.4删除表4.内容重点总结5.练习1.数据库的操作1.1  ......
  • Linux下如何在程序中获取某个命令执行的结果?【附源码】
    在工作中遇到一个问题,就是想获取某个函数执行之后打印的字符串信息。这个功能应用场景挺多的,特地整理了一下相关知识点分享给大家。1.使用临时文件1)使用shell的重定向将命令输出重定向到一个临时文件,在我们的应用程序中读取这个临时文件,获得外部命令执行结果,代码如下所示:/......