创建Bean的三种方式
在大多数情况下,Spring容器直接通过new关键字调用构造器来创建Bean实例,而class属性指定Bean实例的实现类,但这不是实例化Bean的唯一方法。实际上,Spring支持使用以下三种方式来创建Bean:
(1)调用构造器创建Bean
(2)调用静态工厂方法创建Bean
(3)调用实例工厂方法创建Bean
一 构造器创建Bean实例
如果不采用构造注入,Spring底层会调用Bean类的无参数构造器来创建实例,因此该类必须要提供无参数的构造器,并且class属性的值就是该Bean实例的实现类。Spring对Bean实例的所有属性执行默认初始化,即所有基本类型的值初始化为0或false,所有引用类型的值初始化为null。BeanFactory会根据配置文件决定依赖关系,先实例化所依赖的Bean实例,然后为Bean注入依赖关系,最后将一个完整的Bean实例返回给程序。
如果采用构造注入,则使用<constructor-arg>配置一个构造器参数,Spring容器将使用带对应参数的构造器来创建Bean实例,Spring调用构造器传入的参数即可用于初始化Bean的实例变量,最后也将一个完整的Bean实例返回给程序。
二 使用静态工厂方法创建Bean
采用静态工厂方法创建Bean实例时,<bean>元素需要指定两个属性:
class:值为静态工厂类的类名
factory-method:指定静态工厂方法来生产Bean实例
如果静态工厂方法需要参数,则使用<constructor-arg>元素传入。
Being.java
public interface Being {
public void testBeing();
}
Dog.java
public class Dog implements Being {
public void setMsg(String msg) {
this.msg = msg;
}
private String msg;
@Override
public void testBeing() {
System.out.println(msg+",狗爱啃骨头");
}
}
Cat.java
public class Cat implements Being {
public void setMsg(String msg) {
this.msg = msg;
}
private String msg;
@Override
public void testBeing() {
System.out.println(msg+",猫喜欢吃老鼠");
}
}
BeingFactory.java
BeingFactory工厂包含了一个getBeing()静态方法,该静态方法用于返回Being实例。
public class BeingFactory {
public static Being getBeing(String arg){
if(arg.equalsIgnoreCase("dog")){
return new Dog();
}else{
return new Cat();
}
}
}
BeingFactory类是一个静态工厂类,该类的getBeing()方法是一个静态工厂方法,该方法传入的参数决定返回Cat对象,还是Dog对象。
public class BeingFactory {
public static Being getBeing(String msg){
if(msg.equalsIgnoreCase("dog")){
return new Dog();
}else{
return new Cat();
}
}
}
ApplicationContext.xml
//以下配置会驱动Spring调用BeingFactory的静态getBeing()方法来创建Bean,该Bean元素包含的constructor-arg元素用于为静态工厂方法指定参数
<bean id="dog" class="SpringTest.BeingFactory" factory-method="getBeing">
<constructor-arg value="dog" />
//驱动Spring以"狗呢"为参数来执行dog的setMsg()方法
<property name="msg" value="狗呢" />
</bean>

<bean id="cat" class="SpringTest.BeingFactory" factory-method="getBeing">
<constructor-arg value="cat" />
<property name="msg" value="猫呢" />
</bean>
测试:
public class MainTest {
public static void main(String[] args) {
ClassPathXmlApplicationContext ctx=new ClassPathXmlApplicationContext("SpringTest/ApplicationContext.xml");
Being b1=ctx.getBean("dog",Being.class);
b1.testBeing();
Being b2=ctx.getBean("cat",Being.class);
b2.testBeing();
ctx.close();
}
}
结果:狗呢,狗爱啃骨头
猫呢,猫喜欢吃老鼠
一旦为<bean>元素指定了factory-method属性,Spring就不再调用构造器来创建Bean实例,而是调用工厂方法来创建Bean实例。如果同时指定了class和factory-method两个属性,Spring就会调用静态工厂方法来创建Bean。
Spring将先解析配置文件,并根据配置文件指定的信息,通过反射调用静态工厂类的静态工厂方法,将该静态工厂方法的返回值作为Bean实例。在这个过程中,Spring不再负责创建Bean实例,Bean实例是由用户提供的静态工厂类负责创建的。
三 调用实例工厂方法创建Bean
实例工厂方法与静态工厂方法只有一点不同:调用静态工厂方法只需要使用工厂类即可,而调用实例工厂方法则需要工厂实例。所以在配置时,静态工厂方法使用class指定静态工厂类,实例工厂方法使用factory-bean指定工厂实例。
采用实例工厂方法创建Bean的<bean>元素时需要指定两个属性:
factory-bean:工厂bean的id
factory-method:实例工厂的工厂方法
修改BeanFactory.java和AppliactionContext.xml
BeanFactory.java
public class BeingFactory {
public Being getBeing(String msg){
if(msg.equalsIgnoreCase("dog")){
return new Dog();
}else{
return new Cat();
}
}
}
ApplicationContext.xml
<bean id="beingFactory" class="SpringTest.BeingFactory" />
<bean id="dog" factory-bean="beingFactory" factory-method="getBeing">
<constructor-arg value="dog" />
</bean>

<bean id="cat" factory-bean="beingFactory" factory-method="getBeing">
<constructor-arg value="cat" />
</bean>

