FactoryBean
FactoryBean以工厂方式创建Bean,提供更灵活的实例化逻辑。
接口定义
Java
public interface FactoryBean<T> {
// 返回创建的对象
T getObject() throws Exception;
// 返回对象类型
Class<?> getObjectType();
// 是否单例
default boolean isSingleton() {
return true;
}
}
基本实现
Java
@Component
public class UserFactoryBean implements FactoryBean<User> {
private String username;
private String email;
@Override
public User getObject() throws Exception {
// 自定义创建逻辑
User user = new User();
user.setUsername(username);
user.setEmail(email);
user.setCreateTime(LocalDateTime.now());
user.setStatus("active");
return user;
}
@Override
public Class<?> getObjectType() {
return User.class;
}
@Override
public boolean isSingleton() {
return true; // 单例
}
}
XML配置
XML
<bean id="user" class="com.example.UserFactoryBean">
<property name="username" value="admin"/>
<property name="email" value="admin@example.com"/>
</bean>
<!-- 获取FactoryBean本身,添加&前缀 -->
<bean id="userFactory" class="com.example.UserFactoryBean"/>
创建复杂对象
Java
@Component
public class HttpClientFactoryBean implements FactoryBean<HttpClient> {
private String baseUrl;
private int timeout = 5000;
private int maxConnections = 100;
@Override
public HttpClient getObject() throws Exception {
HttpClientBuilder builder = HttpClientBuilder.create();
builder.setConnectTimeout(timeout);
builder.setMaxConnTotal(maxConnections);
HttpClient client = builder.build();
client.setBaseUrl(baseUrl);
return client;
}
@Override
public Class<?> getObjectType() {
return HttpClient.class;
}
}
创建代理对象
Java
@Component
public class ServiceProxyFactoryBean implements FactoryBean<Object> {
private Class<?> serviceInterface;
private String serviceUrl;
@Override
public Object getObject() throws Exception {
// 创建RPC代理对象
return Proxy.newProxyInstance(
serviceInterface.getClassLoader(),
new Class[]{serviceInterface},
(proxy, method, args) -> {
// 远程调用逻辑
return rpcClient.invoke(serviceUrl, method.getName(), args);
}
);
}
@Override
public Class<?> getObjectType() {
return serviceInterface;
}
}
原型模式
Java
@Component
public class PrototypeFactoryBean implements FactoryBean<Report> {
@Override
public Report getObject() throws Exception {
// 每次调用创建新实例
return new Report(UUID.randomUUID().toString());
}
@Override
public Class<?> getObjectType() {
return Report.class;
}
@Override
public boolean isSingleton() {
return false; // 原型模式
}
}
获取FactoryBean本身
Java
@Autowired
@Qualifier("user") // 获取User对象
private User user;
@Autowired
@Qualifier("&user") // 获取FactoryBean本身
private UserFactoryBean userFactory;
// 或通过ApplicationContext
Object bean = context.getBean("user"); // User对象
FactoryBean factory = (FactoryBean) context.getBean("&user"); // FactoryBean
实际应用场景
MyBatis SqlSessionFactory
Java
// Spring集成MyBatis的FactoryBean
public class SqlSessionFactoryBean implements FactoryBean<SqlSessionFactory>,
InitializingBean, ApplicationListener<ApplicationEvent> {
private DataSource dataSource;
private Resource[] mapperLocations;
@Override
public SqlSessionFactory getObject() throws Exception {
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
Configuration configuration = buildConfiguration();
return builder.build(configuration);
}
@Override
public Class<?> getObjectType() {
return SqlSessionFactory.class;
}
}
动态数据源
Java
@Component
public class DynamicDataSourceFactoryBean implements FactoryBean<DataSource> {
private Map<String, DataSourceConfig> configs;
@Override
public DataSource getObject() throws Exception {
Map<Object, Object> targetDataSources = new HashMap<>();
for (Map.Entry<String, DataSourceConfig> entry : configs.entrySet()) {
targetDataSources.put(entry.getKey(), createDataSource(entry.getValue()));
}
DynamicRoutingDataSource routingDataSource = new DynamicRoutingDataSource();
routingDataSource.setTargetDataSources(targetDataSources);
routingDataSource.setDefaultTargetDataSource(
targetDataSources.get("default"));
return routingDataSource;
}
@Override
public Class<?> getObjectType() {
return DataSource.class;
}
}
与普通Bean对比
| 特性 | 普通Bean | FactoryBean |
|---|---|---|
| 创建方式 | 容器直接实例化 | 工厂方法创建 |
| 灵活性 | 依赖注入 | 可自定义复杂逻辑 |
| 获取对象 | getBean(name) | getBean(name) |
| 获取工厂 | N/A | getBean("&name") |
要点总结
- FactoryBean通过getObject()方法创建Bean实例
- getObjectType()定义返回类型
- isSingleton()控制单例/原型模式
- "&beanName"获取FactoryBean本身
- 适合创建复杂对象、代理对象、整合第三方框架
📝 发现内容有误?点击此处直接编辑