Bean 的注册:XML、注解与 JavaConfig 装配

引言

要让容器“认识”一个类并管理它,必须先把它注册成 Bean。Spring 历史上先后演化出三种注册方式:XML、组件扫描注解、JavaConfig。它们解决同一个问题——告诉容器“有哪些对象、怎么创建”,只是写法不同。本章三种方式各给一个最小示例并说明混用规则。

核心概念

  • XML 方式:在配置文件中用 <bean id="..." class="..."> 声明,一个 <bean> 对应一个 Bean;另可用 <context:component-scan> 扫描注解。
  • 注解方式:在类上标注 @Component 及其语义化子注解(@Service@Repository@Controller@Configuration),再用 @ComponentScan 指定扫描包路径。
  • JavaConfig 方式@Configuration 类中用 @Bean 方法声明 Bean,方法返回值即 Bean 实例,方法名默认即 Bean 名称;适合注册第三方类或构造逻辑复杂的 Bean。
  • 三者都注册进同一个容器,可共存:XML 声明 + 扫描注解 + @Bean 混用是允许的,同名冲突时以注册先后/覆盖规则为准(以官方文档为准)。

代码示例

// 方式一:XML(classpath:beans.xml)
// <beans ...> 需声明 beans 命名空间(具体 schema 位置以官方文档为准,此处从略)
//   <bean id="greetingService"
//         class="com.example.GreetingService"/>
// </beans>
// 容器:new ClassPathXmlApplicationContext("beans.xml")

// 方式二:组件扫描注解
@Service
public class GreetingService {
    public String greet(String who) { return "Hello, " + who; }
}

@Configuration
@ComponentScan("com.example") // 扫描 com.example 下的 @Component/@Service/...
public class AppConfig { }

// 方式三:JavaConfig 显式 @Bean
@Configuration
public class AppConfig2 {
    @Bean
    public GreetingService greetingService() {
        return new GreetingService(); // 也可以在这里做复杂构造
    }
}

// 三种方式统一用容器获取:
try (AnnotationConfigApplicationContext ctx =
             new AnnotationConfigApplicationContext(AppConfig.class)) {
    GreetingService s = ctx.getBean("greetingService", GreetingService.class);
    System.out.println(s.greet("Spring"));
}

注意点

  • @Component 系注解必须配合 @ComponentScan(或 Boot 的 @SpringBootApplication)才会被扫描到;忘了扫描是新手最常见问题。
  • @Bean 方法返回类型决定 Bean 类型;方法所在 @Configuration 类本身也是个 Bean。
  • XML 命名空间与 Spring 版本相关,现代项目优先注解/JavaConfig;老项目改造时注意混用陷阱(同名 Bean 覆盖、扫描范围重叠)。
  • Bean 名称默认规则:注解为类名首字母小写,@Bean 为方法名;均可用 @Service("name")/@Bean("name") 显式指定。

小结

三种注册方式解决同一件事:XML 声明式、注解靠扫描、JavaConfig 用 @Bean 方法。推荐组合是“@Component 标业务类 + @ComponentScan 扫描 + @Bean 注册第三方类”,第 04 章将在此基础上讲依赖注入。

笔记加载中…