Spring三 Bean的三种创建方式的更多相关文章

  1. Spring中bean的四种注入方式

    一.前言   最近在复习Spring的相关内容,这篇博客就来记录一下Spring为bean的属性注入值的四种方式.这篇博客主要讲解在xml文件中,如何为bean的属性注入值,最后也会简单提一下使用注解 ...

  2. Spring装配Bean的三种方式+导入和混合配置

    目录 Spring IoC与bean 基于XML的显式装配 xml配置的基本结构 bean实例的三种创建方式 依赖注入的两种方式 构造器注入方式 setter方法注入方式 利用命名空间简化xml 基于 ...

  3. Struts2之命名空间与Action的三种创建方式

    看到上面的标题,相信大家已经知道我们接下来要探讨的知识了,一共两点:1.package命名空间设置:2.三种Action的创建方式.下面我们开始本篇的内容: 首先我们聊一聊命名空间的知识,namesp ...

  4. JavaScript 闭包的详细分享(三种创建方式)(附小实例)

    JavaScript闭包的详细理解 一.原理:闭包函数--指有权访问私有函数里面的变量和对象还有方法等:通俗的讲就是突破私有函数的作用域,让函数外面能够使用函数里面的变量及方法. 1.第一种创建方式 ...

  5. 2019年6月14日 Web框架之Django_07 进阶操作(MTV与MVC、多对多表三种创建方式、前后端传输数据编码格式contentType、ajax、自定义分页器)

    摘要 MTV与MVC 多对多表三种创建方式 ajax ,前后端传输数据编码格式contentType 批量插入数据和自定义分页器 一.MVC与MTV MVC(Model View Controller ...

  6. Django多对多表的三种创建方式,MTV与MVC概念

    MTV与MVC MTV模型(django): M:模型层(models.py) T:templates V:views MVC模型: M:模型层(models.py) V:视图层(views.py) ...

  7. Django-多对多关系的三种创建方式-forms组件使用-cookie与session-08

    目录 表模型类多对多关系的三种创建方式 django forms 组件 登录功能手写推理过程 整段代码可以放过来 forms 组件使用 forms 后端定义规则并校验结果 forms 前端渲染标签组件 ...

  8. django----多对多三种创建方式 form组件

    目录 多对多三种创建方式 全自动 全手动 半自动 form组件 基本使用 form_obj 及 is_valid() 前端渲染方式 取消前端自动校验 正则校验 钩子函数(Hook方法) cleaned ...

  9. Django框架(十)--ORM多对多关联关系三种创建方式、form组件

    多对多的三种创建方式 1.全自动(就是平常我们创建表多对多关系的方式) class Book(models.Model): title = models.CharField(max_length=32 ...

  10. 多对多三种创建方式、forms组件、cookies与session

    多对多三种创建方式.forms组件.cookies与session 一.多对多三种创建方式 1.全自动 # 优势:不需要你手动创建第三张表 # 不足:由于第三张表不是你手动创建的,也就意味着第三张表字 ...

随机推荐

  1. js Dom树结构分析

    对Dom数结构的理解,对用js操作html元素有很大的意义 先来看一下下面这段html代码:(这里就以分析body中的元素来解释,因为我们基本所有的操作基本都围绕body标签来做的) <!DOC ...

  2. VMware虚拟机中如何安装VMWare-Tools详解

    VMware虚拟机中如何安装VMWare-Tools详解 好处:可以支持图形界面,可以支持共享文件功能等 VMware虚拟机中如何配置显 VMware作为一款虚拟机利器,很多人都利用它来实现Linux ...

  3. vertical-align的深入学习

    W3C官方对vertical-align属性的定义有4个方面:    (1)vertical-align属性用于定义“周围的文字.inline元素以及inline-block元素”相对于该元素基线的垂 ...

  4. 让IE8兼容问题,参考文档bootstrap

    问题:制作的页面基本没啥问题,只有IE8不好使 参考文档:bootstrap官网 方案一 方案二

  5. 转 C#开发微信门户及应用(1)--开始使用微信接口

    微信应用如火如荼,很多公司都希望搭上信息快车,这个是一个商机,也是一个技术的方向,因此,有空研究下.学习下微信的相关开发,也就成为日常计划的重要事情之一了.本系列文章希望从一个循序渐进的角度上,全面介 ...

  6. 一次 php nusoap 调试过程

    今天跟同事调用一个数据api ,用soap方式调用.本以为很简单的事情,却弄到了晚上. 因为有过调试经验,直接按照以往的过程直接部署,结果是错误. 1. 以为是调用方式错了,问了一下对接的同事,没问题 ...

  7. odoo9 install

    odoo9 的安装需要 nodejs 的 lessc 命令. 需要先安装nodejs 后,使用nmp(nodejs的一个包管理工具) 安装lessc等功能. window 1:安装nodejs. 安装 ...

  8. linux c++ 遍历一个目录下的文件名 (包括子目录的文件名)

    最近写代码有一个要遍历目录下的每一个文件并取得这个文件的绝对路径的需求, 我们知道linux c++中有system命令所以我在代码中 先生成了一个log,然后去读log文件的每一行文件名,然后给存储 ...

  9. 2016030102 - Ubuntu软件安装与删除相关命令

    apt-get, dkpg 常用命令: 安装软件命令: apt-get install softname1 softname2 softname3…… 卸载软件命令: apt-get remove s ...

  10. 关于Keil的安装与注册

    由于前一段时间一直在做关于stm32f407的相关内容,于是安装的Keil是MDK5,最近一阵子想再看看51单片机以前没有做过的内容,就要再安装一个Keil C51,结果就不可避免的遇到了两个软件必须 ...