1.Bean概述

(1) Spring IoC容器管理一个或多个bean,这些bean是根据我们所提供的配置元数据来创建的,在容器内部,BeanDefinition对象就代表了bean的配置元数据,它主要包含了如下几个方面的内容:

属性 说明
Class 全限定类名
Name bean的名称
Scope bean的作用域
Constructor arguments 构造函数参数
Properties 成员变量属性值
Autowiring Mode 自动装配模式
Lazy initialization mode 懒加载模式
Initialization Method 初始化回调
Destruction Method 销毁回调

(2) 一般情况下,Spring中的bean来自于Spring的自动扫描解析,除此之外,Spring还允许我们手动的向容器中注册一些额外的对象,如下所示:

ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("boke/definition.xml");
//1.获取ApplicationContext中的BeanFactory
ConfigurableListableBeanFactory beanFactory = ctx.getBeanFactory();
Man man = new Man();
//2.通过beanFactory的registerSingleton方法向容器中注册容器外的额外对象
beanFactory.registerSingleton("man", man);
//3.注册之后,便可获取使用该对象
Man existMan = beanFactory.getBean("man", Man.class);
existMan.doSomething();

总结一下,向Spring IOC容器中注册额外对象,大致可分为两步:

第一步:通过调用ApplicationContext实现类们的getBeanFactory()方法拿到DefaultListableBeanFactory

第二步:调用DefaultListableBeanFactory中的registerSingleton()方法或registerBeanDefinition()来向容器中注册额外对象

注意:在实践上由我们手动注册的bean需要尽早向容器中注册,如果注册的太晚,就无法和Spring所提供的一些步骤结合,会导致一些依赖注入失败

2.命名Bean

(1) Spring中的bean通常有一个唯一的id和多个别名,在基于xml的配置中,可通过bean标签中的id属性和name属性来标识一个bean的id和别名,其中id属性必须唯一,而name属性可不唯一,多个别名之间用分号,逗号或空格分隔开,如下所示:

<!-- xml文件内容 -->
<beans ...>
<!-- 定义了一个bean,它的id为man,别名为thisMan,yesMan -->
<bean class="cn.example.spring.boke.Man" id="man" name="thisMan,yesMan"> </bean>
</beans> //Java代码:
ApplicationContext ctx = new ClassPathXmlApplicationContext("boke/from.xml");
//打印下面这三个Man对象的地址,发现它们的地址相同,为同一对象
Man man = (Man) ctx.getBean("man"), thisMan = (Man) ctx.getBean("thisMan"), yesMan = (Man) ctx.getBean("yesMan");

(2) 在基于Java code的配置中,如使用@Bean,@Component等注解时,id或name属性不是必须提供的,如果都没有,Spring容器会默认提供一个唯一的id(生成规则:通常情况下会按照驼峰命名法取类名并将其首字母小写,但如果类名的第一,二个字符都是大写时,会保留原始大小写),如下所示

//例子一:定义一个bean,未声明它的id或name,此时Spring会自动帮我们生成一个唯一的id,为exampleA
@Component
public class ExampleA {
public void doSomething() {
System.out.println("Hello This is ExampleA");
}
} //从Spring IOC中获取上面这个bean
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext("cn.example.spring");
//使用exampleA这个id来寻找容器中ExampleA对象
ExampleA exampleA = (ExampleA) ctx.getBean("exampleA");
exampleA.doSomething(); //例子二:定义了一个bean,未声明它的id或name,且该类名的第一,二个字符都是大写,此时Spring为其生成的id为IMyService,与类名相同
@Component
public class IMyService {
}
//验证过程省略...

(3) 还可以使用alias标签来定义一个bean的别名,如下

<beans ...>
<bean class="cn.example.spring.boke.ExampleA" id="exampleA"> </bean> <!-- 此时,既可以用exampleA来获取到这个bean,也可以用aliasA来获取这个bean,它俩是等价的 -->
<alias name="exampleA" alias="aliasA"></alias>
</beans>

3.实例化bean

(1) BeanDefinition在本质上就是bean的‘配方表’,容器会根据BeanDefinition中的配置信息来创建出所需要的对象供我们使用,在基于xml的配置中,通过bean标签中的class属性来指定要创建对象的类类型,这个bean标签中的class属性对应于BeanDefanition里的Class属性

(2) 通过美元符号($)或点符号(.)来注册静态内部类,如下

