从零开始 Spring Boot 45:FactoryBean
在前文中我介绍过 FactoryBean
,本篇文章会更深入的介绍相关内容。
依赖注入
从一个简单示例开始,我们看使用FactoryBean
定义的 Spring Bean 如何注入。
假设我们有以下的几个类:
public class Clock {
private LocalDateTime time;
private int num;
private static DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ISO_DATE_TIME;
public Clock(LocalDateTime time, int num) {
this.time = time;
this.num = num;
}
@Override
public String toString() {
return "Clock#%d(%s)".formatted(num, dateTimeFormatter.format(time));
}
}
public class ClockFactory implements FactoryBean<Clock> {
private static int num = 0;
@Override
public Clock getObject() throws Exception {
return new Clock(LocalDateTime.now(), ++num);
}
@Override
public Class<?> getObjectType() {
return Clock.class;
}
@Override
public boolean isSingleton() {
return false;
}
@Override
public String toString() {
return "ClockFactory(num=%d)".formatted(num);
}
}
Clock
是一个POJO类,ClockFactory
是Clock
的“工厂类”,并且实现了FactoryBean<Clock>
接口。
需要注意的是,这里的ClockFacotry.isSingleton
方法返回的是false
,并且每次请求ClockFactory.getObject
也会返回一个新的Clock
实例。
使用 @Bean
方法向上下文添加 ClockFacotry
bean:
@Configuration
public class WebConfig {
@Bean("clock")
public ClockFactory clockFactory(){
return new ClockFactory();
}
}
注意,这里只添加了ClockFactory
bean,并没有添加Clock
bean,但因为前者实现了FactoryBean
接口,因此 Spring 会将其看作一个工厂 bean,如果向上下文请求Clock
类型的 bean,Spring 就会利用ClockFacotry
bean 的getObject
方法返回一个Clock
对象。
我们可以通过下面的测试验证这一点:
@SpringJUnitConfig(classes = {
FactoryBeanApplication.class})
public class ClockFactoryTests {
@Autowired
private ClockFactory clockFactory1;
@Autowired
private ClockFactory clockFactory2;
@Autowired