Spring入门学习——使用Spring的FactoryBean创建Bean
2017-04-21 10:49
447 查看
有时候希望使用Spring的工厂Bean在Spring IoC容器中创建Bean。工厂Bean(Factory Bean)是作为创建IoC容器中其他Bean的工厂的一个Bean(拗口~)。工厂Bean主要用于实现框架机制,如(1)在JNDI中查找对象,可以使用JndiObjectFactoryBean,(2)使用经典SpringAOP为一个Bean创建代理时,可以使用ProxyFactoryBean等等。Spring提供了抽象模板类AbstractFactoryBean供扩展
但是,作为框架用户,你难得有必要编写自定义的工厂Bean,因为它们是框架专用的,无法用在SpringIoC容器之外。
实际上,你总是能够为工厂Bean实现一个等价的工厂方法。——《Spring攻略》
使用一个实例来理解其内部机制十分有用,因此有这样一个场景,为一个使用价格折扣的产品编写一个工厂Bean,它接收一个product属性和一个discount属性,将折扣应用到产品上并且作为一个新的Bean返回。继承AbstractFactoryBean需要实现createInstance和getObjectType两个方法package com.cgy.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;
}
@Override
protected Object createInstance() throws Exception {
product.setPrice( product.getPrice()*(1-discount) );
return product; //返回Bean实例
}
@Override
public Class getObjectType() {
return product.getClass(); //返回目标Bean类型
}
}
package com.cgy.springrecipes.shop;
public abstract class Product {
private String name;
private double price;
public Product(){}
public Product(String name,double price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String toString() {
return name + " " + price;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<b
4000
eans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="battery" class="com.cgy.springrecipes.shop.DiscountFactoryBean">
<property name="product">
<bean class="com.cgy.springrecipes.shop.Battery"> <!-- 内部Bean -->
<constructor-arg value="kingston" type="java.lang.String" />
<constructor-arg value="2.5" type="double" />
</bean>
</property>
<property name="discount" value="0.2" />
</bean>
<bean id="disc" class="com.cgy.springrecipes.shop.DiscountFactoryBean">
<property name="product">
<bean class="com.cgy.springrecipes.shop.Disc"> <!-- 内部Bean -->
<constructor-arg value="tyalor" type="java.lang.String" />
<constructor-arg value="1.5" type="double" />
</bean>
</property>
<property name="discount" value="0.1" />
</bean>
</beans>
运行输出结果:kingston 2.0
tyalor 1.35很明显,产品按照预期打折了
但是,作为框架用户,你难得有必要编写自定义的工厂Bean,因为它们是框架专用的,无法用在SpringIoC容器之外。
实际上,你总是能够为工厂Bean实现一个等价的工厂方法。——《Spring攻略》
使用一个实例来理解其内部机制十分有用,因此有这样一个场景,为一个使用价格折扣的产品编写一个工厂Bean,它接收一个product属性和一个discount属性,将折扣应用到产品上并且作为一个新的Bean返回。继承AbstractFactoryBean需要实现createInstance和getObjectType两个方法package com.cgy.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;
}
@Override
protected Object createInstance() throws Exception {
product.setPrice( product.getPrice()*(1-discount) );
return product; //返回Bean实例
}
@Override
public Class getObjectType() {
return product.getClass(); //返回目标Bean类型
}
}
package com.cgy.springrecipes.shop;
public abstract class Product {
private String name;
private double price;
public Product(){}
public Product(String name,double price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String toString() {
return name + " " + price;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<b
4000
eans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="battery" class="com.cgy.springrecipes.shop.DiscountFactoryBean">
<property name="product">
<bean class="com.cgy.springrecipes.shop.Battery"> <!-- 内部Bean -->
<constructor-arg value="kingston" type="java.lang.String" />
<constructor-arg value="2.5" type="double" />
</bean>
</property>
<property name="discount" value="0.2" />
</bean>
<bean id="disc" class="com.cgy.springrecipes.shop.DiscountFactoryBean">
<property name="product">
<bean class="com.cgy.springrecipes.shop.Disc"> <!-- 内部Bean -->
<constructor-arg value="tyalor" type="java.lang.String" />
<constructor-arg value="1.5" type="double" />
</bean>
</property>
<property name="discount" value="0.1" />
</bean>
</beans>
运行输出结果:kingston 2.0
tyalor 1.35很明显,产品按照预期打折了
相关文章推荐
- Spring源码学习之:FactoryBean的使用
- Spring学习(三)使用Spring容器创建bean
- 创建ApplicationContext与BeanFactory时的区别-Spring源码学习之容器的基本实现
- Spring 学习总结 使用静态工厂创建Bean
- Spring学习笔记 使用Static Factory(静态工厂类)创建Bean
- 创建ApplicationContext与BeanFactory时的区别-Spring源码学习之容器的基本实现
- spring学习小结8-使用factoryBean来配置bean
- 使用Spring的FactoryBean创建同步队列线程池
- Spring学习之使用factorybean获取bean实例
- Spring学习记录(十)---使用FactoryBean配置Bean
- Spring入门学习——使用Bean感知容器
- SpringBoot入门学习一(如何使用IDEA创建一个SpringBoot应用)
- Spring入门学习——调用静态工厂方法创建Bean
- Spring学习笔记 关于FactoryBean接口的使用
- Spring学习笔记 使用Non-Static Factory(非静态工厂类)创建Bean
- 8.5.2: Spring的事务---使用TransactionProxyFactoryBean创建事务代理
- Spring事务——使用TransactionProxyFactoryBean创建事务代理
- Spring学习笔记 —— AOP(面向切面编程) 之使用ProxyFactoryBean实现AOP
- Spring入门学习——调用一个实例工厂方法创建Bean
- spring MethodInvokingFactoryBean 的使用和了解,Spring 通过通过方法创建Bean的实例