Spring 通过工厂方法(Factory Method)来配置bean
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 Factory
factory-method: method of get Bean Object
constructor-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个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]
小结
本人觉得实例工厂方式使用起来更加灵活啦, 不过项目中其实本文一开始提到的第三种方法FactoryBean比起工厂方法方式更加常见。
Spring 通过工厂方法(Factory Method)来配置bean的更多相关文章
- 抽象工厂(Abstract Factory),工厂方法(Factory Method),单例模式(Singleton Pattern)
在谈工厂之前,先阐述一个观点:那就是在实际程序设计中,为了设计灵活的多态代码,代码中尽量不使用new去实例化一个对象,那么不使用new去实例化对象,剩下可用的方法就可以选择使用工厂方法,原型复制等去实 ...
- [设计模式-创建型]工厂方法(Factory Method)
概括 名称 Factory Method 结构 动机 定义一个用于创建对象的接口,让子类决定实例化哪一个类.Factory Method 使一个类的实例化延迟到其子类. 适用性 当一个类不知道它所必 ...
- 设计模式——工厂方法(Factory Method)
定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法使一个类的实例化延迟到其子类. ——DP UML类图 模式说明 抽象业务基类 实际业务类的公共基类,也是工厂要创建的所有对象的父类,这部分 ...
- Headfirst设计模式的C++实现——工厂方法(Factory Method)
引用原书的一句话:所有的工厂模式都用来封装对象的创建,工厂方法模式通过让子类决定该创建的对象是什么来达到封装的目的. Pizza类及其派生类与上一例相同 PizzaStore.h #ifndef _P ...
- 设计模式二: 工厂方法(Factory Method)
简介 工厂方法模式是创建型模式的一种, 核心结构有四个角色: 抽象工厂,具体工厂,抽象产品,具体产品; 实现层面上,该模式定义一个创建产品的接口,将实际创建工作推迟到具体工厂类实现, 一个产品对应一个 ...
- 工厂方法 Factory Method
背景:有一个应用框架,它可以向用户显示多个文档.在这个框架中,两个主要的抽象是类Application和Document.这两个类都是抽象的.客户必须通过它们的子类来做与举替应用相关的实现. 分析:因 ...
- 设计模式学习心得<工厂方法 Factory Method>
概述 意图 业务代码中常常有构造对象的过程,它拥有大量的参数.并且有很多地方需要这对象. 简化对象构造过程. 主要解决 一个类在不同场景的频繁地创建,让不同对象的创建更有语义化,提高代码复用性. 何时 ...
- spring 通过工厂方法配置Bean
概要: 通过调用静态工厂方法创建Bean 调用静态工厂方法创建Bean是将对象创建的过程封装到静态方法中.当client须要对象时,仅仅须要简单地调用静态方法,而不用关心创建对象地细节. 要声明通过静 ...
- 11.Spring通过工厂方法配置Bean
通过工厂方法配置Bean暴扣静态工厂方法和实例工厂方法. 1.静态工厂方法 调用静态工厂方法创建Bean是将对象创建的过程封装到静态方法中,当客户端需要对象时,只需要简单的调用静态方法,而不去关心创建 ...
随机推荐
- Magento的布局(Layout),块(Block)和模板(Template)
public function indexAction() { //remove our previous echo //echo 'Hello Index!'; $this->loadLayo ...
- jquery处理textarea中的手动换行
textarea的手动换行会产生换行标志,但这个标志存在却看不到,存入数据库中后读出来显示在页面上却不会换行,如何处理呢? 网上众说纷纭,经过测试用 textarea的内容.replace(/\n/g ...
- 数据结构与算法JavaScript 读书笔记
由于自己在对数组操作这块比较薄弱,然后经高人指点,需要好好的攻读一下这本书籍,原本想这个书名就比较高深,这下不好玩了.不过看着看着突然觉得讲的东西都比较基础.不过很多东西,平时还是没有注意到,故写出读 ...
- Redis Cache 简介
Microsoft Azure Redis Cache 是基于流行的开源Redis Cache 1.Microsoft Azure Redis Cache 可分为以下几个级别: Basic – 单节点 ...
- SQL Server游标+延迟执行简介
在项目测试中,我们可能会使用批量生成数据来测试程序的性能. 这里讲一个我遇到的问题,由于我们批量生成数据时基本上是瞬间完成,所以GETDATE()函数获得的时间基本上也是一样的,而我们又要求生成每条数 ...
- Android开发之Adapter
学习android时,对于我这种初学者来说,刚开始接触控件,发现有的控件需要adapter有些不需要,对此我感到不解.所以决定一探究竟. 其实android是一个完全遵从MVC模式的框架,activi ...
- SQL Server调优系列进阶篇 - 查询语句运行几个指标值监测
前言 上一篇我们分析了查询优化器的工作方式,其中包括:查询优化器的详细运行步骤.筛选条件分析.索引项优化等信息. 本篇我们分析在我们运行的过程中几个关键指标值的检测. 通过这些指标值来分析语句的运行问 ...
- Android SDK目录含义介绍
Android SDK目录的具体结构: 1.add-ons:该目录下存放第三方公司为Android平台开发的附加功能系统. 2.build-tools:编译工具.保存着一些通用工具,比如aapt.ai ...
- 淘宝开源Web服务器Tengine安装教程
简介Tengine是由淘宝核心系统部基于Nginx开发的Web服务器,它在Nginx的基础上,针对大访问量网站的需求,添加了很多功能和特性.Tengine的性能和稳定性已经在大型的网站如淘宝网,淘宝商 ...
- struts2自定义类型转换器
首先,何为struts2的类型转换器? 类型转换器的作用是将请求中的字符串或字符串数组参数与action中的对象进行相互转换. 一.大部分时候,使用struts2提供的类型转换器以及OGNL类型转换机 ...