美文网首页
Spring扩展(4)-FactoryBean

Spring扩展(4)-FactoryBean

作者: Terminalist | 来源:发表于2018-02-27 20:10 被阅读65次

1.关于FactoryBean

它是spring容器提供的一种可以扩展容器对象实例化逻辑的接口,同时,从它的名字也可以看出它本身也是一个Bean,与注册到容器的其他对象一样;

2.FactoryBean的使用

介绍就免了,spring源码一搜就有,这里我主要讲下它在spring和springboot中的使用。
首先,我们先定义一个对象,代码如下:

 @Data
 @AllArgsConstructor
 public class Tool {

     private int id;

 }

然后,我们通过这个借助这个对象去扩展FactoryBean接口:

@Data
public class ToolFactory implements FactoryBean<Tool> {

    private int factoryId;
    private int toolId;

    @Override
    public Tool getObject() throws Exception {
        return new Tool(toolId);
    }

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

    @Override
    public boolean isSingleton() {
        return false;
    }
}

然后,如果我们是使用的spring的xml格式配置的话,请这么玩:

<bean id="tool" class="com.tyust.spring.boot.demo.factory.ToolFactory">
        <property name="factoryId" value="9090"/>
        <property name="toolId" value="1"/>
    </bean>

测试案例如下:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:spring-ctx.xml" })
public class SpringApplicationTest {
 
    @Resource(name = "&tool")
    private ToolFactory toolFactory;

    @Autowired
    private Tool tool;
 
    @Test
    public void test() {
        assertThat(toolFactory.getFactoryId(), equalTo(9090));
        assertThat(tool.getId(), equalTo(1));
    }
}

如果使用的是springboot形式,以代码的形式配置的话,请用如下代码替换xml的配置:

@Configuration
public class AppConfig {
  
    @Bean(name = "tool")
    public ToolFactory toolFactory() {
        ToolFactory factory = new ToolFactory();
        factory.setFactoryId(7070);
        factory.setToolId(2);
        return factory;
    }
 
    @Bean
    public Tool tool() throws Exception {
        return toolFactory().getObject();
    }
}

测试案例,可以依照如下方式注入:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = FactoryBeanAppConfig.class)
public class SpringApplicationTest {
 
    @Autowired
    private Tool tool;
  
    @Resource(name = "&tool")
    private ToolFactory toolFactory;
 
    @Test
    public void testConstructWorkerByJava() {
        assertThat(tool.getId(), equalTo(2));
        assertThat(toolFactory.getFactoryId(), equalTo(7070));
    }
}

spring提供了一个AbstractFactoryBean作为一个简单的模版类用于扩展FactoryBean,通过这个类,我们可以方便的建一个Singleton或者prototype的类去使用;
singleton的方式:

@Data
public class SingleToolFactory extends AbstractFactoryBean<Tool> {
 
    private int factoryId;
    private int toolId;
 
    @Override
    public Class<?> getObjectType() {
        return Tool.class;
    }
 
    @Override
    protected Tool createInstance() throws Exception {
        return new Tool(toolId);
    }
}

prototype的方式:

@Data
public class PrototypeToolFactory extends AbstractFactoryBean<Tool> {
 
    private int factoryId;
    private int toolId;
 
    public NonSingleToolFactory() {
        setSingleton(false);
    }
 
    @Override
    public Class<?> getObjectType() {
        return Tool.class;
    }
 
    @Override
    protected Tool createInstance() throws Exception {
        return new Tool(toolId);
    }
}

配置的话,提供一种,springboot的跟上面的类似,就不贴出来了.

 <bean id="singletonTool" class="com.tyust.spring.boot.demo.factory.SingleToolFactory">
        <property name="factoryId" value="3001"/>
        <property name="toolId" value="1"/>
    </bean>
 
    <bean id="prototypeTool" class="com.tyust.spring.boot.demo.factory.NonSingleToolFactory">
        <property name="factoryId" value="3002"/>
        <property name="toolId" value="2"/>
    </bean>

测试的代码如下:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:spring-ctx.xml" })
public class SpringApplicationTest {
 
    @Resource(name = "singletonTool")
    private Tool tool1;
  
    @Resource(name = "singletonTool")
    private Tool tool2;
  
    @Resource(name = "prototypeTool")
    private Tool tool3;
  
    @Resource(name = "prototypeTool")
    private Tool tool4;
 
    @Test
    public void testSingleToolFactory() {
        assertThat(tool1.getId(), equalTo(1));
        assertTrue(tool1 == tool2);
    }
 
    @Test
    public void testPrototypeToolFactory() {
        assertThat(tool3.getId(), equalTo(2));
        assertThat(tool4.getId(), equalTo(2));
        assertTrue(tool3 != tool4);
    }
}

通过这篇文章,我简要的给大家讲述下了FactoryBean和AbstractFactoryBean的使用,spring用FactoryBean类型的bean定义,通过正常的id引用,返回的是FactoryBean所"生产"的对象类型m,而非Factory本身,而factoryBean本身可以通过在bean定义的id前面添加前缀&来获取.要了解更多FactoryBean的内容,读者可以看看spring内部实现的一些案例:
DateTimeFormatterFactoryBean,HessianProxyFactoryBean,LocalConnectionFactoryBean等等;

相关文章

网友评论

      本文标题:Spring扩展(4)-FactoryBean

      本文链接:https://www.haomeiwen.com/subject/bramxftx.html