《Spring攻略(第2版)》——1.7 使用Spring的FactoryBean创建Bean

简介: 你可能希望用Spring的工厂Bean在Spring IoC容器中创建Bean。工厂Bean(Factory bean)是作为创建IoC容器中其他Bean的工厂的一个Bean。概念上,工厂Bean与工厂方法非常类似,但是它是Bean构造期间可被Spring IoC容器识别的Spring专用Bean。

本节书摘来自异步社区《Spring攻略(第2版)》一书中的第1章,第1.7节,作者: 【美】Gary Mak , Josh Long , Daniel Rubio著,更多章节内容可以访问云栖社区“异步社区”公众号查看

1.7 使用Spring的FactoryBean创建Bean

1.7.1 问题
你可能希望用Spring的工厂Bean在Spring IoC容器中创建Bean。工厂Bean(Factory bean)是作为创建IoC容器中其他Bean的工厂的一个Bean。概念上,工厂Bean与工厂方法非常类似,但是它是Bean构造期间可被Spring IoC容器识别的Spring专用Bean。

1.7.2 解决方案
工厂Bean的基本要求是实现FactoryBean接口。为了方便,Spring提供了抽象模板类AbstractFactoryBean供你扩展。

工厂Bean主要用于实现框架机制。下面是一些例子:

在JNDI中查找对象(例如一个数据源)时,你可以使用JndiObjectFactoryBean。
使用经典Spring AOP为一个Bean创建代理时,可以使用ProxyFactoryBean。
在IoC容器中创建一个Hibernate会话工厂时,可以使用LocalSessionFactoryBean。
但是,作为框架用户,你难得有必要编写自定义的工厂Bean,因为它们是框架专用的,无法用在Spring IoC容器之外。实际上,你总是能够为工厂Bean实现一个等价的工厂方法。

1.7.3 工作原理
尽管你很少有必要编写自定义的工厂Bean,但是会发现通过一个实例来理解其内部机制很有帮助。例如,你可以为创建一个适用价格折扣的产品编写一个工厂Bean。它接受一个product属性和一个discount属性,将折扣应用到产品上并且作为一个新的Bean返回。

package com.apress.springrecipes.shop;

import org.springframework.beans.factory.config.AbstractFactoryBean;

public class DiscountFactoryBean extends AbstractFactoryBean {

   private Product product;
   private double discount;

   public void setProduct(Product product) {
     this.product = product;
   }

   public void setDiscount(double discount) {
     this.discount = discount;
   }

   public Class getObjectType() {
     return product.getClass();
   }

   protected Object createInstance() throws Exception {
     product.setPrice(product.getPrice() * (1 - discount));
     return product;
   }
}

通过扩展AbstractFactoryBean类,你的工厂Bean能够重载createInstance()方法以创建目标Bean实例。此外,你必须在getObjectType()方法中返回目标Bean的类型,使自动装配(Auto-wiring)功能正常工作。

接下来,你可以用DiscountFactoryBean声明你的产品实例。每当你请求一个实现Factory Bean接口的Bean,Spring IoC容器将使用这个工厂Bean创建目标Bean并且返回给你。如果你确定希望得到工厂Bean的实例,可以在Bean名称之前加上&。

<beans ...>
   <bean id="aaa"
     class="com.apress.springrecipes.shop.DiscountFactoryBean">
     <property name="product">
        <bean class="com.apress.springrecipes.shop.Battery">
          <constructor-arg value="AAA" />
          <constructor-arg value="2.5" />
        </bean>
     </property>
     <property name="discount" value="0.2" />
   </bean>

   <bean id="cdrw"
     class="com.apress.springrecipes.shop.DiscountFactoryBean">
     <property name="product">
        <bean class="com.apress.springrecipes.shop.Disc">
          <constructor-arg value="CD-RW" />
          <constructor-arg value="1.5" />
        </bean>
     </property>
     <property name="discount" value="0.1" />
   </bean>
</beans>

前述的工厂Bean配置的工作方式和下面的代码片段类似:

DiscountFactoryBean aaa = new DiscountFactoryBean();
aaa.setProduct(new Battery("AAA", 2.5));
aaa.setDiscount(0.2);
Product aaa = (Product) aaa.createInstance();

DiscountFactoryBean cdrw = new DiscountFactoryBean();
cdrw.setProduct(new Disc("CD-RW", 1.5));
cdrw.setDiscount(0.1);
Product cdrw = (Product) cdrw.createInstance();
相关文章
|
25天前
|
缓存 Java Spring
Spring 框架中 Bean 的生命周期
Spring 框架中 Bean 的生命周期
32 1
|
1月前
|
XML Java 开发者
Spring Boot中的bean注入方式和原理
Spring Boot中的bean注入方式和原理
61 0
|
1天前
|
XML 人工智能 Java
Spring Bean名称生成规则(含源码解析、自定义Spring Bean名称方式)
Spring Bean名称生成规则(含源码解析、自定义Spring Bean名称方式)
|
9天前
|
Java 数据库连接 开发者
浅谈Spring的Bean生命周期
浅谈Spring的Bean生命周期
18 1
|
14天前
|
XML Java 数据格式
Bean工厂探秘:解析Spring底层工厂体系BeanFactory的神奇之道
Bean工厂探秘:解析Spring底层工厂体系BeanFactory的神奇之道
19 0
Bean工厂探秘:解析Spring底层工厂体系BeanFactory的神奇之道
|
24天前
|
XML Java 程序员
作为Java程序员还不知道Spring中Bean创建过程和作用?
作为Java程序员还不知道Spring中Bean创建过程和作用?
15 0
|
29天前
|
XML 缓存 Java
天天用 Spring,bean 实例化原理你懂吗
天天用 Spring,bean 实例化原理你懂吗
17 0
|
29天前
|
Java 应用服务中间件 Maven
SpringBoot 项目瘦身指南
SpringBoot 项目瘦身指南
43 0
|
2月前
|
缓存 Java Maven
Spring Boot自动配置原理
Spring Boot自动配置原理
48 0
|
1月前
|
缓存 安全 Java
Spring Boot 面试题及答案整理,最新面试题
Spring Boot 面试题及答案整理,最新面试题
111 0