public class Outer {
//注意:这里是‘静态‘内部类
public static class Inner {
public void doSomething() {
System.out.println("Here is inner");
}
}
} <!-- xml文件配置 -->
<beans ...>
<!-- 使用$调用静态内部类 -->
<bean class="cn.example.spring.boke.Outer$Inner" id="inner"></bean> <!-- 使用.调用静态内部类,与上面的等价 -->
<!-- <bean class="cn.example.spring.boke.Outer.Inner" id="inner"></bean> -->
</beans> //使用
ApplicationContext ctx = new ClassPathXmlApplicationContext("boke/from.xml");
//获取已注册到容器中的静态内部类
Outer.Inner inner = (Outer.Inner) ctx.getBean("inner");
inner.doSomething();

(3) 实例化bean的方式

  • 通过构造函数:最常用的方式,无需实现任何特定的接口,只需简单的指定bean的class属性即可,如下所示
<beans ...>
<!-- 此时,Spring会调用无参构造函数来实例化ExampleA对象,因此,请确保ExampleA中有一个无参构造器,否则,Spring会提示报错 -->
<!-- 除了默认的无参构造器外,还可指定某个有参构造器来实例化对象,见后文 -->
<bean id="exxampleA" class="cn.example.spring.boke.ExampleA"></bean>
</beans>
  • 通过静态工厂方法:适用于初始化过程比较复杂的对象
//静态工厂
public class ExampleAFactory {
private static ExampleA exampleA = new ExampleA();
//注意:这里必须是'静态'工厂方法
public static ExampleA createInstance() {
return exampleA;
}
} <!-- xml文件配置 -->
<beans ...>
<!-- class属性指定工厂类,factory-method属性指定它的静态工厂方法,Spring会调用这个工厂方法来创建并注册所需的对象 -->
<bean id="exampleA" class="cn.example.spring.boke.ExampleAFactory" factory-method="createInstance"></bean>
</beans> //使用,与普通的bean没什么不同
ApplicationContext ctx = new ClassPathXmlApplicationContext("boke/from.xml");
ExampleA exampleA = (ExampleA)ctx.getBean("exampleA");
  • 通过实例工厂方法:与静态工厂类似,不过要先注册一个实例工厂bean
//实例工厂
public class ExampleAFactory {
private static ExampleA exampleA = new ExampleA();
//这里是实例方法,注意与上面的静态工厂方法区分
public ExampleA createInstance() {
return exampleA;
}
} <!-- xml文件配置 -->
<beans ...>
<!-- 1.首先要注册一个实例工厂bean -->
<bean id="factory" class="cn.example.spring.boke.ExampleAFactory"></bean>
<!-- 2.factory-bean指定上面这个实例工厂bean,factory-method指定它的实例方法,之后Spring会调用这个实例方法来创建并注册所需的对象 -->
<bean id="exampleA" factory-bean="factory" factory-method="createInstance"></bean>
</beans> //此时容器有两个bean,一个是实例工厂,一个实例工厂所生产的对象
ApplicationContext ctx = new ClassPathXmlApplicationContext("boke/from.xml");
//工厂
ExampleAFactory factory = (ExampleAFactory)ctx.getBean("factory");
ExampleA exampleA = (ExampleA)ctx.getBean("exampleA");

4.确定bean的类型

(1) 通过执行调用BeanFactory.getType方法,来获取到某个特定bean的类型,如下

ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("boke/from.xml");
Class clazz = ctx.getBeanFactory().getType("exampleA");

