FactoryBean

FactoryBean 和 BeanFactory

FactoryBean 和 BeanFactory 别搞混了,就记结尾就好了

FactoryBean:是以 Bean 结尾,所以这是一个 bean。这是一个特殊的 bean

BeanFactory:是以 Factory 结尾,所以这是工厂。工厂用来创建 bean(也会保存bean,是 IOC 容器的父接口)

FactoryBean 特性

  • 当注入一个 FactoryBean 时会产生两个 bean:一个是工厂 bean、一个是真实 bean
  • 通过 &beanName 获取工厂 bean;通过 beanName 获取真实 bean

FactoryBean 接口定义

public interface FactoryBean<T> {
    T getObject() throws Exception;    // 返回生产的对象
    Class<?> getObjectType();         // 返回对象类型
    boolean isSingleton();            // 是否单例
}

FactoryBean 使用示例

@Component // User 会注册到容器
public class User implements FactoryBean<Person> {
    @Override
    public Person getObject() throws Exception { // 创建了 user 后会调用这个方法再产生一个 bean
        return new Person();
    }

    @Override
    public Class<?> getObjectType() { // 真实bean的类型
        return Person.class;
    }
}

// 获取真实 bean
Object bean = context.getBean("user");
Person person = context.getBean("user", Person.class);

// 获取工厂 bean
Object factoryBean = context.getBean("&user");
User user = context.getBean("&user", User.class);

FactoryBean 场景

类似 Mybatis 的 SqlSession,每次要使用新连接

public class MyConnectionFactoryBean implements FactoryBean<Connection> {
    @Override
    public Connection getObject() throws Exception {
        return DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb");
    }
    
    @Override
    public Class<?> getObjectType() {
        return Connection.class;
    }
    
    @Override
    public boolean isSingleton() {
        return false; // 每次获取新连接
    }
}

动态代理

public class ProxyFactoryBean implements FactoryBean<Object> {
    private Object target;
    private Class<?> interfaceClass;
    
    @Override
    public Object getObject() {
        return Proxy.newProxyInstance(
            interfaceClass.getClassLoader(),
            new Class<?>[]{interfaceClass},
            (proxy, method, args) -> method.invoke(target, args)
        );
    }
    
    // 其他方法实现...
}

最佳实践

  1. 命名规范:建议工厂 Bean 名称以 "Factory" 或 "FactoryBean" 结尾
  2. 文档说明:在工厂类上添加详细注释说明其用途
  3. 作用域控制:通过 isSingleton() 明确声明是否为单例
  4. 异常处理:在 getObject() 中妥善处理异常
posted @ 2024-06-29 18:08  CyrusHuang  阅读(38)  评论(0)    收藏  举报