精华内容
下载资源
问答
  • 概述 在Spring中,配置类(使用@Configuration的那些类)可以使用@Import直接导入另外一个配置类,也可以导入一个ImportSelector实现类根据特定的选择条件导入符合条件的配置类,也可以实现该接口...

    概述

    Spring中,配置类(使用@Configuration的那些类)可以使用@Import直接导入另外一个配置类,也可以导入一个ImportSelector实现类根据特定的选择条件导入符合条件的配置类,也可以实现该接口ImportBeanDefinitionRegistrar根据特定条件程序化地直接注册bean定义到容器。

    一个ImportBeanDefinitionRegistrar实现类通常也可能会实现各种Aware接口,如果实现了这些Aware接口,这些接口方法的调用会发生在registerBeanDefinitions之前。

    ImportBeanDefinitionRegistrar#registerBeanDefinitions的调用在ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsFromRegistrars中。

    ImportBeanDefinitionRegistrar实现类举例 :

    • DataSourceInitializationConfiguration$Registrar

      向容器注册一个名称为dataSourceInitializerPostProcessor的基础设施GenericBeanDefinition

    • DataSourceInitializedPublisher$Registrar

      向容器注册一个名称为dataSourceInitializedPublisher的基础设施GenericBeanDefinition

    • FeignClientsRegistrar

      向容器注册所有feign客户端的缺省配置bean定义,每个feign客户端的配置bean定义,以及每个feign客户端bean定义。

    一个ImportBeanDefinitionRegistrar通常被@Import注解使用,如下所示:

    //...
    @Import(FeignClientsRegistrar.class)
    public @interface EnableFeignClients {
        //...
    }
    

    源代码解析

    package org.springframework.context.annotation;
    
    import org.springframework.beans.factory.support.BeanDefinitionRegistry;
    import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
    import org.springframework.core.type.AnnotationMetadata;
    
    public interface ImportBeanDefinitionRegistrar {
    
    	/**
    	 * Register bean definitions as necessary based on the given annotation metadata of
    	 * the importing @Configuration class.
    	 * Note that BeanDefinitionRegistryPostProcessor types may not be
    	 * registered here, due to lifecycle constraints related to @Configuration
    	 * class processing.
         * 基于导入该ImportBeanDefinitionRegistrar的配置类的注解元数据按需求注册bean定义到
         * 容器。
         * 注意这里不能注册BeanDefinitionRegistryPostProcessor类型的bean定义,原因是
         * 这跟配置类的生命周期机制有冲突。
         * 
    	 * @param importingClassMetadata annotation metadata of the importing class
    	 * @param registry current bean definition registry
    	 */
    	public void registerBeanDefinitions(
    			AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry);
    
    }
    
    

    相关文章

    基于Java配置的Spring应用中如何导入更多的bean定义配置
    Spring 概念模型接口 ImportSelector : 配置类导入选择器

    展开全文
  • 将powerDesigner的概念模型转换成物理模型,生成sql文件导入数据库.
  • 在Spring中,如果想基于一个给定的选择标准(selection criteria),比如一个或者多个注解属性导入一些配置类(使用@Configuration的那些类)。可以实现接口ImportSelector来实现这样的逻辑。 一个ImportSelector实现类...

    概述

    Spring中,如果想基于一个给定的选择标准(selection criteria),比如一个或者多个注解属性导入一些配置类(使用@Configuration的那些类),某个bean注册器,可以实现接口ImportSelector来实现这样的逻辑。

    一个ImportSelector实现类通常也可能会实现各种Aware接口,如果实现了这些Aware接口,这些接口方法的调用会发生在selectImports之前。

    ImportSelector#selectImports的调用在ConfigurationClassParser#processImports中。

    实现类举例:

    • AutoConfigurationImportSelector

      Springboot用于从所有jar包的META-INF/spring.factories文件中加载所有的自动配置类:keyorg.springframework.boot.autoconfigure.EnableAutoConfiguration的项。

    • SessionAutoConfiguration$SessionConfigurationImportSelector

      根据当前Web环境类型决定启用哪个Session配置类。

    一个ImportSelector通常被@Import注解使用,如下所示 :

    //...
    @Import(AutoConfigurationImportSelector.class)
    public @interface EnableAutoConfiguration {
        //...
    }
    

    ImportSelector#selectImports 返回的树组的元素的类型可以是以下三种情况之一 :

    1. ImportSelector (也就是说,一个ImportSelector可以导入另外一个ImportSelector)
    2. ImportBeanDefinitionRegistrar
    3. 某个配置类

    源代码解析

    package org.springframework.context.annotation;
    
    import org.springframework.core.type.AnnotationMetadata;
    
    
    public interface ImportSelector {
    
    	/**
    	 * Select and return the names of which class(es) should be imported based on
    	 * the AnnotationMetadata of the importing @Configuration class.
         * 
         * 这里importingClassMetadata是使用@Import注解导入该ImportSelector
         * 的配置类的注解元数据。实现类可以实现该方法,根据导入类的注解元数据
         * 也就是importingClassMetadata,当然也可以结合考虑当前环境中的其他信息,
         * 决定导入哪些配置类。
    	 */
    	String[] selectImports(AnnotationMetadata importingClassMetadata);
    
    }
    

    有关文章

    Spring 概念模型接口 ImportBeanDefinitionRegistrar: Bean定义导入器

    展开全文
  • 包的概念:包是一种通过使用‘.模块名’来组织python模块名称空间的方式。通俗的讲包就是一系列模块的集合体 具体的:包就是一个包含有 __ init __ .py文件的文件夹,所以其实我们创建包的目的就是为了用文件夹将...

    包的认识

    包的概念:包是一种通过使用‘.模块名’来组织python模块名称空间的方式。通俗的讲包就是一系列模块的集合体
    具体的:包就是一个包含有 __ init __ .py文件的文件夹,所以其实我们创建包的目的就是为了用文件夹将文件/模块组织起来

    使用包的目的:包的本质就是一个文件夹,那么文件夹唯一的功能就是将文件组织起来,而随着模块越来越多,我们就需要用文件夹将模块文件组织起来,以此来提高程序的结构性和可维护性

    包名:包名就是存放一系列模块的文件夹名字

    重点:
    包中一定有一个专门用来管理包中所有模块的文件
    包名(包对象)存放的是管理模块的那个文件的地址,指向其全局名称空间

    模块的加载顺序

    模块的加载顺序:内存 => 内置 => sys.path(一系列自定义模块)

    import sys
    sys.path  
    '''
    sys.path 就是环境变量:存放文件路径的列表
    重点:默认列表第一个元素就是当前被执行文件所在的目录
    '''
    我们可以自己往sys.path添加路径
    sys.path.append(r'想导入的模块的绝对路径') 
    添加到环境变量最后,最后被查找
    sys.path.insert(0, r'想导入的模块的绝对路径')  
    添加到指定索引,索引就决定了自定义模块的查找顺序
    
    

    包以及包所包含的模块都是用来被导入的,而不是被直接执行的。而环境变量都是以执行文件为准的。

    import time
    第一次导入:内存->内置->自定义,最终在自定义中找到,完成导入,并在内存中缓存模块的内存地址
    import m1
    print(m1.num)
    time.sleep(5) #利用延迟把对应文件m1删除
    再次导入,从内存中就可以直接找到,即时当前文件为删除状态,内存中的地址任然可以被引用
    import m1 as mm1
    print(mm1.num)
    
    

    模块导入的执行流程

    '''
    导入模块的指令:
    	-- 相当于 函数名() 调用函数体,函数调用会进入函数体,从上至下逐句解释执行函数体代码
    	-- 导入模块,会进入模块文件,从上至下逐句解释执行模块文件代码
    	-- 如果在模块中又遇到导入其他模块,会接着进入导入的模块,从上至下逐句解释执行文件中代码,依次类推
    '''
    

    循环导入

    模块之间出现了环状导入,如:m1.py 中导入了m2,m2.py 中又导入了m1

    循环导入引发的问题:
    两个模块直接相互导入,且相互使用其名称空间中的名字,但是有些名字没有产生就使用,就出现了循环导入问题。

    m1.py文件
    import m2
    x = 10
    print(m2.y)
    
    m2.py文件
    import m1
    y = 10
    print(m2.x)
    
    

    两种解决循环导入的问题:延后导入
    1、将循环导入对应包要使用的变量提前定义,再导入相应的包
    2、将导包的路径放到函数体中,保证存放导包逻辑的函数调用在要使用的变量定义之后

    注意点:
    from导入马上会使用名字,极容易出现错误,建议循环导入情况下,尽量使用import导入。

    包的导入

    import本质:通过查找环境变量(sys.path)中的绝对路径来完成导入(右键执行该文件,sys.path第一个元素是当前文件夹路径)。

    导包:
    1.保证包所在文件夹在环境变量中
    2.导入的文件夹名就是包名

    import pk
    '''
    pk文件夹
    	-- __init__.py
    '''
    

    导包完成的三件事

    导包过程中会完成以下三件事:
    1.编译执行包中的__ init __ .py 文件,会在包中__ pycache __ 创建对应的pyc文件
    2.产生 __ init __ .py 文件的全局名称空间,用来存放 __ init __ 出现的名字
    3.产生包名指向 __ init __ .py 文件的全局名称空间 | 指定变量名指向包中指定名字

    总结:包名为文件夹名,名称空间是 __ init __ .py 产生的

    使用包中模块中的名字:采用import导入

    注意点:
    1.在包 __ init__ . py中不建议使用import导入
    2、在包 __ init __ .py 中不建议使用as起别名
    总结:不建议 __ init __ .py 中采用import管理名字 ==> 空着不写

    在使用文件中
    直接在要使用的文件中用import一层层找到你想要的名字
    import 包名.文件名 as 别名

    起完别名,原名不可以再使用
    原名:包名.文件名 => 包名.文件名.变量名
    别名:别名 => 别名.变量名

    绝对导入和相对导入

    包中使用import导入:绝对导入

    # 在包的__init__文件中
    import 模块名  # 问题:所属包不在环境变量,报错
    import 包名.模块名  # 问题:包所属文件夹不在文件变量,报错
    import 包名.模块名 as 别名  # 在外界:包名.模块名 | 包名.别名 都可以访问
    import 包名.模块名.名字  # 问题:导包语句.语法左侧必须全部是包(文件夹)
    
    外界
    import 包名
    包名.名字  # 访问的是__init__中的名字
    包名.模块  # 访问的模块这个地址
    包名.模块.名字  # 访问的模块中的名字
    
    import 包名.模块
    包名.模块  # 访问的模块这个地址
    包名.模块.名字  # 访问的模块中的名字
    
    from 包名 import 模块
    模块  # 访问的模块这个地址
    模块.名字  # 访问的模块中的名字
    
    from 包名.模块 import 名字
    名字  # 访问的模块中的名字
    
    

    包中使用from导入:相对导入

    没有子包

    1)
    pk包
    	-- __init__.py
    		-- 名字 a = 10
    	-- pkm.py
    		-- 名字 b = 20
    	
    在外界
    import pk
    pk.a 访问a
    pk.b 访问b
    
    init管理文件
    a不需要操作
    from .pkm import b
    
    

    有子包

    1、pk包
    	-- __init__.py
    	sub子包
    		-- __init__.py
    			名字 x = 10
    		-- subm.py
    			名字 y = 10	
    直接在外界访问内部名字时
    import pk
    pk.x 访问x
    pk.y 访问y
    在pk的init管理文件
    from .sub import x
    from .sub.subm import 
    
    2、pk包
    	-- __init__.py
    	sub子包
    		-- __init__.py
    			名字 x = 10
    		-- subm.py
    			名字 y = 10	
    直接在外界访问内部名字时
    import pk
    pk.sub.x 访问x
    pk.sub.y 访问y
    
    在pk的init管理文件:要产生sub名字
    from . import sub  => pk.sub
    
    在sub的init管理文件:要产生x,y名字
    x不需要操作  => pk.sub.x
    from .subm import y  => pk.sub.y
    
    

    需要注意:
    有相对导入.语法的文件都不能自执行

    展开全文
  • go中包的概念导入与可见性

    千次阅读 2018-01-05 15:40:55
    包是结构化代码的一种方式:每个程序都由包(通常简称为 pkg)的概念组成,可以使用自身的包或者从其它包中导入内容。 如同其它一些编程语言中的类库或命名空间的概念,每个 Go 文件都属于且仅属于一个包。一个包...

    转自:https://studygolang.com/articles/7165


    包是结构化代码的一种方式:每个程序都由包(通常简称为 pkg)的概念组成,可以使用自身的包或者从其它包中导入内容。

    如同其它一些编程语言中的类库或命名空间的概念,每个 Go 文件都属于且仅属于一个包。一个包可以由许多以 .go 为扩展名的源文件组成,因此文件名和包名一般来说都是不相同的。

    你必须在源文件中非注释的第一行指明这个文件属于哪个包,如:package mainpackage main表示一个可独立执行的程序,每个 Go 应用程序都包含一个名为 main 的包。

    一个应用程序可以包含不同的包,而且即使你只使用 main 包也不必把所有的代码都写在一个巨大的文件里:你可以用一些较小的文件,并且在每个文件非注释的第一行都使用 package main 来指明这些文件都属于 main 包。如果你打算编译包名不是为 main 的源文件,如 pack1,编译后产生的对象文件将会是 pack1.a 而不是可执行程序。另外要注意的是,所有的包名都应该使用小写字母。

    标准库

    在 Go 的安装文件里包含了一些可以直接使用的包,即标准库。在 Windows 下,标准库的位置在 Go 根目录下的子目录 pkg\windows_386 中;在 Linux 下,标准库在 Go 根目录下的子目录 pkg\linux_amd64 中(如果是安装的是 32 位,则在 linux_386 目录中)。一般情况下,标准包会存放在 $GOROOT/pkg/$GOOS_$GOARCH/ 目录下。

    Go 的标准库包含了大量的包(如:fmt 和 os),但是你也可以创建自己的包。

    如果想要构建一个程序,则包和包内的文件都必须以正确的顺序进行编译。包的依赖关系决定了其构建顺序。

    属于同一个包的源文件必须全部被一起编译,一个包即是编译时的一个单元,因此根据惯例,每个目录都只包含一个包。

    如果对一个包进行更改或重新编译,所有引用了这个包的客户端程序都必须全部重新编译。

    Go 中的包模型采用了显式依赖关系的机制来达到快速编译的目的,编译器会从后缀名为 .o 的对象文件(需要且只需要这个文件)中提取传递依赖类型的信息。

    如果 A.go 依赖 B.go,而 B.go 又依赖 C.go

    • 编译 C.goB.go, 然后是 A.go.
    • 为了编译 A.go, 编译器读取的是 B.o 而不是 C.o.

    这种机制对于编译大型的项目时可以显著地提升编译速度。

    每一段代码只会被编译一次

    一个 Go 程序是通过 import 关键字将一组包链接在一起。

    import "fmt" 告诉 Go 编译器这个程序需要使用 fmt 包(的函数,或其他元素),fmt 包实现了格式化 IO(输入/输出)的函数。包名被封闭在半角双引号 "" 中。如果你打算从已编译的包中导入并加载公开声明的方法,不需要插入已编译包的源代码。

    如果需要多个包,它们可以被分别导入:

    import "fmt"
    import "os"

    或:

    import "fmt"; import "os"

    但是还有更短且更优雅的方法(被称为因式分解关键字,该方法同样适用于 const、var 和 type 的声明或定义):

    import (
       "fmt"
       "os"
    )

    它甚至还可以更短的形式,但使用 gofmt 后将会被强制换行:

    import ("fmt"; "os")

    当你导入多个包时,导入的顺序会按照字母排序。

    如果包名不是以 . 或 / 开头,如 "fmt" 或者 "container/list",则 Go 会在全局文件进行查找;如果包名以 ./ 开头,则 Go 会在相对目录中查找;如果包名以 / 开头(在 Windows 下也可以这样使用),则会在系统的绝对路径中查找。

    导入包即等同于包含了这个包的所有的代码对象。

    除了符号 _,包中所有代码对象的标识符必须是唯一的,以避免名称冲突。但是相同的标识符可以在不同的包中使用,因为可以使用包名来区分它们。

    包通过下面这个被编译器强制执行的规则来决定是否将自身的代码对象暴露给外部文件:

    可见性规则

    当标识符(包括常量、变量、类型、函数名、结构字段等等)以一个大写字母开头,如:Group1,那么使用这种形式的标识符的对象就可以被外部包的 代码所使用(客户端程序需要先导入这个包),这被称为导出(像面向对象语言中的 public);标识符如果以小写字母开头,则对包外是不可见的,但是他们在整个包的内部是可见并且可用的(像面向对象语言中的 private )。

    (大写字母可以使用任何 Unicode 编码的字符,比如希腊文,不仅仅是 ASCII 码中的大写字母)。

    因此,在导入一个外部包后,能够且只能够访问该包中导出的对象。

    假设在包 pack1 中我们有一个变量或函数叫做 Thing(以 T 开头,所以它能够被导出),那么在当前包中导入 pack1 包,Thing 就可以像面向对象语言那样使用点标记来调用:pack1.Thing(pack1 在这里是不可以省略的)。

    因此包也可以作为命名空间使用,帮助避免命名冲突(名称冲突):两个包中的同名变量的区别在于他们的包名,例如 pack1.Thing和 pack2.Thing

    你可以通过使用包的别名来解决包名之间的名称冲突,或者说根据你的个人喜好对包名进行重新设置,如:import fm "fmt"。下面的代码展示了如何使用包的别名:

    示例 4.2 alias.go

    package main
    
    import fm "fmt" // alias3
    
    func main() {
       fm.Println("hello, world")
    }

    注意事项

    如果你导入了一个包却没有使用它,则会在构建程序时引发错误,如 imported and not used: os,这正是遵循了 Go 的格言:“没有不必要的代码!“。

    包的分级声明和初始化

    你可以在使用 import 导入包之后定义或声明 0 个或多个常量(const)、变量(var)和类型(type),这些对象的作用域都是全局的(在本包范围内),所以可以被本包中所有的函数调用(如 gotemplate.go 源文件中的 c 和 v),然后声明一个或多个函数(func)。

     

    Go 程序的一般结构

    下面的程序可以被顺利编译但什么都做不了,不过这很好地展示了一个 Go 程序的首选结构。这种结构并没有被强制要求,编译器也不关心 main 函数在前还是变量的声明在前,但使用统一的结构能够在从上至下阅读 Go 代码时有更好的体验。

    所有的结构将在这一章或接下来的章节中进一步地解释说明,但总体思路如下:

    • 在完成包的 import 之后,开始对常量、变量和类型的定义或声明。
    • 如果存在 init 函数的话,则对该函数进行定义(这是一个特殊的函数,每个含有该函数的包都会首先执行这个函数)。
    • 如果当前包是 main 包,则定义 main 函数。
    • 然后定义其余的函数,首先是类型的方法,接着是按照 main 函数中先后调用的顺序来定义相关函数,如果有很多函数,则可以按照字母顺序来进行排序。

    示例 4.4 gotemplate.go

    package main
    
    import (
       "fmt"
    )
    
    const c = "C"
    
    var v int = 5
    
    type T struct{}
    
    func init() { // initialization of package
    }
    
    func main() {
       var a int
       Func1()
       // ...
       fmt.Println(a)
    }
    
    func (t T) Method1() {
       //...
    }
    
    func Func1() { // exported function Func1
       //...
    }

    Go 程序的执行(程序启动)顺序如下:

    1. 按顺序导入所有被 main 包引用的其它包,然后在每个包中执行如下流程:
    2. 如果该包又导入了其它的包,则从第一步开始递归执行,但是每个包只会被导入一次。
    3. 然后以相反的顺序在每个包中初始化常量和变量,如果该包含有 init 函数的话,则调用该函数。
    4. 在完成这一切之后,main 也执行同样的过程,最后调用 main 函数开始执行程序。

    展开全文
  • 使用Protege建立了本体模型及实例保存为.owl以后,如何通过jena找到某给定概念的子概念? 求具体的代码!
  • 模块概念 对module的理解 Module的查找路径 与package关系 模块导入 导入 同一目录 不同目录 import、from module import packet使用规则示例 重新导入模块 包的概念 包的导入导入的几种情况 import语句...
  • Oracle11g数据库导入导出: 1. 传统方式:exp(导出)...一、相关概念介绍 什么是数据库导入导出 oracle11g数据库的导入/导出,就是通常所说Oracle数据库的还原/备份。 数据库导入: 把.dmp格式文件从本地导入到数据库...
  • Python相对导入与绝对导入

    千次阅读 2018-05-14 18:34:08
    Python 相对导入与绝对导入,这两个概念是相对于包内导入而言的。包内导入即是包内的模块导入包内部的模块。 Python import 的搜索路径 在当前目录下搜索该模块 在环境变量 PYTHONPATH 中指定的路径列表中依次...
  • 这两个概念是相对于包内导入而言的。包内导入即是包内的模块导入包内部的模块。 2、python中import的搜索路径 当前文件夹下 环境变量PYTHONPAHT中 sys.path中 3、python中的import 导入当前模块同级别的...
  • 2014-08-31 Created By BaoXinjian 一、摘要 在平常备库和数据库迁移的时候,当遇到大的数据库的时候在用exp的时候往往是需要好几个小时,耗费大量时间。oracle10g以后可以用expdp来导出数据库花费的时间要远...
  • 基本概念 Python 中的包,即包含 __init__.py 文件的文件夹。 对于 Python 的包内导入,即包内模块导入包内模块,存在绝对导入和相对导入问题。 普通 Python 模块的搜索路径 1. 在当前模块所在路径中搜索导入...
  • Solr 概念概念上,Solr 可以被分成四大块: 模式(schema.xml)配置(solrconfig.xml)索引搜索 要理解模式,需要先理解 Lucene 对 Document的注释。一个 Document包含一个或多个 Field。一个 Field由...
  • 静态导入

    2011-03-08 09:49:00
    前一阵子在看书的时候,看到静态导入概念的时候,不懂,今天突然想起,查阅资料,并编写了一个例子静态导入,在你自己的类中使用静态导入,可以让你使用其它类中定义的类方法和类变量,而且这些类方法和类变量就像...
  • 详解Python中的相对导入和绝对导入

    千次阅读 2017-08-31 09:35:40
    Python 相对导入与绝对导入,这两个概念是相对于包内导入而言的。包内导入即是包内的模块导入包内部的模块。 Python import 的搜索路径 在当前目录下搜索该模块在环境变量 PYTHONPATH 中指定的路径列表中依
  • Python 3.x | 史上最详解的 导入(import)

    万次阅读 多人点赞 2018-07-27 15:05:02
    一、理解一些基本概念 1、包、模块 模块 module:一般情况下,是一个以.py为后缀的文件。其他可作为module的文件类型还有”.pyo”、”.pyc”、”.pyd”、”.so”、”.dll”,但Python初学者几乎用不到。 module ...
  • matlab 数据导入

    万次阅读 多人点赞 2015-05-24 16:47:35
    matlab导入数据有2中方式,一种是在命令行通过代码把数据导进去;另一种是通过matlab的数据导入向导导入。下面分布介绍这两种方法: 一、使用matlab数据导入向导  1、先来看看txt文档中保存的数据结构,如图所示...
  • Java的静态导入

    2015-03-12 13:31:34
    概念: 静态导入是JDK5引入的新特性,使用静态导入后被导入类的静态变量和静态方法在当前类中直接可见,使用时这些 静态成员无需再给出他们的类名,调用的时候和调用自己的方法没有任何区别。 使用方法: 在...
  • import 导入问题

    千次阅读 2020-01-16 14:47:26
    文章目录Python import导入问题1.sys.modules2.\_\_dict\_\_属性3. import 做了什么?4.sys.path总结 python的导包流程(绝对导入):案例说明绝对导入相对导入导包场景测试说明☆Python 2.7 和3.7 执行情况说明总结:...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 205,064
精华内容 82,025
关键字:

导入的概念