摘要:概述容器管理一个或多个,这些是使用你提供给容器的配置元数据创建的例如,以定义的形式。在容器内部,这些定义被表示为对象,其中包含其他信息以下元数据包限定的类名通常,定义的实际实现类。
Bean概述
Spring IoC容器管理一个或多个bean,这些bean是使用你提供给容器的配置元数据创建的(例如,以XML
在容器内部,这些bean定义被表示为BeanDefinition对象,其中包含(其他信息)以下元数据:
包限定的类名:通常,定义bean的实际实现类。
Bean行为配置元素,它声明Bean在容器中的行为(作用域、生命周期回调,等等)。
对bean执行其工作所需的其他bean的引用,这些引用也称为协作者或依赖项。
要在新创建的对象中设置的其他配置设置 — 例如,池的大小限制或在管理连接池的bean中使用的连接数。
此元数据转换为组成每个bean定义的一组属性,下表描述了这些属性:
属性 | 解释 |
---|---|
Class | 实例化Bean |
Name | 命名Bean |
Scope | Bean作用域 |
构造函数参数 | 依赖注入 |
属性 | 依赖注入 |
自动装配模式 | 自动装配协作者 |
延迟初始化模式 | 延迟初始化Bean |
初始化方法 | 初始化回调 |
销毁方法 | 销毁回调 |
除了包含关于如何创建特定bean的信息的bean定义之外,ApplicationContext实现还允许注册(由用户)在容器外部创建的现有对象,通过getBeanFactory()方法访问ApplicationContext的BeanFactory,该方法返回BeanFactory DefaultListableBeanFactory实现。DefaultListableBeanFactory通过registerSingleton(..)和registerBeanDefinition(..)方法支持这种注册,然而,典型的应用程序只使用通过常规bean定义元数据定义的bean。
Bean元数据和手动提供的单例实例需要尽早注册,以便容器在自动装配和其他内省步骤中正确地推断它们,虽然在某种程度上支持覆盖现有的元数据和现有的单例实例,但是在运行时注册新bean(与对工厂的实时访问同时进行)并不是官方支持的,并且可能会导致并发访问异常、bean容器中不一致的状态,或者两者兼有。命名Bean
每个bean都有一个或多个标识符,这些标识符在承载bean的容器中必须是惟一的,bean通常只有一个标识符,但是,如果需要多个,则可以将额外的标识符视为别名。
在基于XML的配置元数据中,可以使用id属性、name属性或两者都使用来指定bean标识符,id属性允许你精确地指定一个id,通常,这些名称是字母数字("myBean"、"someService"等),但它们也可以包含特殊字符。如果希望为bean引入其他别名,还可以在name属性中指定它们,以逗号(,)、分号(;)或空格分隔。作为历史记录,在Spring 3.1之前的版本中,id属性被定义为xsd:ID类型,这限制了可能的字符,从3.1开始,它被定义为xsd:string类型,注意,bean id惟一性仍然由容器执行,但不再由XML解析器执行。
你不需要为bean提供name或id,如果不显式提供name或id,容器将为该bean生成唯一的名称,但是,如果你希望通过名称引用该bean,通过使用ref元素或服务定位器样式查找,你必须提供一个名称,不提供名称的动机与使用内部bean和自动装配协作者有关。
Bean命名约定约定是在为bean命名时使用标准Java约定作为实例字段名,也就是说,bean名称以小写字母开头,并采用驼峰大小写,此类名称的示例包括accountManager、accountService、userDao、loginController等等。
一致地命名bean使你的配置更容易阅读和理解,另外,如果你使用Spring AOP,当你将advice应用到一组按名称关联的bean时,它会提供很大的帮助。
使用类路径中的组件扫描,Spring按照前面描述的规则为未命名的组件生成bean名称:本质上,取简单的类名并将其初始字符转换为小写,但是,在(不寻常的)特殊情况下,如果有多个字符,并且第一个和第二个字符都是大写的,则保留原来的大小写,这些规则与java.beans.Introspector.decapitalize(Spring在这里使用)定义的规则相同。在Bean定义之外别名化Bean
在bean定义本身中,可以使用id属性指定的最多一个名称和name属性中任意数量的其他名称的组合,为bean提供多个名称。这些名称可以是相同bean的等价别名,在某些情况下非常有用,比如通过使用特定于该组件本身的bean名称,让应用程序中的每个组件引用公共依赖项。
但是,指定实际定义bean的所有别名并不总是足够的,有时需要为在其他地方定义的bean引入别名,在大型系统中,配置通常在每个子系统之间进行划分,每个子系统都有自己的一组对象定义,在基于XML的配置元数据中,可以使用
在这种情况下,在使用别名定义之后,名为fromName的bean(在同一个容器中)也可以称为toName。
例如,子系统A的配置元数据可以通过subsystemA-dataSource的名称引用数据源,子系统B的配置元数据可以通过subsystemB-dataSource的名称引用数据源。在组合使用这两个子系统的主应用程序时,主应用程序通过myApp-dataSource的名称引用数据源,要使所有三个名称都引用同一个对象,可以将以下别名定义添加到配置元数据中:
现在,每个组件和主应用程序都可以通过惟一的名称引用数据源,并且保证不会与任何其他定义冲突(有效地创建名称空间),但是它们引用的是同一个bean。
Java配置实例化Bean如果使用Java配置,可以使用@Bean注解提供别名,有关详细信息,请参见使用@Bean注解。
bean定义本质上是创建一个或多个对象的配方,当被询问时,容器会查看命名bean的配方,并使用该bean定义封装的配置元数据来创建(或获取)一个实际对象。
如果使用基于XML的配置元数据,则要在
通常,在容器本身通过反射调用其构造函数直接创建bean的情况下,指定要构造的bean类,这有点类似于使用new操作符的Java代码。
要指定包含创建对象时调用的static工厂方法的实际类,在不太常见的情况下,容器调用类上的static工厂方法来创建bean,从static工厂方法调用返回的对象类型可以是同一个类,也可以完全是另一个类。
内部类的名字使用构造函数实例化如果要为static嵌套类配置bean定义,必须使用嵌套类的二进制名称。
例如,如果你在com.example包中有一个名为SomeThing类,这个类有一个static嵌套类叫做OtherThing,bean定义上的class属性的值是com.example.SomeThing$OtherThing。
注意,在名称中使用$字符将嵌套的类名与外部类名分隔开。
当你使用构造函数方法创建bean时,所有的普通类都可以被Spring使用并与Spring兼容,也就是说,正在开发的类不需要实现任何特定的接口或以特定的方式编码,只需指定bean类就足够了。但是,根据你为特定bean使用的IoC类型,你可能需要一个默认(空)构造函数。
Spring IoC容器几乎可以管理你希望它管理的任何类,它不仅限于管理真正的JavaBean,大多数Spring用户更喜欢实际的JavaBean,它只有一个默认(无参数)构造函数,以及根据容器中的属性建模的适当的setter和getter。你还可以在容器中包含更多非bean样式的类,例如,如果你需要使用完全不符合JavaBean规范的遗留连接池,Spring也可以很好的管理它。
使用基于XML的配置元数据,你可以指定你的bean类如下:
有关向构造函数提供参数(如果需要)和在构造对象之后设置对象实例属性的机制的详细信息,请参阅注入依赖项。
使用静态工厂方法实例化在定义使用静态工厂方法创建的bean时,使用class属性指定包含static工厂方法的类,使用factory-method属性指定工厂方法本身的名称。你应该能够调用这个方法(带有可选参数,如后面所述)并返回一个活动对象,随后将其视为通过构造函数创建的,这种bean定义的一个用途是在遗留代码中调用static工厂。
下面的bean定义指定通过调用工厂方法创建bean,定义没有指定返回对象的类型(类),只指定包含工厂方法的类,在本例中,createInstance()方法必须是一个静态方法,下面的例子展示了如何指定工厂方法:
下面的例子展示了一个使用前面bean定义的类:
public class ClientService { private static ClientService clientService = new ClientService(); private ClientService() {} public static ClientService createInstance() { return clientService; } }
有关向工厂方法提供(可选)参数并在对象从工厂返回后设置对象实例属性的机制的详细信息,请参阅依赖项和配置。
使用实例工厂方法实例化与通过静态工厂方法实例化类似,使用实例工厂方法实例化将从容器中调用现有bean的非静态方法来创建新bean,要使用此机制,请保留class属性为空,并在factory-bean属性中,在当前(或父或祖先)容器中指定bean的名称,该容器包含要调用来创建对象的实例方法,使用factory-method属性设置工厂方法本身的名称,下面的例子展示了如何配置这样一个bean:
下面的例子显示了相应的Java类:
public class DefaultServiceLocator { private static ClientService clientService = new ClientServiceImpl(); public ClientService createClientServiceInstance() { return clientService; } }
一个工厂类也可以包含多个工厂方法,如下例所示:
下面的例子显示了相应的Java类:
public class DefaultServiceLocator { private static ClientService clientService = new ClientServiceImpl(); private static AccountService accountService = new AccountServiceImpl(); public ClientService createClientServiceInstance() { return clientService; } public AccountService createAccountServiceInstance() { return accountService; } }
这种方法表明,工厂bean本身可以通过依赖项注入(DI)进行管理和配置。
在Spring文档中,“工厂bean”指的是在Spring容器中配置的bean,它通过实例或静态工厂方法创建对象,相反,FactoryBean(注意大小写)指的是特定于spring的FactoryBean。上一篇:容器概述
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/75745.html
摘要:容器概述接口表示容器,负责实例化配置和组装。基于的元数据不是惟一允许的配置元数据形式,容器本身与实际编写配置元数据的格式完全解耦,现在,许多开发人员为他们的应用程序选择基于的配置。 容器概述 org.springframework.context.ApplicationContext接口表示Spring IoC容器,负责实例化、配置和组装bean。容器通过读取配置元数据获取关于要实例化...
摘要:容器和介绍本章介绍了控制反转原理的实现,也称为依赖注入。在中,构成应用程序主干并由容器管理的对象称为,是由容器实例化组装和管理的对象,否则,只是应用程序中的许多对象之一,及其之间的依赖关系反映在容器使用的配置元数据中。 Spring IoC容器和bean介绍 本章介绍了控制反转(IoC)原理的Spring Framework实现,IoC也称为依赖注入(DI)。它是一个过程,对象仅通过构...
摘要:除此之外,还为不同的应用程序体系结构提供了基础支持,包括消息传递事务数据和持久性以及,它还包括基于的框架,以及与之并行的反应性框架。还支持依赖项注入和公共注解规范,应用程序开发人员可以选择使用这些规范,而不是提供的特定于的机制。 概述 Spring使创建Java企业应用程序变得很容易,它提供了在企业环境中使用Java语言所需要的一切,支持Groovy和Kotlin作为JVM上的替代语言...
摘要:注解从版开始,的缓存抽象完全支持标准注解和以及和。使用方法调用的结果更新缓存,要求将其作为使用注解的参数传递给它由于这种差异,允许在实际方法调用之前或之后更新缓存。非常相似,当方法调用导致异常时,支持条件驱逐。 JCache(JSR-107)注解 从4.1版开始,Spring的缓存抽象完全支持JCache标准注解:@CacheResult、@CachePut、@CacheRemove和...
摘要:地址前面一个部分讲解了如何使用工具来测试项目,现在我们讲解如何使用工具来测试项目。所以我们可以利用这个特性来进一步简化测试代码。因为只有这样才能够在测试环境下发现生产环境的问题,也避免出现一些因为配置不同导致的奇怪问题。 Github地址 前面一个部分讲解了如何使用Spring Testing工具来测试Spring项目,现在我们讲解如何使用Spring Boot Testing工具来测...
阅读 2406·2021-10-08 10:17
阅读 1797·2021-09-06 15:02
阅读 2503·2019-08-29 17:30
阅读 2623·2019-08-29 13:24
阅读 1471·2019-08-29 11:12
阅读 3312·2019-08-28 17:52
阅读 629·2019-08-26 11:30
阅读 3545·2019-08-26 11:01