当前位置: 首页 > article >正文

SpringBoot中的Component和ComponentScan注解工作原理

Spring IoC 容器的工作是通过管理对象的生命周期和配置来保持业务逻辑清晰,但是 Spring 容器并不会自动知道要管理哪些 bean。所以我们来告诉 Spring 应该处理哪些 bean 以及如何处理,很简单这就是 Spring 的 @Component 和 @ComponentScan 注释的作用所在。

Spring的@Component注释的作用

创建一个由 Spring 管理的 JavaBean,那么引起 IoC 容器注意的一种方法就是用 Spring 的 @Component 注释来装饰该类,其他注解@Service等同于@Component,这里以@Component注解来统一说明。

以下代码显示两个类由 Spring 容器管理,因此都使用 @Component 注释进行修饰。但是,简单地将 @Component 注释添加到 JavaBean 并不意味着它将自动由Spring 框架进行管理。只有当明确告知容器搜索 @Component 注释的类时,注释才会使 Spring 管理修饰的类。这就是 @ComponentScan 注释的作用所在。

@Component
public class Score {
  int wins, losses, ties;
}

@Component
public class Game {
  @Autowired
  private Score score;

  public void playTheGame(String gesture) {
    score.wins++;
  }
}

Spring 的 @ComponentScan 注解起什么作用?

如果在初始化期间,Spring 容器加载了一个使用 @ComponentScan 注释修饰的 bean,Spring 将在该类的包和子包中搜索带有 @Component 注释的类。如果找到,Spring IoC 容器将自动管理它们。

在下面的代码中,SimpleExample 类既用 @ComponentScan 注释修饰,又在 Spring IoC 容器初始化时加载到 Spring 的 ApplicationContext 中。ApplicationContext 是代表 Spring IoC 容器的 Java 接口的名称。

@ComponentScan
public class SimpleExample {
public static void main(String[] args) {
    SpringApplication springApp = new SpringApplication(Score.class, Game.class);
    ApplicationContext springContainer = springApp.run(args);

    Game game = springContainer.getBean(Game.class);

    game.playTheGame("rock");
    System.out.print(game.score.wins);
    System.out.print(game.score.wins); // prints 1
  }
}

当此代码运行时,Game类和Score类都由Spring容器管理。当main方法运行时,会从容器中拉取Game类的实例,并通过Spring的依赖注入机制初始化Game的分数,当将获胜次数打印到控制台时,显示了正确的输出1。

Spring 的 @Component 和 @ComponentScan 一起

可以看到,@ComponentScan 和 @Component 注释一起起作用。@Component 注释表示如果在组件扫描期间发现某个类,则该类应该由Spring IoC 容器进行管理,而使用 @ComponentScan 注释修饰的类才是真正触发组件扫描的类。

@SpringBootApplication注解

实际使用中我们用到更多的是这个@SpringBootApplication注解,并没有看到ComponentScan,那是因为@SpringBootApplication这个注解帮我们做了很多事情,已经自动帮我引入了@ComponentScan注解,同时有默认的扫描Component策略。
在这里插入图片描述

ComponentScan扫描包的策略

指定包
@ComponentScan(basePackages = "com.example")
public class SpingbootBannerDemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpingbootBannerDemoApplication.class, args);
	}

}
过滤掉指定的class
@ComponentScan(basePackages = "com.example", excludeFilters = {@ComponentScan.Filter(type= FilterType.CUSTOM, classes={HelloWorld.class}) })
public class SpingbootBannerDemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpingbootBannerDemoApplication.class, args);
	}

}
更多用法

在这里插入图片描述


http://www.kler.cn/news/356356.html

相关文章:

  • 各种语言的序列化与反序列化(C/C++ c# Python Javascript Java)
  • 【C++】string类(接口使用详解 下)
  • c++中,经常需要用来获取用户输入的写法,或者暂停【防止终端退出】
  • MySQL中8.0为啥引入索引跳跃扫描(Index Skip Scan)
  • 基于DE1-SOC的My_first_fpga
  • 14.归一化——关键的数据预处理方法
  • 汽车与航空领域的功能安全对比:ISO 26262-6 与 DO-178C 的差异浅析
  • 【分布式微服务云原生】《Redis 大 Key 和热点 Key:问题与解决方案全攻略》
  • Python画笔案例-083 绘制 3D世界坐标轴
  • Gin框架操作指南04:GET绑定
  • Python编程探索:从基础语法到循环结构实践(下)
  • python高级函数详解
  • [含文档+PPT+源码等]精品基于Nodejs实现的微信小程序校园心理健康平台设计与实现
  • Unity性能优化
  • 拓扑学与集合论的关系
  • 除了 Python,还有哪些语言适合做爬虫?
  • 从空口分析经典蓝牙A2DP和AVRCP协议
  • 2012年国赛高教杯数学建模A题葡萄酒的评价解题全过程文档及程序
  • 周末总结(2024/10/19)
  • GDAL+C#实现矢量多边形转栅格