Component-Scan

在前一节的内容中,我们可以通过 Annotation 来指导 Bean 的依赖关系,然而 Bean 本身的定义还是写在 XML 当中,下面我们介绍一种方法,允许我们直接在代码中创建出 Bean。这种方法被称为 Component-Scan。

首先我们修改 XML 配置,打开 Component-Scan 功能:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans
  6. http://www.springframework.org/schema/beans/spring-beans.xsd
  7. http://www.springframework.org/schema/context
  8. http://www.springframework.org/schema/context/spring-context.xsd">
  9. <context:component-scan base-package="com.skyline"/>
  10. </beans>

注意我们去掉了所有的 Bean 定义,也同时去掉了 <context:annotation-config>,因为 <context:component-scan> 默认就会打开 <context:annotation-config>,因此不需要再手动设置 <context:annotation-config>

Component

Spring 中定义了若干用于注册 Bean 的 Annotation,包括 @Component 以及继承自 @Component@Service@Repository。所谓的 component-scan 也就是告诉 Spring 去扫描标示了这些 Annotation 的类,将它们用于 Bean 的注册。 Spring 中推荐使用 @Service@Component 标示逻辑和服务层的组件,使用 @Repository 标示持久层的组件。

@Service@Repository 都继承自 @Component,因此在 Bean 注册的层面,它们没有本质上的区别,不过 @Repository 在持久层会有一个 exception 转换的作用,这里先略去不讲。

创建一个新类 MyPersonComponent:

  1. package com.skyline.service;
  2. import com.skyline.model.Person;
  3. import org.springframework.context.annotation.Bean;
  4. import org.springframework.stereotype.Component;
  5. @Component
  6. public class MyPersonComponent {
  7. @Bean("aPerson")
  8. public Person testPerson() {
  9. Person aPerson = new Person();
  10. aPerson.setName("Chester");
  11. return aPerson;
  12. }
  13. @Bean("myService")
  14. public MyServiceImpl testService() {
  15. MyServiceImpl service = new MyServiceImpl();
  16. service.setGreeting("Hello");
  17. return service;
  18. }
  19. }

可以看到,我们基本就是把原先在 XML 当中的配置,挪到了 Java 代码当中。运行代码,得到和之前一样的结果

注意到我们的 MyServiceImpl 仅仅设置了 greeting,为什么这样就能够正常工作呢?还记得上一节的 @Autowired 吗,它依然在发挥自己的作用,帮我们找到了 Person 的实例,并且赋给了 MyServiceImpl