[Spring实战系列](14)Bean的自动检测

简介: 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/SunnyYoona/article/details/50650102 即使有助于完全消除Spring注解中的和元素,但是还是不能完全消除,仍然需要使用元素显示定义Bean。
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/SunnyYoona/article/details/50650102
即使 <context:annotation-config>有助于完全消除Spring注解中的<property>和<constructor-arg>元素,但是还是不能完全消除,仍然需要使用<bean>元素显示定义Bean。因此 <context:component-scan>元素出现了,它除了 完成<context:annotation-config>一样的工作,还允许Spring自动检测Bean定义Bean。这就意味着我们不使用<bean>元素,Spring应用中的大多数(或者所有)Bean都能够实现定义和装配。

为了配置Spring自动检测,需要使用<context:component-scan>元素来代替<context:annotation-config>元素:
 
   
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="">
</context:component-scan>
 
</beans>

<context:component-scan>元素会 扫描指定的包以及所有子包,并 查找出能够自动注册为Spring Bean的类base-package属性标示了 <context:component-scan>元素所扫描的包

为自动检测标注Bean

默认情况下, <context:component-scan>查找使用构造型(stereotype)注解所标注的类,这些特殊的注解如下:
类型 说明
@component 通用的构造型注解,标示该类为Spring 组件。
@Controller
标识将该类定义为Spring MVC controller。
@Repository
标识将该类定义为数据仓库(例如:Dao层)。
@Service 标识将该类定义为服务(例如:Service层)。

1. @component

假设我们应用上下文中仅仅包含Student和School两个Bean。我们可以配置 <context:component-scan>元素并使用@Component注解标注Student和School类,从而消除显示的<bean>定义。
 
   
package com.sjf.bean;
 
import org.springframework.stereotype.Component;
 
/**
* 学校实体类
* @author sjf0115
*
*/
@Component
public class School {
private String name;
private String location;
...
}
Spring 扫描com.sjf.bean包时,会发现 使用Component注解所标注的School,并 自动将它注册为Spring BeanBean的ID默认为无限定类名(第一个字母小写),School Bean的ID为school

下面我们标注Student类:
 
   
package com.sjf.bean;
 
import org.springframework.stereotype.Component;
 
/**
* 学生实体类
* @author sjf0115
*
*/
@Component("studentBean")
public class Student {
private String name;
private int age;
private School school;
...
}

这种场景下,我们 指定了一个Bean ID作为@Component注解的参数。该Bean 的ID不会使用默认的类名,而是显示的命名为studentBean。

当使用<context:component-scan>时,基于注解的自动检测只是一种扫描策略。下面让我们来了解其他的扫描策略来查找候选Bean。

2. 过滤组件扫描

在如何扫描来获得候选Bean方面, <context:component-scan>元素非常灵活。通过为 <context:component-scan>配置<context:include-filter>和<context:exclude-filter>子元素,我们可以随意调整扫描行为。

假设我们基于注解让<context:component-scan>自动注册所有实现某个接口的类,我们不得不浏览每一个接口实现的类,并使用@Component来标注它们,非常不方便。所以我们替换掉基于注解的组件扫描策略,再增加一个包含过滤器来要求<context:component-scan>注册以及排除类。
 
   
<context:component-scan base-package="com.sjf.bean">
<context:include-filter type="" expression=""/>
<context:exclude-filter type="" expression=""/>
</context:component-scan>

<context:include-filter>的type和expression属性一起协作来定义组件扫描策略。我们还可以选择如下任意一种过滤器:
类型 说明
annotation 过滤器扫描使用指定注解标注的那些类,通过expression属性指定要扫描的注解
assignable 过滤器扫描派生于expression属性所指定类型的那些类
aspectj 过滤器扫描与expression属性所指定的AspectJ表达式所匹配的那些类
custom 使用自定义的org.springframework.core.type.TypeFilter实现类,该类由expression属性指定。
regex 过滤器扫描类的名称与expression属性所指定的正则表达式所匹配的那些类

除了使用<context:include-filter>告知<context:component-scan>哪些类需要注册为Spring Bean以外,我们还可以使用 <context:exclude-filter>来告知 <context:component-scan>哪些类不需要注册为Spring Bean。

我们实现了两个接口,一个是Worker接口(员工),一个是Performer(表演者)。然后根据这两个接口,分别实现了接口的实现类:
 
   
package com.sjf.bean;
/**
* 农民实体类
* @author sjf0115
*
*/
public class Farmer implements Worker {
 
public void work() {
System.out.println("正在辛勤的耕地...");
}
}

我们使用<context:include-filter>告知<context:component-scan>实现了Worker接口的实现类需要注册为Spring Bean,使用 <context:exclude-filter>来告知实现了Perfomer接口的实现类 不需要注册为Spring Bean。
 
   
<context:component-scan base-package="com.sjf.bean">
<context:include-filter type="assignable" expression="com.sjf.bean.Worker"/>
<context:exclude-filter type="assignable" expression="com.sjf.bean.Performer"/>
</context:component-scan>