Spring IOC官方文档学习笔记(二)之Bean概述的更多相关文章

  1. Spring Framework 官方文档学习(二)之IoC容器与bean lifecycle

    到目前为止,已经看了一百页.再次感慨下,如果想使用Spring,那可以看视频或者找例子,但如果想深入理解Spring,最好还是看官方文档. 原计划是把一些基本接口的功能.层次以及彼此的关系罗列一下.同 ...

  2. Spring Boot 官方文档学习(二)特点

    一.SpringApplication banner,就是启动时输出的信息,可以在classpath下添加 banner.txt,或者设置 banner.location 来指向特定的文件.(默认编码 ...

  3. Vue.js官方文档学习笔记(二)组件化应用的构建

    组件化应用的构建 组件化应用允许我们使用小型.独立和通常可复用的组件构建大型应用. Vue注册组件 Vue.component('todo-item',{template:'<li>这是个 ...

  4. Spring 4 官方文档学习(十二)View技术

    关键词:view technology.template.template engine.markup.内容较多,按需查用即可. 介绍 Thymeleaf Groovy Markup Template ...

  5. Spring Framework 官方文档学习(四)之Validation、Data Binding、Type Conversion(二)

    接前一篇 Spring Framework 官方文档学习(四)之Validation.Data Binding.Type Conversion(一) 本篇主要内容:Spring Type Conver ...

  6. Spring 4 官方文档学习(十一)Web MVC 框架

    介绍Spring Web MVC 框架 Spring Web MVC的特性 其他MVC实现的可插拔性 DispatcherServlet 在WebApplicationContext中的特殊的bean ...

  7. Spring Boot 官方文档学习(一)入门及使用

    个人说明:本文内容都是从为知笔记上复制过来的,样式难免走样,以后再修改吧.另外,本文可以看作官方文档的选择性的翻译(大部分),以及个人使用经验及问题. 其他说明:如果对Spring Boot没有概念, ...

  8. Spring Framework 官方文档学习(四)之Validation、Data Binding、Type Conversion(一)

    题外话:本篇是对之前那篇的重排版.并拆分成两篇,免得没了看的兴趣. 前言 在Spring Framework官方文档中,这三者是放到一起讲的,但没有解释为什么放到一起.大概是默认了读者都是有相关经验的 ...

  9. Spring boot官方文档学习(一)

    个人说明:本文内容都是从为知笔记上复制过来的,样式难免走样,以后再修改吧.另外,本文可以看作官方文档的选择性的翻译(大部分),以及个人使用经验及问题. 其他说明:如果对Spring Boot没有概念, ...

  10. Spring Framework 官方文档学习(四)之Validation、Data Binding、Type Conversion

    本篇太乱,请移步: Spring Framework 官方文档学习(四)之Validation.Data Binding.Type Conversion(一) 写了删删了写,反复几次,对自己的描述很不 ...

随机推荐

  1. Docker容器获取宿主机信息

    最近在做产品授权的东西,开始宿主机为Window,程序获取机器硬件信息相对简单些,后来部署时发现各种各样的的环境问题,所有后来改用dokcer部署,docker方式获取宿主机信息时花了些时间,特此记录 ...

  2. 1、使用简单工厂模式设计能够实现包含加法(+)、减法(-)、乘法(*)、除法(/)四种运算的计算机程序,要求输入两个数和运算符,得到运算结果。要求使用相关的工具绘制UML类图并严格按照类图的设计编写程

    1.使用简单工厂模式设计能够实现包含加法(+).减法(-).乘法(*).除法(/)四种运算的计算机程序,要求输入两个数和运算符,得到运算结果.要求使用相关的工具绘制UML类图并严格按照类图的设计编写程 ...

  3. File常用的方法操作、在磁盘上创建File、获取指定目录下的所有文件、File文件的重命名、将数据写入File文件

    文章目录 1.基本介绍 2.构造方法 3.常用的方法 4.代码实例 4.1 创建文件和目录(目录不存在) 4.1.1 代码 4.1.2 测试结果 4.2 测试目录存在的情况.直接写绝对的路径名 4.2 ...

  4. .net core-利用PdfSharpCore和SkiaSharp.QrCode 添加PDF二维码页眉

    前序 由于去年的一个项目需要在PDF 添加公司二维码 ,当时在网上找了很多操作PDF方案,第一种Aspose.PDF,很遗憾 Aspose.PDF 有添加版权的背景还是页脚我忘记了,不适合公司项目,最 ...

  5. 十一、Pod的健康检查-探针

    Pod 的健康检查-探针 一.Pod 的健康检查-探针 1.1.探针基本概念 ​探针是由 kubelet 对容器执行的定期诊断.要执行诊断,kubelet 调用由容器实现的 Handler 有三种类型 ...

  6. Workflow,要不要了解一下

    摘要:Workflow本质是开发者基于实际业务场景开发用于部署模型或应用的流水线工具. Workflow(也称工作流,下文中均可使用工作流进行描述)本质是开发者基于实际业务场景开发用于部署模型或应用的 ...

  7. JS逆向实战2--cookie-AcwScV2加密—某招标信息网

    cookies的获取 首先拿到第一次访问原链接 拿到acw_tc的值,然后放到session中去 再用这个session再次访问原链接拿到js加载的加密的真实数据.用了一些反混淆. 最后获取这个数据中 ...

  8. Linux--网络基础(概念+协议的了解+OSI七层模型,TCP/IP五层协议,网络数据传输流程)

    网络的发展 网络的发展有下面几个阶段: 独立模式:计算机最开始是以单机模式被广泛使用的.每一台计算机都是独立的,之间不能够进行数据共享与通信 网络互联: 计算机之间可以链接在一起,完成数据共享,计算机 ...

  9. 云原生之旅 - 8)云原生时代的网关 Ingress Nginx

    前言 当我们在Kubernetes部署的服务需要暴露给外部用户使用时,有三种选择:LoadBalancer,NodePort, Ingress. LoadBalancer类型得结合各个Cloud Pr ...

  10. Oracle pfile与spfile文件参数(转载)

    一.pfile与spfile Oracle中的参数文件是一个包含一系列参数以及参数对应值的操作系统文件.它们是在数据库实例启动时候加载的,决定了数据库的物理 结构.内存.数据库的限制及系统大量的默认值 ...