spring共提供了三种实例化bean的方式:构造器实例化(全类名,反射)、工厂方法(静态工厂实例化   动态工厂实例化)和FactoryBean ,下面一一详解:

1、构造器实例化

City.java

 package com.proc.bean;

 public class City {

     private String name;
private String code; public City() {
} public City(String name, String code) {
this.name = name;
this.code = code;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getCode() {
return code;
} public void setCode(String code) {
this.code = code;
} @Override
public String toString() {
return "City [name=" + name + ", code=" + code + "]";
}
}

通过构造方式配置Bean

 <bean id="city" class="com.proc.bean.City">
<constructor-arg value="北京"/>
<constructor-arg value="BJ"/>
</bean>

测试代码

 ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
City city=ctx.getBean("city", City.class);
System.out.println(city);

输出结果

City [name=北京, code=BJ]

2、静态工厂实例化

  先创建一个静态工厂StaticCityFactory

 package com.proc.bean;

 import java.util.HashMap;
import java.util.Map; public class StaticCityFactory { private static Map<String, City> cities; static{
cities=new HashMap<String, City>();
cities.put("BJ", new City("北京", "BJ"));
cities.put("SH", new City("上海", "SH"));
cities.put("CD", new City("成都", "CD"));
cities.put("SZ", new City("深圳", "SZ"));
} public static City getCity(String code){
return cities.get(code);
}
}

  配置bean

 <!-- 通过静态工厂实例化对象
class:静态工厂类型
factory-method:静态工厂静态方法名称
constructor-arg:为静态工厂方法指定参数
-->
<bean id="city" class="com.proc.bean.StaticCityFactory" factory-method="getCity">
<constructor-arg value="BJ"/>
</bean>

3、动态工厂实例化

  先创建一个实例化工厂

 package com.proc.bean;

 import java.util.HashMap;
import java.util.Map; public class InstanceCityFactory { private Map<String, City> cities;
{
cities=new HashMap<String, City>();
cities.put("BJ", new City("北京", "BJ"));
cities.put("SH", new City("上海", "SH"));
cities.put("CD", new City("成都", "CD"));
cities.put("SZ", new City("深圳", "SZ"));
} public City getCity(String code){
return cities.get(code);
}
}

  配置

 <!-- 配置实例化工厂 -->
<bean id="cityFacotry" class="com.proc.bean.InstanceCityFactory"/> <!-- 通过实例化工厂获取对象 -->
<bean id="city" factory-bean="cityFacotry" factory-method="getCity">
<constructor-arg value="SH"/> <!-- 配置参数 -->
</bean>

4、FactoryBean

  

一般情况下,Spring 通过反射机制利用 <bean> 的 class 属性指定实现类实例化 Bean ,在某些情况下,实例化 Bean 过程比较复杂,如果按照传统的方式,则需要在 <bean> 中提供大量的配置信息。配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。 Spring 为此提供了一个org.springframework.bean.factory.FactoryBean 的工厂类接口,用户可以通过实现该接口定制实例化 Bean 的逻辑。

  FactoryBean接口对于 Spring 框架来说占用重要的地位, Spring 自身就提供了 70 多个 FactoryBean 的实现。它们隐藏了实例化一些复杂 Bean 的细节,给上层应用带来了便利。从 Spring 3.0 开始, FactoryBean 开始支持泛型,即接口声明改为 FactoryBean<T> 的形式:

 public interface FactoryBean<T> {
T getObject() throws Exception;
Class<?> getObjectType();
boolean isSingleton();
}

  在该接口中还定义了以下3 个方法:

    T getObject():返回由 FactoryBean 创建的 Bean 实例,如果 isSingleton() 返回 true ,则该实例会放到Spring 容器中单实例缓存池中;

    boolean isSingleton():返回由 FactoryBean 创建的 Bean 实例的作用域是 singleton 还是 prototype ;

    Class<T> getObjectType():返回 FactoryBean 创建的 Bean 类型。

  当配置文件中<bean> 的 class 属性配置的实现类是 FactoryBean 时,通过 getBean() 方法返回的不是FactoryBean 本身,而是 FactoryBean#getObject() 方法所返回的对象,相当于 FactoryBean#getObject() 代理了getBean() 方法。

  例:如果使用传统方式配置下面Car 的 <bean> 时, Car 的每个属性分别对应一个 <property> 元素标签。

 public class Car {
private int maxSpeed;
private String brand;
private double price;
public int getMaxSpeed() {
return this.maxSpeed;
}
public void setMaxSpeed(int maxSpeed) {
this.maxSpeed = maxSpeed;
}
public String getBrand() {
return this.brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public double getPrice() {
return this.price;
}
public void setPrice(double price) {
this.price = price;
}
}

  如果用FactoryBean 的方式实现就灵活点,下例通过逗号分割符的方式一次性的为 Car 的所有属性指定配置值:

public class CarFactoryBean implements FactoryBean<Car> {
private String carInfo;
public Car getObject() throws Exception {
Car car = new Car();
String[] infos = carInfo.split(",");
car.setBrand(infos[0]);
car.setMaxSpeed(Integer.valueOf(infos[1]));
car.setPrice(Double.valueOf(infos[2]));
return car;
}
public Class<Car> getObjectType() {
return Car.class;
}
public boolean isSingleton() {
return false;
}
public String getCarInfo() {
return this.carInfo;
}
// 接受逗号分割符设置属性信息
public void setCarInfo(String carInfo) {
this.carInfo = carInfo;
}
}

  有了这个CarFactoryBean 后,就可以在配置文件中使用下面这种自定义的配置方式配置 Car Bean 了:

 <bean id="car" class="com.baobaotao.factorybean.CarFactoryBean">
<property name="carInfo" value="法拉利 ,400,2000000"/>
</bean>

  当调用getBean("car") 时, Spring 通过反射机制发现 CarFactoryBean 实现了 FactoryBean 的接口,这时Spring 容器就调用接口方法 CarFactoryBean#getObject() 方法返回。如果希望获取 CarFactoryBean 的实例,则需要在使用 getBean(beanName) 方法时在 beanName 前显示的加上 "&" 前缀:如 getBean("&car");

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

  1. spring ioc三种注入方式

    spring ioc三种注入方式 IOC ,全称 (Inverse Of Control) ,中文意思为:控制反转 什么是控制反转? 控制反转是一种将组件依赖关系的创建和管理置于程序外部的技术. 由容 ...

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. java中的多线程 // 基础

    java 中的多线程 简介 进程 : 指正在运行的程序,并具有一定的独立能力,即 当硬盘中的程序进入到内存中运行时,就变成了一个进程 线程 : 是进程中的一个执行单元,负责当前程序的执行.线程就是CP ...

  2. flex弹性盒子

    注意事项 1.设为Flex布局之后,子元素的float,clear和vertical-align属性都讲失效 2.采用Flex布局的元素,称为Flex容器(Flex container),所有的子元素 ...

  3. Java中文件与字节数组转换

    注:来源于JavaEye 文件转化为字节数组: http://www.javaeye.com/topic/304980 /** * 文件转化为字节数组 * * @param file * @retur ...

  4. PSCollectionView瀑布流实现

    [-] 一基本原理 二具体实现 相关数据结构 视图更新方式 relayoutViews方法 removeAndAddCellsIfNecessary方法 select方法 重用数据块视图机制 三使用方 ...

  5. LM27313 (ACTIVE) 具有 30V 内部 FET 开关(采用 SOT-23 封装)的 1.6 MHz 升压转换器

    The LM27313 switching regulator is a current-mode boost converter with a fixed operating frequency o ...

  6. warning: suggest parentheses around assignment used as truth value

    编译时的警告如下:

  7. 对于矩阵的理解-- by 孟岩老师

    “如果不熟悉线性代数的概念,要去学习自然科学,现在看来就和文盲差不多.” --瑞典数学家Lars Garding名著<Encounter with Mathematics>. 1. 矩阵的 ...

  8. Alert Messager

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  9. CSS学习要点

    目标 掌握CSS基本语法,了解如何应用CSS到Html元素上并能熟练使用CSS进行元素布局. 要点 CSS基本概念.存在的意义 CSS 指层叠样式表 (Cascading Style Sheets), ...

  10. GPGPU OpenCL Reduction操作与group同步

    Reduction操作:规约操作就是由多个数生成一个数,如求最大值.最小值.向量点积.求和等操作,都属于这一类操作. 有大量数据的情况下,使用GPU进行任务并行与数据并行,可以收到可好的效果. gro ...