我们测试一下上述过滤器是否起作用了:
 
   
Farmer farmer = (Farmer) context.getBean("farmer");
farmer.work();

运行结果:

正在辛勤的耕地...  

 
   
Singer singer = (Singer) context.getBean("singer");
singer.perform();

运行结果:

Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'singer' is defined  



参考:《Spring实战》




目录
相关文章
|
1月前
|
XML Java 测试技术
Spring IOC—基于注解配置和管理Bean 万字详解(通俗易懂)
Spring 第三节 IOC——基于注解配置和管理Bean 万字详解!
135 26
|
3月前
|
XML 安全 Java
|
4天前
|
人工智能 自然语言处理 前端开发
Spring AI与DeepSeek实战二:打造企业级智能体
本文介绍如何基于Spring AI与DeepSeek模型构建企业级多语言翻译智能体。通过明确的Prompt设计,该智能体能自主执行复杂任务,如精准翻译32种ISO标准语言,并严格遵循输入格式和行为限制。代码示例展示了如何通过API实现动态Prompt生成和翻译功能,确保服务的安全性和可控性。项目已开源,提供更多细节和完整代码。 [GitHub](https://github.com/zlt2000/zlt-spring-ai-app) | [Gitee](https://gitee.com/zlt2000/zlt-spring-ai-app)
82 11
|
11天前
|
人工智能 Java API
Spring AI与DeepSeek实战一:快速打造智能对话应用
在 AI 技术蓬勃发展的今天,国产大模型DeepSeek凭借其低成本高性能的特点,成为企业智能化转型的热门选择。而Spring AI作为 Java 生态的 AI 集成框架,通过统一API、简化配置等特性,让开发者无需深入底层即可快速调用各类 AI 服务。本文将手把手教你通过spring-ai集成DeepSeek接口实现普通对话与流式对话功能,助力你的Java应用轻松接入 AI 能力!虽然通过Spring AI能够快速完成DeepSeek大模型与。
286 11
|
23天前
|
JavaScript 前端开发 Java
Jeesite5:Star24k,Spring Boot 3.3+Vue3实战开源项目,架构深度拆解!让企业级项目开发效率提升300%的秘密武器
Jeesite5 是一个基于 Spring Boot 3.3 和 Vue3 的企业级快速开发平台,集成了众多优秀开源项目,如 MyBatis Plus、Bootstrap、JQuery 等。它提供了模块化设计、权限管理、多数据库支持、代码生成器和国际化等功能,极大地提高了企业级项目的开发效率。Jeesite5 广泛应用于企业管理系统、电商平台、客户关系管理和知识管理等领域。通过其强大的功能和灵活性,Jeesite5 成为了企业级开发的首选框架之一。访问 [Gitee 页面](https://gitee.com/thinkgem/jeesite5) 获取更多信息。
Jeesite5:Star24k,Spring Boot 3.3+Vue3实战开源项目,架构深度拆解!让企业级项目开发效率提升300%的秘密武器
|
3月前
|
存储 Java Spring
【Spring】获取Bean对象需要哪些注解
@Conntroller,@Service,@Repository,@Component,@Configuration,关于Bean对象的五个常用注解
|
3月前
|
存储 Java 应用服务中间件
【Spring】IoC和DI,控制反转,Bean对象的获取方式
IoC,DI,控制反转容器,Bean的基本常识,类注解@Controller,获取Bean对象的常用三种方式
|
3月前
|
XML Java 数据格式
Spring容器Bean之XML配置方式
通过对以上内容的掌握,开发人员可以灵活地使用Spring的XML配置方式来管理应用程序的Bean,提高代码的模块化和可维护性。
89 6
|
3月前
|
XML Java 数据格式
🌱 深入Spring的心脏:Bean配置的艺术与实践 🌟
本文深入探讨了Spring框架中Bean配置的奥秘,从基本概念到XML配置文件的使用,再到静态工厂方式实例化Bean的详细步骤,通过实际代码示例帮助读者更好地理解和应用Spring的Bean配置。希望对你的Spring开发之旅有所助益。
223 4
|
4月前
|
缓存 Java Spring
实战指南:四种调整 Spring Bean 初始化顺序的方案
本文探讨了如何调整 Spring Boot 中 Bean 的初始化顺序,以满足业务需求。文章通过四种方案进行了详细分析: 1. **方案一 (@Order)**:通过 `@Order` 注解设置 Bean 的初始化顺序,但发现 `@PostConstruct` 会影响顺序。 2. **方案二 (SmartInitializingSingleton)**:在所有单例 Bean 初始化后执行额外的初始化工作,但无法精确控制特定 Bean 的顺序。 3. **方案三 (@DependsOn)**:通过 `@DependsOn` 注解指定 Bean 之间的依赖关系,成功实现顺序控制,但耦合性较高。
198 4
实战指南:四种调整 Spring Bean 初始化顺序的方案