静态工厂和实例工厂的区别

9 39~50 min

在 Spring 中,静态工厂(Static Factory)实例工厂(Instance Factory) 是两种不同的 Bean 实例化方式,它们的核心区别在于工厂类的使用方式配置方法。以下是它们的详细对比:


1. 定义与机制

静态工厂

实例工厂

通过 工厂类的静态方法 创建 Bean 实例。

通过 工厂类的实例方法 创建 Bean 实例。

无需实例化工厂类,直接调用静态方法。

需先实例化工厂类,再调用实例方法。


2. 配置方式(XML 示例)

(1) 静态工厂

  • 工厂类无需定义为 Bean,直接通过 class 指定工厂类,factory-method 指定静态方法。

  • 示例

    <bean id="logger" class="com.example.LoggerFactory" factory-method="createLogger"/>
    public class LoggerFactory {
        // 静态方法
        public static Logger createLogger() {
            return new FileLogger();
        }
    }

(2) 实例工厂

  • 工厂类需先定义为 Bean,再通过 factory-bean 引用工厂实例,factory-method 指定实例方法。

  • 示例

    <!-- 1. 定义工厂实例 -->
    <bean id="parserFactory" class="com.example.ParserFactory"/>
    <!-- 2. 通过工厂实例的方法创建 Bean -->
    <bean id="jsonParser" factory-bean="parserFactory" factory-method="createJsonParser"/>
    public class ParserFactory {
        // 实例方法
        public Parser createJsonParser() {
            return new JsonParser();
        }
    }

3. 核心区别

特性

静态工厂

实例工厂

工厂实例化

无需实例化工厂类,直接调用静态方法。

需先实例化工厂类,再调用实例方法。

方法类型

静态方法(static)。

实例方法(非静态)。

配置复杂度

简单,无需额外定义工厂 Bean。

复杂,需先定义工厂 Bean,再关联目标 Bean。

适用场景

工厂无需状态或外部依赖(如工具类)。

工厂需要维护状态或依赖其他 Bean(如动态配置)。

灵活性

较低,静态方法无法访问实例变量或依赖注入的资源

较高,实例方法可以访问工厂类的状态或依赖注入的资源


4. 使用场景

(1) 静态工厂适用场景

  • 工厂方法逻辑简单,无需依赖外部资源或状态。

  • 例如:创建工具类实例(如日期格式化器、日志记录器)。

    public class DateUtils {
        public static DateFormat createDateFormat(String pattern) {
            return new SimpleDateFormat(pattern);
        }
    }

(2) 实例工厂适用场景

  • 工厂需要依赖其他 Bean 或维护状态(如动态配置)。

  • 例如:根据运行时条件创建不同的 Bean 实现。

    public class ParserFactory {
        private String config; // 工厂状态
        public void setConfig(String config) {
            this.config = config;
        }
        public Parser createParser() {
            if ("json".equals(config)) {
                return new JsonParser();
            } else {
                return new XmlParser();
            }
        }
    }

5. 注解配置的对比

(1) 静态工厂(通过 @Bean 方法模拟)

  • @Configuration 类中直接定义静态方法,但 Spring 不推荐此方式(需结合 @Bean + static)。

    @Configuration
    public class AppConfig {
        @Bean
        public static Logger logger() {
            return LoggerFactory.createLogger();
        }
    }

(2) 实例工厂(更自然的方式)

  • @Configuration 类中定义工厂 Bean 和目标 Bean:

    @Configuration
    public class AppConfig {
        // 1. 定义工厂实例
        @Bean
        public ParserFactory parserFactory() {
            return new ParserFactory();
        }
        // 2. 通过工厂实例的方法创建 Bean
        @Bean
        public Parser jsonParser(ParserFactory parserFactory) {
            return parserFactory.createJsonParser();
        }
    }

6. 总结

特性

静态工厂

实例工厂

工厂实例化

无需实例化工厂类。

需先实例化工厂类。

方法类型

静态方法。

实例方法。

配置复杂度

简单(直接指定类和方法)。

复杂(需定义工厂 Bean 并关联目标 Bean)。

灵活性

低(无法依赖注入或维护状态)。

高(可依赖注入和维护状态)。

典型场景

无状态工具类。

需要动态配置或依赖其他 Bean 的场景。

选择建议

  • 如果工厂逻辑简单且无状态 → 静态工厂

  • 如果工厂需要依赖注入、维护状态或动态决策 → 实例工厂