spring的FactoryBean分析

1:有什么用

正常我们创建bean的时候都是使用配置的方式,配置后由spring来统一加载创建放到IOC容器中,比如只是简单的通过构造函数,通过setter方法等创建,并且相关的参数的值也都是确定的,此时使用配置的方式无疑是最好的选择,但是如果是bean创建没有那么简单,比如创建对象依赖的数据需要经过复杂的解析,配置的方式就无法实现了,这个时候就可以考虑使用FactoryBean来完成对象的创建了。

2:如何用

为了让我们使用FactoryBean,spring定义了接口org.springframework.beans.factory.FactoryBean,源码如下:

public interface FactoryBean<T> {
	// 获取目标对象,在该方法中创建自定制的对象,并返回
	// 我们再getBean时如果传入的bean名称不是&开头的则会调用
	// 该方法获取目标对象
	@Nullable
	T getObject() throws Exception;

	// getObject方法返回的对象的类型
	@Nullable
	Class<?> getObjectType();
	
	// 是否是单例的,默认是true,即为单例
	default boolean isSingleton() {
		return true;
	}
}

我们想要使用的话只需要创建一个类,来实现接口,然后在getObject方法中创建自己的对象并返回,然后像普通bean一样注册在spring的配置文件中就可以了,注册完毕后,当getBean时如果直接通过bean名称获取,默认就是调用getObject方法获取真实的对象,如果是想要获取bean工厂本身的话,只需要在bean名称前加上&号就可以了,下面我们来看个例子。

3:例子

3.1:定义要自己创建的对象

public class Car {
    private int maxSpeed;
    private String brand;
    private double price;

    ...getter setter tostring...
}

3.2:定义工厂bean

public class CarFactoryBean implements FactoryBean<Car> {
	// 作为创建目标对象的数据源
    private String carInfo;
    /**
     * 获取对象
     *
     * @return 自己定制创建的对象
     * @throws Exception
     */
    @Override
    public Car getObject() throws Exception {
        Car car = new Car();
        String[] infos = carInfo.split(",");
        car.setBrand(infos[0]);
        car.setMaxSpeed(Integer.valueOf(infos[1]));
        car.setPrice(Double.valueOf(infos[2]));
        return car;
    }

    /**
     * 返回对象的类型
     *
     * @return
     */
    @Override
    public Class<?> getObjectType() {
        return Car.class;
    }


    public String getCarInfo() {
        return carInfo;
    }

    public void setCarInfo(String carInfo) {
        this.carInfo = carInfo;
    }
}

3.3:定义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="yudaosourcecode.factorybean.CarFactoryBean">
        <property name="carInfo" value="超级跑车,400,2000000"/>
    </bean>
</beans>

3.4:测试

@Test
public void testFactoryBean() {
    ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("tsetfactorybean.xml");
    System.out.println("获取bean工厂本身");
    System.out.println(ac.getBean("&car"));
    System.out.println("获取内部对象");
    System.out.println(ac.getBean("car"));
}

运行:

获取bean工厂本身
yudaosourcecode.factorybean.CarFactoryBean@1fc2b765
获取内部对象
Car{maxSpeed=400, brand='超级跑车', price=2000000.0}

Process finished with exit code 0
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值