Skip to content

注解

@ComponentScan

@ComponentScanSpring / Spring Boot 中用于 指定组件扫描路径 的注解。它的作用是告诉 Spring:去哪些包中查找组件并注册到 IOC 容器

Spring 会扫描带有以下注解的类,并自动创建 Bean:

  • @Component
  • @Service
  • @Repository
  • @Controller
  • @RestController
  • @Configuration

这些都属于 组件(Component)

java
@ComponentScan("com.example")
//扫描 com.example 包及其子包,把标注组件注解的类注册到 Spring 容器。

@ComponentScan 没有写任何参数时,Spring 的行为是:默认扫描当前配置类(或启动类)所在的包及其所有子包。


Spring 容器并不是在启动时翻遍项目里的每一个字节码文件,它的逻辑如下:

  1. 确定根路径:找到标注了 @ComponentScan 的类(通常是启动类)。
  2. 递归搜索:从该路径出发,寻找带有 @Component@Service@Repository@Controller@Configuration(因为 @Configuration 派生自 @Component)的类。
  3. 注册 Bean:将这些类实例化并放入 IoC 容器。

@Configuration

@Configuration 是 Spring Framework 中的一个配置类注解,用于声明一个类是 Spring 的配置类(Configuration Class)。 被这个注解标记的类,相当于以前的 XML 配置文件,主要用于 定义 Bean

当一个类被 @Configuration 标注后,Spring 在启动时会:

  1. 把这个类当成配置类加载
  2. 解析类中的 @Bean 方法
  3. 把返回对象注册到 Spring 容器
java
@Configuration
public class AppConfig {

    @Bean
    public UserService userService() {
        return new UserService();
    }
}

启动后,Spring 容器中就会有一个 UserService Bean。

特性true (Full)【默认】false (Lite)
CGLIB 代理
方法直调永远返回容器中的单例每次调用都执行方法逻辑(非单例)
启动速度较慢(需生成字节码)快(直接反射实例化)
限制类和方法不能用 final无限制
java
@Configuration(proxyBeanMethods = false) // 设为 false
public class MyConfig {

    @Bean
    public User user() {
        return new User();
    }

    @Bean
    public OrderService orderService() {
        // 关键点:由于没代理,这里调用 user() 会直接 new 一个 User
        // 这个 User 和容器里那个 user Bean 不是同一个对象!
        return new OrderService(user()); 
    }
}

无论 proxyBeanMethodstrue 还是 false,Spring 容器启动后,内部只会有 2 个由它管理的 Bean

  1. user (类型: User)
  2. orderService (类型: OrderService)

虽然容器里只有 2 个 Bean,但在 JVM 堆内存 中,对象的情况完全不同:

proxyBeanMethods = false 时:

内存中会存在 3 个对象

  • 对象 A (User):Spring 调用 user() 方法创建的,并存入了 IOC 容器。
  • 对象 B (OrderService):Spring 调用 orderService() 方法创建的,并存入了 IOC 容器。
  • 对象 C (User):在创建 OrderService 时,由于内部又调用了一次 user(),导致方法体内的 new User() 再次执行

@Import

@ImportSpring 中用于向容器导入组件(Bean)的注解。 它通常写在 @Configuration 配置类上,作用是 把指定的类注册到 Spring 容器中,相当于手动把 Bean 加入容器。

java
@Configuration
@Import(UserService.class)
public class AppConfig {
}

@ImportResource

@ImportResourceSpring 用来导入 XML 配置文件的注解把 XML 中定义的 Bean 加载到当前 Spring 容器中

java
@Configuration
@ImportResource("classpath:beans.xml")
public class AppConfig {
}
  • beans.xml
xml
<beans>
    <bean id="userService" class="com.demo.UserService"/>
</beans>