@Configurable

作用: @Configurable 注解主要用于支持 Spring 对非 Spring 管理对象的依赖注入(DI)。当一个类被标记为 @Configurable 时,Spring 将能够对该类的实例进行依赖注入,即使这些实例不是通过 Spring 容器直接创建的(例如,通过 new 关键字直接实例化)。这意味着即使在非 Spring 管理的代码中创建的对象,也可以享受到 Spring 的依赖注入特性。

特性与应用场景:

  1. 开启 AspectJ 支持: @Configurable 功能的实现通常依赖于 AspectJ(一个面向切面编程的框架)。你需要在项目中集成 AspectJ 编译器或加载时编织器(LTW, Load-Time Weaving),以便在对象创建时动态地应用依赖注入。

  2. 与 Spring 容器关联: @Configurable 类型的对象必须与一个 Spring 容器关联,通常是通过指定 @Configurable 注解中的 value 属性或 @EnableSpringConfigured 注解来指明关联的配置类或配置命名空间。

  3. 适用于领域驱动设计(DDD)中的实体对象: 在 DDD 中,业务实体通常由 ORM 工具(如 Hibernate)自动创建,而非通过 Spring 容器。@Configurable 可以确保这些由 ORM 创建的对象也能获得 Spring 管理的依赖。

  4. 支持代理模式: 为了实现对非容器管理对象的依赖注入,Spring 可能会为 @Configurable 类型的对象生成代理对象。当通过 new 关键字创建实例时,实际上是创建了一个代理对象,该代理对象在初始化时会触发依赖注入过程。

示例:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.Configurable;

@Configurable
public class MyService {
    @Autowired
    private Dependency dependency; // 这个依赖即使在非 Spring 容器中创建 MyService 实例时也会被注入
}

@Configuration

作用: @Configuration 注解标识一个类作为 Spring IoC 容器中的一个“配置类”,即一个特殊的 Bean 定义源。这样的类可以包含方法,这些方法通过 @Bean 注解来声明和配置 Bean。配置类相当于传统的 XML 配置文件,但采用更加类型安全和易于维护的 Java 代码形式。

特性与应用场景:

  1. 声明和配置 Bean: 配置类中的 @Bean 方法返回的对象会被注册为 Spring 容器中的 Bean。这些方法可以拥有复杂的逻辑,包括调用其他 @Bean 方法来构建依赖关系。

  2. 支持组件扫描: 当配置类与 @ComponentScan 注解结合使用时,可以自动扫描指定包及其子包中的组件(如标有 @Component, @Service, @Repository, @Controller 的类),并将它们作为 Bean 注册到容器中。

  3. 内建 Bean 间的依赖: 配置类中的 @Bean 方法可以相互调用,从而明确表示 Bean 之间的依赖关系。Spring 会根据方法的调用顺序来确定依赖注入的顺序。

  4. 替代 XML 配置: @Configuration 类是 Spring 从 XML 配置转向基于注解配置的关键部分,它极大地简化了 Spring 应用程序的配置方式,使得配置与业务逻辑紧密集成。

示例:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {

    @Bean
    public Dependency dependency() {
        return new Dependency();
    }

    @Bean
    public MyService myService() {
        return new MyService(dependency()); // 显式依赖注入
    }
}

区别总结

  • @Configurable 主要用于支持非 Spring 容器管理的对象进行依赖注入,通常与 AspectJ 结合使用,适用于那些由第三方库(如 ORM 工具)创建或通过 new 关键字直接实例化的对象。

  • @Configuration 标记的类是一个特殊的 Bean 定义源,用于声明和配置 Spring 容器中的 Bean。它是基于 Java 代码的配置方式,替代或补充传统的 XML 配置,提供了更强大的编程能力和更好的代码组织结构。

简而言之,@Configurable 使非 Spring 管理的对象也能获得依赖注入的能力,而 @Configuration 用于定义和组织 Spring 容器中的 Bean 配置。两者在功能和应用场景上存在显著差异,分别解决 Spring 应用程序中不同的配置需求。