一般情况下, Spring是通过反射机制利用bean的class属性指定实现类来完成实例化bean的。在某些特定的情况下, 想做一些定制,Spring为此提供了一个org.springframework.beans.factory.FactoryBean的工厂类接口, 用户可以通过实现该接口定制实例化bean的逻辑。

Spring从3.0开始, FactoryBean开始支持泛型, 即接口声明改为: FactoryBean<T> 的形式。

 package org.springframework.beans.factory;

 public interface FactoryBean<T> {

     /**
*
* @return 返回由FactoryBean创建的bean实例, 如果isSingleton()返回true, 则该实例则会放到Spring容器单实例缓存池中
* @throws Exception
*/
T getObject() throws Exception; /**
*
* @return 返回FactoryBean创建Bean的类型
*/
Class<?> getObjectType(); /**
*
* @return 返回有FactoryBean创建的bean实例的作用域是singleten还是prototype
*/
boolean isSingleton();
}

Action

创建一个pojo类<Car>。

 /**
* @filename: Car.java
* @author: Wang Chinda
* @date: 2018-05-22
* @version: v1.0
* @modify_history: -
* 20180522 Wang Chinda create
* 20180522 Wang Chinda modify method()
*/
package com.itdoc.learn.source.factory; /**
* @desc FactoryBean 的使用
* @author Wang Chinda
* @create 2018-05-22 16:07
*/
public class Car {
/** 最大速度 */
private int maxSpeed;
/** 品牌 */
private String brand;
/** 价钱 */
private double price; public int getMaxSpeed() {
return maxSpeed;
} public void setMaxSpeed(int maxSpeed) {
this.maxSpeed = maxSpeed;
} public String getBrand() {
return brand;
} public void setBrand(String brand) {
this.brand = brand;
} public double getPrice() {
return price;
} public void setPrice(double price) {
this.price = price;
} @Override
public String toString() {
return "Car{" +
"maxSpeed=" + maxSpeed +
", brand='" + brand + '\'' +
", price=" + price +
'}';
}
}

创建一个定制实例化bean逻辑的类<CarFactoryBean>:

 /**
* @filename: CarFactoryBean.java
* @author: Wang Chinda
* @date: 2018-05-22
* @version: v1.0
* @modify_history: -
* 20180522 Wang Chinda create
* 20180522 Wang Chinda modify method()
*/
package com.itdoc.learn.source.factory; import org.springframework.beans.factory.FactoryBean; /**
* @desc FactoryBean测试的工厂类
* @author Wang Chinda
* @create 2018-05-22 16:17
*/
public class CarFactoryBean implements FactoryBean<Car> { /** 车的详细信息 */
private String carInfo; @Override
public Car getObject() throws Exception {
Car car = new Car();
String[] infos = carInfo.split(",");
car.setBrand(infos[0].trim());
car.setMaxSpeed(Integer.valueOf(infos[1].trim()));
car.setPrice(Double.valueOf(infos[2].trim()));
return car;
} @Override
public Class<Car> getObjectType() {
return Car.class;
} @Override
public boolean isSingleton() {
return false;
} public String getCarInfo() {
return carInfo;
} public void setCarInfo(String carInfo) {
this.carInfo = carInfo;
}
}

配置xml<car-factory-bean.xml>:

 <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="car" class="com.itdoc.learn.source.factory.CarFactoryBean">
<property name="carInfo" value="超级跑车, 400, 300000000"></property>
</bean> </beans>

测试<Car>:

 /**
* @filename: CarClient.java
* @author: Wang Chinda
* @date: 2018-05-22
* @version: v1.0
* @modify_history: -
* 20180522 Wang Chinda create
* 20180522 Wang Chinda modify method()
*/
package com.itdoc.learn.source.factory; import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; /**
* @desc FactoryBean使用测试客户端入口
* @author Wang Chinda
* @create 2018-05-22 16:27
*/
public class CarClient {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("test/car-factory-bean.xml");
Car car = (Car) applicationContext.getBean("car");
System.out.println(car);
}
}

控制台打印:

流程分析:

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

从缓存中或者singletonFactories中的ObjectFactory中获取共享实例。

Object sharedInstance = getSingleton(beanName);

bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); 获取对应实例。

强制将共享实例转化成FactoryBean。FactoryBean<?> factory = (FactoryBean<?>) beanInstance;

object = getObjectFromFactoryBean(factory, beanName, !synthetic); 在FactoryBean中获取bean实例。

doGetObjectFromFactoryBean(factory, beanName, shouldPostProcess);

调用getObject()方法,object = factory.getObject();

返回实例bean。

GitHub源码: https://github.com/wcd19901010/spring-01

最新文章

  1. win10 设置声卡驱动 --- 解决喇叭没有声音!
  2. mac+php+xdebug+phpstorm在苹果下配置xdebug一波三折
  3. postgresql命令行
  4. 30个php操作redis常用方法代码例子
  5. 十五、mysql 分区之 分区管理
  6. 利用autoit自动关闭指定标题窗口
  7. Linux内核IP层的报文处理流程(一)
  8. spring集成quartz
  9. Linux配置SSH端口以及密钥登录
  10. 树形dp总结
  11. ios开发-指纹识别
  12. C# 离线人脸识别Demo 使用ArcFace 2.0开发完成
  13. p1313计算系数题解
  14. Lua require 相对路径
  15. Java密码体系结构简介:Java Cryptography Architecture (JCA) Reference Guide
  16. Unity3D学习笔记(十八):动画内容补充
  17. django url 使用总结
  18. springmvc+json 前后台数据交互
  19. [JQuery插件系列]-强烈推荐10个非常不错的jQuery工具提示插件
  20. SpringApplicationConfiguration 这个不能用 解决方案

热门文章

  1. ES6的新特性(6)——正则的扩展
  2. centos上搭建git服务--3
  3. 由A到D中间可不止“B、C”
  4. &quot;Hello World&quot;团队召开的第三周第七次会议
  5. pat甲级1002
  6. 2018软工实践—Alpha冲刺(2)
  7. 【线段树求区间第一个不大于val的值】Lpl and Energy-saving Lamps
  8. 【IdentityServer4文档】- 使用密码保护 API
  9. WebForm与MVC模式优缺点
  10. Linux下编译程序时,经常会遇到“undefined reference to XXX” 报错,