Spring 通过工厂方法(Factory Method)来配置bean
在spring的世界中, 我们通常会利用bean config file 或者 annotation注解方式来配置bean.
在第一种利用bean config file(spring xml)方式中, 还包括如下三小类
反射模式
工厂方法模式(本文重点)
Factory Bean模式
其中反射模式最常见, 我们需要在bean 配置中指明我们需要的bean object的全类名。
例如:
<bean id="car1" class="com.home.factoryMethod.Car"> <property name="id" value="1"></property> <property name="name" value="Honda"></property> <property name="price" value="300000"></property> </bean>
上面bean 里面的class属性就是全类名, Spring利用Java反射机制创建这个bean。
Factory方法模式
本文介绍的是另1种模式, 在工厂方法模式中, Spring不会直接利用反射机制创建bean对象, 而是会利用反射机制先找到Factory类,然后利用Factory再去生成bean对象。
而Factory Mothod方式也分两种, 分别是静态工厂方法 和 实例工厂方法。
静态工厂方法方式
所谓镜头静态工厂方式就是指Factory类不本身不需要实例化, 这个Factory类中提供了1个静态方法来生成bean对象
下面是例子
bean类Car
首先我们定义1个bean类Car
package com.home.factoryMethod;public class Car { private int id; private String name; private int price; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } @Override public String toString() { return "Car [id=" + id + ", name=" + name + ", price=" + price + "]"; } public Car(){ } public Car(int id, String name, int price) { super(); this.id = id; this.name = name; this.price = price; } }
然后我们再定义1个工厂类CarStaticFactory
package com.home.factoryMethod;import java.util.HashMap;
import java.util.Map;public class CarStaticFactory { private static Map<Integer, Car> map = new HashMap<Integer,Car>(); static{ map.put(1, new Car(1,"Honda",300000)); map.put(2, new Car(2,"Audi",440000)); map.put(3, new Car(3,"BMW",540000)); } public static Car getCar(int id){ return map.get(id); } }
里面定义了1个静态的bean 容器map. 然后提供1个静态方法根据Car 的id 来获取容器里的car对象。
xml配置
<!-- Static Factory method:class: the class of Factoryfactory-method: method of get Bean Objectconstructor-arg: parameters of factory-method--><bean id="bmwCar" class="com.home.factoryMethod.CarStaticFactory" factory-method="getCar"> <constructor-arg value="3"></constructor-arg> </bean> <bean id="audiCar" class="com.home.factoryMethod.CarStaticFactory" factory-method="getCar"> <constructor-arg value="2"></constructor-arg> </bean>
可以见到, 利用静态工厂方法定义的bean item种, class属性不在是bean的全类名, 而是静态工厂的全类名, 而且还需要指定工厂里的 getBean 静态方法名字和参数
客户端代码
public static void h(){ApplicationContext ctx = new ClassPathXmlApplicationContext("bean-factoryMethod.xml"); Car car1 = (Car) ctx.getBean("bmwCar"); System.out.println(car1); car1 = (Car) ctx.getBean("audiCar"); System.out.println(car1); }
输出
May 30, 2016 11:17:45 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@43765ab3: startup date [Mon May 30 23:17:45 CST 2016]; root of context hierarchy May 30, 2016 11:17:46 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions INFO: Loading XML bean definitions from class path resource [bean-factoryMethod.xml] Car [id=3, name=BMW, price=540000] Car [id=2, name=Audi, price=440000]
- 1
小结
由上面的例子, 静态工厂方法方式是非常适用于作为1个bean容器(集合的), 只不过吧bean集合定义在工厂类里面而不是bean config file里面。 缺点也比较明显, 把数据写在class里面而不是配置文件中违反了我们程序猿的常识和spring的初衷。当然优点就是令到令人恶心的bean config file更加简洁啦。
实例工厂方法方式
所谓实例工厂方式也很容易看懂, 就是里面的getBean 方法不是静态的, 也就是代表要先实例1个工厂对象, 才能依靠这个工厂对象去获得bean 对象。
用回上面的例子。
而这次我们写1个实例工厂类
CarInstanceFactroy
package com.home.factoryMethod;import java.util.HashMap;
import java.util.Map;public class CarInstanceFactory { private Map<Integer, Car> map = new HashMap<Integer,Car>(); public void setMap(Map<Integer, Car> map) { this.map = map; } public CarInstanceFactory(){ } public Car getCar(int id){ return map.get(id); } }
bean xml写法
<!-- Instance Factory Method:1.must create a bean for the Instance Factroy First--><bean id="carFactory" class="com.home.factoryMethod.CarInstanceFactory"> <property name="map"> <map> <entry key="4"> <bean class="com.home.factoryMethod.Car"> <property name="id" value="4"></property> <property name="name" value="Honda"></property> <property name="price" value="300000"></property> </bean> </entry> <entry key="6"> <bean class="com.home.factoryMethod.Car"> <property name="id" value="6"></property> <property name="name" value="ford"></property> <property name="price" value="500000"></property> </bean> </entry> </map> </property> </bean> <!-- 2.use Factory bean to get bean objectr factory-bean : the bean define above factory-method: method of get Bean Object constructor-arg: parameters of factory-method --> <bean id="car4" factory-bean="carFactory" factory-method="getCar"> <constructor-arg value="4"></constructor-arg> </bean> <bean id="car6" factory-bean="carFactory" factory-method="getCar"> <constructor-arg value="6"></constructor-arg> </bean>
因为实例工厂本身要实例化, 所以我们可以在xml中 指定它里面容器的data, 解决了上面提到的静态工厂方法的缺点啦
client代码
public static void h2(){ApplicationContext ctx = new ClassPathXmlApplicationContext("bean-factoryMethod.xml"); Car car1 = (Car) ctx.getBean("car4"); System.out.println(car1); car1 = (Car) ctx.getBean("car6"); System.out.println(car1); }
输出结果
May 31, 2016 12:22:28 AM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@5d79a4c9: startup date [Tue May 31 00:22:28 CST 2016]; root of context hierarchy May 31, 2016 12:22:28 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions INFO: Loading XML bean definitions from class path resource [bean-factoryMethod.xml] Car [id=4, name=Honda, price=300000] Car [id=6, name=ford, price=500000]
- 1小结
本人觉得实例工厂方式使用起来更加灵活啦, 不过项目中其实本文一开始提到的第三种方法FactoryBean比起工厂方法方式更加常见。
转载于:https://www.cnblogs.com/mochaMM/p/6925366.html
Spring 通过工厂方法(Factory Method)来配置bean相关推荐
- 设计模式--工厂方法(Factory Method)模式
模式定义 定义一个用于创建对象的接口,让子类决定实例化哪一个类,使得一个类的实例化延迟到子类 类图 应用场景 1.当你不知道该使用对象的确切类型的时候: 2.当你希望为库或框架提供扩展其内部组件的方法 ...
- [设计模式-创建型]工厂方法(Factory Method)
概括 名称 Factory Method 结构 动机 定义一个用于创建对象的接口,让子类决定实例化哪一个类.Factory Method 使一个类的实例化延迟到其子类. 适用性 当一个类不知道它所必 ...
- Java工厂方法---Factory Method
工厂方法:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类 工厂方法优点: 1.支持OCP原则,开闭原则,把创建产品的细节隐藏起来,对上层类的调用时透明的 2 ...
- 工厂方法 Factory Method
背景:有一个应用框架,它可以向用户显示多个文档.在这个框架中,两个主要的抽象是类Application和Document.这两个类都是抽象的.客户必须通过它们的子类来做与举替应用相关的实现. 分析:因 ...
- spring 通过工厂方法配置Bean
概要: 通过调用静态工厂方法创建Bean 调用静态工厂方法创建Bean是将对象创建的过程封装到静态方法中.当client须要对象时,仅仅须要简单地调用静态方法,而不用关心创建对象地细节. 要声明通过静 ...
- php factory interface,【PHP 設計模式大頭菜】工廠方法 Factory Method
工廠方法 Factory Method 工廠方法,跟抽象工廠有點像,可是又沒那麼像,抽象工廠的工廠會有個抽象類別,並且把工廠要做且會重工的事情寫在抽象類別當中,而工廠方法則是需要定義一個工廠介面,並且 ...
- Spring IOC refresh()方法——告诉子类刷新内部bean工厂
告诉子类刷新内部bean工厂. /*** Tell the subclass to refresh the internal bean factory.* @return the fresh Bean ...
- 当Android遇上设计模式之工厂方法(Factory)模式
文章目录 1. 简单工厂模式 2.1 定义 2.2 代码实现 2.3 使用场景 2. 工厂方法模式 2.1 定义 2.2 代码实现 2.3 使用场景 设计模式六大原则: 单一职责原则:就一个类仅有一个 ...
- 四 Spring的工厂类,xml的配置
Spring工厂类的结构图: BeanFactory:老版本的工厂类 BeanFactory:调用getBean的时候,才会生产类的实例 ApplicationFactory:新版本的工厂类 加载配置 ...
最新文章
- docker一步安装mysql,docker的魅力就在于此
- linux 查看es安装目录,Linux安装Elasticsearch
- android toast有焦点,android – 如何在显示Toast后进行edittext自动对焦?
- C#命名规则和编码规范
- 工业交换机与光纤收发器的区别
- win10计算机启动一分钟重启,Win10开机提示电脑将在一分钟后自动重启怎么办?...
- 【LeetCode笔记】96. 不同的二叉搜索树(Java、动态规划)
- php写按条件查询代码,php如何实现按条件查询
- AIR中文帮助 第十章. 窗体(Windows)和菜单
- box-sizing的不同属性值间的区别
- centos mysql 安装及配置
- 关于delete字符串 需不需要加 [ ]
- 谷歌修复已遭在野利用的两个 0day
- 约瑟夫环问题 poj 1012 poj 2244
- 评价类问题中的模糊综合评价法
- NR中关于RE、RB、CRB、PRB、VRB、REG、RBG、CCE等概念
- 色貌模型-introduction
- IP Forwarding打开
- AcWing 1714.混合牛奶
- what is pathon?(脚本语言pathon简介)
热门文章
- 精准钓鱼***,只有榜上有名的人才会被***
- t-sql使用小记2010-01-27
- 大数据+机器学习#x3D;天下无敌!
- Visual Studio 各个版本下载地址
- 字符串工具类、数组工具类、集合工具类、转型操作工具类、编码与解码操作工具类...
- SegmentFault 专访 | AlloyTeam 2015 前端技术大会讲师圆桌
- 基于ubuntu 的LAMP 优化加固
- 35 岁佛系程序员,年后第一天被辞退
- 第二十到第二十一天:让你和页面对话-IFE
- /etc/fstab文件损坏怎么办