前置知识: FactoryBean的作用

FactoryBean

简介

FactoryBean是Spring中一种特殊的Bean,是用于创建Bean对象的,最大的作用便是可以让我们自定义Bean的创建过程。如果你在XML配置文件配置了一个节点,我们通过ApplicationContext获取的对象实际上是getObject方法返回的对象,而不是其本身。FactoryBean的定义如下:

public interface FactoryBean<T> {
    
    /**
     * 自定义创建Bean的方法
     */
    T getObject() throws Exception;
    
    /**
     * Bean的类型
     */
    Class<?> getObjectType();
    
    /**
     * 是不是单例
     */
    boolean isSingleton();
}

使用

想要掌握一个东西,莫过于先使用它。

/**
 * Bean
 */
public class Mapper {

    private Integer id;

    public Mapper(Integer id) {
        this.id = id;
    }

    public Integer getId() {
        return id;
    }
}

public class MapperFactoryBean implements FactoryBean<Mapper> {

    private Integer id;

    private Mapper mapper;

    public void setId(Integer id) {
        this.id = id;
    }

    @Override
    public Mapper getObject() {
        if (mapper == null) {
            mapper = new Mapper(id);
        }
        return mapper;
    }

    @Override
    public Class<?> getObjectType() {
        return Mapper.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }
}
<!-- 配置 -->
<bean id="mapper" class="com.wangtao.spring.bean.MapperFactoryBean">
    <property name="id" value="1"/>
</bean>
public class BaseTest {
    @Test
    public void application() {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        // 下面这句将抛出异常
        // MapperFactoryBean mapper = context.getBean("mapper", MapperFactoryBean.class);
        Mapper mapper = context.getBean("mapper", Mapper.class);
        Assert.assertEquals(1, mapper.getId().intValue());
    }
}

从测试结果中得知,我们虽然配置的是MapperFactoryBean的实列,但是根据id拿到的是getObject方法创建的对象。其实在容器中创建的对象仍然是MapperFactoryBean的实列,只是在获取的时候会判断这个结果对象是不是派生于FactoryBean,如果是的话则返回getObject方法创建的对象,并且这个对象并不是容器初始化时创建的,而是使用context.getBean()方法时才创建。当然了,如果你确实想要获取FactoryBean实例,你需要这样写: MapperFactoryBean mapper = context.getBean("&mapper", MapperFactoryBean.class); 只需要在bean的名字ID前加上&符号。

posted on 2019-03-04 13:33  wastonl  阅读(1698)  评论(0编辑  收藏  举报