Spring系统学习 - 基于注解管理Bean

什么是基于注解的方式管理Bean

在 Spring 框架中,基于注解的方式管理 Bean 是一种非常流行且现代的方法。它允许你通过在类、方法或字段上添加特定的注解来声明 Bean 的创建和依赖注入,从而避免了在 XML 配置文件中定义 Bean 的繁琐工作。

注解和 XML 配置文件一样,注解本身并不能执行,注解本身仅仅只是做一个标记,具体的功能是框架检测到注解标记的位置,然后针对这个位置按照注解标记的功能来执行具体操作。

本质上:所有一切的操作都是Java代码来完成的,XML和注解只是告诉框架中的Java代码如何执行。

用通俗的话来说就是,不管是注解还是XML实际上就相当于,我们在现实生活中,假设你手上有一群人,然后你需要这群人去做三个任务,对于你标记为红色区域的,要放置红色的花朵,你标记为黄色的区域就放置黄色话多,标记为绿色的地方,就放置绿色草块,你标记完毕之后,剩下的放置花朵和草块的地方就交给你手上的那群人去完成就行。

扫描

上面我举了一个例子,用来标记不同颜色的地方,然后分别对不同颜色的地方做不同的事情,那么Spring是如何知道程序员在哪些地方标记了哪些注解呢?

spring是通过扫描的方式来进行检测,在检测成功之后,根据我们配置的注解来进行后续操作。

<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>SSM</artifactId><groupId>com.miaow</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>spring-annotation</artifactId><packaging>jar</packaging><name>spring-annotation</name><description>Spring基于注解管理Bean</description><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.2</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13</version><scope>test</scope></dependency></dependencies></project>

在这里插入图片描述

@Component, @Service, @Repository, @Controller

这些是组件扫描时使用的注解,它们都是@Component的特殊化,用于标记特定类型的类。Spring会自动发现并注册这些带有注解的类为Bean。

  • @Component:通用注解,可以用于任何层次的类。
  • @Service:通常用于标注业务层服务类。
  • @Repository:通常用于标注数据访问层(如DAO类)。
  • @Controller:用于标注控制器层,主要用于处理HTTP请求。

在这里插入图片描述
我们通过看了@Controller注解为例子,@Controller、@Service、@Repository这三个注解只是在@Component注解的基础上起了三个新的名字。

对于Spring使用IOC容器管理这些组件来说没有区别。所以@Controller、@Service、@Repository这三个注解只是给开发人员看的,让我们能够便于分辨组件的作用。

注意:虽然它们本质上一样,但是为了代码的可读性,为了程序结构严谨我们肯定不能随便胡乱标记。

案例

目录结构

在这里插入图片描述

创建组件

创建控制层

@Controller("controller") //自定义bean的id
//@Controller
public class UserController {/*** 能够找到唯一的bean:直接执行装配* 如果完全找不到匹配这个类型的bean:装配失败* 如果找到多个匹配这个类型的bean:* 1.如果这个类型的bean只有一个,那么直接装配* 2.如果这个类型的bean有多个,那么就需要通过@Qualifier注解来指定装配哪个bean** 没有@Qualifier注解:根据@Autowired标记位置成员变量的变量名作为bean的id进行匹配**/@Autowired@Qualifier("userServiceImpl")  //byName 根据@Qualifier注解中指定的名称作为bean的id进行匹配private UserService userService;public String getUser(){return "user";}public UserController(UserService userService) {this.userService = userService;}public void savaUser(){userService.saveUser();}
}

创建Service接口

public interface UserService {void add();void saveUser();
}

创建Service接口实现层

@Service
public class UserServiceImpl implements UserService {@Autowiredprivate UserDao userDao;@Overridepublic void add() {System.out.println("添加成功");}@Overridepublic void saveUser() {userDao.saveUser();}
}

创建Dao层接口

public interface UserDao {/*** 保存用户*/int saveUser();
}

创建Dao层接口实现层

@Repository
public class UserDaoImpl implements UserDao {@Overridepublic int saveUser() {System.out.println("保存成功");return 1;}
}

创建一个User类

//其实没啥用
public class User {public void sayHello(){System.out.println("hello");}
}

创建一个spring-annotation.xml配置文件

<?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 https://www.springframework.org/schema/context/spring-context.xsd"><!--    扫码组件的几种方式  -->
<!--   1 基于包内的最基本的扫描方式 --><context:component-scan base-package="com.miaow.spring"><!--    2:指定要排除的组件 --><!-- context:exclude-filter标签:指定排除规则 --><!--type:设置排除或包含的依据type="annotation",根据注解排除,expression中设置要排除的注解的全类名type="assignable",根据类型排除,expression中设置要排除的类型的全类名--><!--    排查扫描控制层 建议配置方式-->
<!--        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"></context:exclude-filter>--><!--    单个指定太麻烦了,不推荐方式    -->
<!--        <context:exclude-filter type="assignable" expression="com.miaow.spring.controller.UserController"/>--><!--        3 仅仅扫描指定的组件   use-default-filter="false" --><!-- context:include-filter标签:指定在原有扫描规则的基础上追加的规则 --><!-- use-default-filters属性:取值false表示关闭默认扫描规则 --><!-- 此时必须设置use-default-filters="false",因为默认规则即扫描指定包下所有类 --><!--type:设置排除或包含的依据type="annotation",根据注解排除,expression中设置要排除的注解的全类名type="assignable",根据类型排除,expression中设置要排除的类型的全类名-->
<!--        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"></context:include-filter>-->
<!--        <context:include-filter type="annotation" expression="org.springframework.stereotype.Service"></context:include-filter>--><!--        <context:include-filter type="assignable" expression="com.miaow.spring.controller.UserController"/>--></context:component-scan>
</beans>

创建测试类

    @Autowiredprivate UserService userService;@Testpublic void test(){ApplicationContext context = new ClassPathXmlApplicationContext("spring-annotation.xml");// UserController controller = (UserController) context.getBean("userController");//这样发现我们获取不到UserController controller = (UserController) context.getBean("controller");//这样我们发现可以获到相关值System.out.println(controller);}//测试@AutrWired注解/*** Autowired工作流程* 1. 通过反射获取类中的属性* 2. 通过反射获取属性上的注解* 3. 通过注解获取属性的名称* 4. 通过名称获取bean* 5. 将bean设置到属性上* 6. 将bean设置到ioc容器中*/@Testpublic void testAutowired(){ApplicationContext context = new ClassPathXmlApplicationContext("spring-annotation.xml");// UserController controller = (UserController) context.getBean("userController");//这样发现我们获取不到UserController controller = (UserController) context.getBean("controller",UserController.class);//这样我们发现可以获到相关值System.out.println(controller);controller.savaUser();}

在这里插入图片描述

在这里插入图片描述

其他注解(拓展)

@Autowired

@Autowired注解用于自动装配Bean,Spring会自动将匹配的Bean注入到标记了该注解的字段或方法上。默认按类型匹配,如果需要按名称匹配,可以与@Qualifier一起使用。

@Autowired
private SomeService someService;

在这里插入图片描述
首先根据所需要的组件类型到IOC容器中查找

  • 能够找到唯一的bean:直接执行装配
  • 如果完全找不到匹配这个类型的bean:装配失败
  • 和所需类型匹配的bean不止一个
    • 没有@Qualifier注解:根据@Autowired标记位置成员变量的变量名作为bean的id进行匹配

    • 能够找到:执行装配

    • 找不到:装配失败

    • 使用@Qualifier注解:根据@Qualifier注解中指定的名称作为bean的id进行匹配

    • 能够找到:执行装配

    • 找不到:装配失败

@Autowired中有属性required,默认值为true,因此在自动装配无法找到相应的bean时,会装配失败,可以将属性required的值设置为true,则表示能装就装,装不上就不装,此时自动装配的属性为默认值,但是实际开发时,基本上所有需要装配组件的地方都是必须装配的,用不上这个属性

@Resource

@Resource注解来源于JDK,与@Autowired类似,也是用于依赖注入,但它可以根据名称进行注入,如果没有指定名称,则默认按照类型匹配

@Resource
private SomeService someService;

@Configuration 和 @Bean

@Configuration类允许你通过Java类的方式提供Spring容器的配置,而@Bean注解告诉Spring这是一个Bean的定义,用来创建Bean实例。

@Configuration
public class AppConfig {@Beanpublic MyBean myBean() {return new MyBean();}
}

@Value

@Value注解用于注入属性值,可以直接注入硬编码的值,也可以注入外部配置文件中的值。

@Value("${property.name}")
private String propertyName;

@Scope

@Scope注解用于定义Bean的作用域,默认是singleton(单例),也可以设置为prototype(原型)、request、session等。

@Scope("prototype")
@Service
public class MyPrototypeService {}

启用组件扫描

为了使Spring能够自动发现这些带有注解的类,需要在配置类或XML配置文件中启用组件扫描。在Java配置中,可以使用@ComponentScan注解来实现:

@Configuration
@ComponentScan(basePackages = {"com.example.myapp"})
public class AppConfig {}

Sping和SpringBoot中的一些注解介绍

    /*** @Contoller 添加控制层注解* @Service 添加service层注解* @Repository 添加dao层注解* @Component 添加普通bean注解* @Autowired 添加自动注入注解* @Qualifier 添加bean的名称注解* @Resource 添加自动注入注解* @Value 添加属性注入注解* @Primary 添加主要bean注解* @Lazy 添加延迟加载注解* @Scope 添加作用域注解* @Configuration 添加配置类注解* @Bean 添加bean注解* @Import 添加导入注解* @ImportResource 添加导入资源注解* @PropertySource 添加属性源注解* @ComponentScan 添加组件扫描注解* @Conditional 添加条件注解* @Profile 添加配置文件注解* @ConfigurationProperties 添加配置属性注解* @EnableAspectJAutoProxy 添加切面注解* @Aspect 添加切面注解* @Pointcut 添加切点注解* @Before 添加前置通知注解* @After 添加后置通知注解* @AfterReturning 添加返回通知注解* @AfterThrowing 添加异常通知注解* @Around 添加环绕通知注解* @Order 添加排序注解* @Transactional 添加事务注解* @EnableTransactionManagement 添加事务管理注解* @EnableAspectJAutoProxy 添加切面注解* @EnableCaching 添加缓存注解* @Cacheable 添加缓存注解* @CacheEvict 添加缓存注解* @CachePut 添加缓存注解* @Caching 添加缓存注解* @EnableCaching 添加缓存注解* @EnableScheduling 添加定时任务注解* @Scheduled 添加定时任务注解*/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/36560.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

码农:如何快速融入团队

问题&#xff1a; 码农如何快速融入团队&#xff1f; 记住一个标准&#xff1a;能干事、能抗事。 总结一个字&#xff1a; 靠谱。 适用范围&#xff1a;新手码农、老司机码农、测试、DBA、运维、产品经理、项目经理、架构师、技术专家、。。。。适用于任何行业的打工者。 下面要…

电脑开机就一直在开机界面转圈,怎么回事?

前言 前段时间小白去给一位朋友修电脑。她说这个电脑很奇怪&#xff0c;有时候开机很快就进入电脑界面&#xff0c;但有时候开机一直在那转圈&#xff0c;半天也不见进入。 Windows7系统的小伙伴应该也有遇到过类似的问题&#xff0c;就是电脑一直在Windows的logo界面&#xf…

自动驾驶水泥搅拌车在梁场的应用(上)

北京渡众机器人科技有限公司的自动驾驶水泥搅拌车在梁场的应用可以极大地提升生产效率和安全性。通常情况下&#xff0c;梁场是用于预制混凝土梁的生产和装配的场地&#xff0c;传统上需要大量的人工操作和搅拌车的驾驶。引入自动驾驶技术可以带来以下几个显著的优势&#xff1…

AI进阶指南第五课,大模型相关概念(知识库,微调)

虽然前面大概讲了一下大模型的一些基本概念&#xff0c;但是那些都比较偏向于大模型本身&#xff0c;但是我们使用的时候如果只靠大模型肯定是不行的。 就好比如果一个人只有一个脑子&#xff0c;其他什么部位也没有的话&#xff0c;那场面。&#xff08;感觉现在网上的AI图片…

npm install报错Maximum call stack size exceeded

npm 报错 方案&#xff1a; npm cache clean --force npm install

成功解决​​​​​​​TypeError: __call__() got an unexpected keyword argument ‘first_int‘

成功解决TypeError: __call__() got an unexpected keyword argument first_int 目录 解决问题 解决思路 解决方法 T1、直接调用原始函数 T2、检查装饰器实现 T3、使用不同的调用方式 解决问题 result = multiply(**arguments) File "D:\ProgramData\Anaconda3\Li…

Redis 7.x 系列【10】数据类型之有序集合(ZSet)

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Redis 版本 7.2.5 源码地址&#xff1a;https://gitee.com/pearl-organization/study-redis-demo 文章目录 1. 概述2. 常用命令2.1 ZADD2.2 ZCARD2.3 ZSCORE2.4 ZRANGE2.5 ZREVRANGE2.6 ZRANK2.7…

kettle使用手册 安装9.0版本 建议设置为英语

0.新建转换的常用组件 0. Generate rows 定义一个字符串 name value就是字符串的值 0.1 String operations 字段转大写 去空格 1. Json input 来源于一个json文件 1.json 或mq接收到的data内容是json字符串 2. Json output 定义Jsonbloc值为 data, 左侧Fieldname是数据库…

常见的字符串函数(包含头文件string.h)和字符函数(2)

八. strstr函数 1.strstr的定义 char *strstr( const char *str1, const char *str2 ); ->1. strstr查找子串(str2)在字符串(str2)中第一次出现的位置&#xff0c;记录并返回该位置的指针&#xff0c;如果找不到&#xff0c;则返回NULL ->2. str1&#xff1a;查找字符…

springboot + Vue前后端项目(第二十记)

项目实战第二十记 写在前面1. 高德地图官网2. 开发文档3. 集成高德地图3.1 在public文件夹下创建config.js3.2 index.html&#xff08;在项目启动文件中引入外部的js&#xff09;3.3 点标记&#xff08;用点标记当前位置&#xff09;3.4 信息窗体&#xff08;点击当前位置&…

【MAVEN学习 | 第2篇】Maven工程创建及核心功能

文章目录 一. 基于IDEA的Maven工程创建1.1 Maven工程GAVP属性&#xff08;1&#xff09;GroupID 格式&#xff08;2&#xff09;ArtifactID 格式&#xff08;3&#xff09;Version版本号格式&#xff08;4&#xff09;Packaging定义规则 1.2 IDEA构建Maven JavaSE工程1.3 IDEA构…

Termius:现代化的SSH客户端,让服务器管理变得优雅简洁

Termius简介 是一款现代化的跨平台终端模拟器和SSH客户端。以下是对Terminus的介绍以及使用它的理由&#xff1a; 跨平台兼容性&#xff1a; Terminus支持Windows、macOS、Linux、IOS和Android&#xff0c;让用户在不同操作系统间保持一致的终端体验。优雅的用户界面&#xf…

通达信机构买卖抓牛指标公式源码

通达信机构买卖抓牛指标公式源码&#xff1a; X_1:V/CLOSE/2; X_2:SUM(IF(X_1>100 AND CLOSE>REF(CLOSE,1),X_1,0),0); X_3:SUM(IF(X_1>100 AND CLOSE<REF(CLOSE,1),X_1,0),0); X_4:SUM(IF(X_1<100 AND CLOSE>REF(CLOSE,1),X_1,0),0); X_5:SUM(IF(X_1&l…

ATA-7025:高压放大器的原理是怎样的

高压放大器是一种电子器件&#xff0c;主要用于将输入信号的电压放大到更高的水平。它在许多领域中都有重要的应用&#xff0c;包括医学影像设备、科学研究装置、激光系统等。高压放大器的原理涉及到放大器的工作原理、电路结构、工作特性等多个方面。下面将从这些方面对高压放…

.net core接入nacos注册服务并使用配置中心

1、安装依赖 Nuget包&#xff1a;nacos-sdk-csharp.Extensions.Configuration和nacos-sdk-csharp.AspNetCore 2、在appsettings.json中配置 "nacos": {"ServerAddresses": ["http://localhost:8848/"],"DefaultTimeOut": 15000,"…

各省药品集中采购平台-地方药品集采分析数据库

国家第十批药品集中采购的启动时间暂未明确&#xff0c;但即将到来&#xff0c;在5月&#xff0c;国家医保局发布了《关于加强区域协同做好2024年医药集中采购提质扩面的通知》&#xff0c;其中明确指出将“开展新批次国家组织药品和医用耗材集中带量采购&#xff0c;对协议期满…

Vue2 - 项目上线后生产环境中去除console.log的输出以及断点的解决方案

前言 当你准备将Vue.js应用程序部署到生产环境时,一个关键的优化步骤是移除代码中的所有 console.log 语句以及断点。在开发阶段,console.log 是一个非常有用的调试工具,但在生产环境中保留它们可能会影响性能和安全性。在本文中,我将向你展示如何通过使用Vue CLI 2来自动…

大语言模型在医疗领域的进展、应用和挑战_医疗大语言模型算法csdn

### 概述 本文综述了医学领域大型语言模型&#xff08;LLM&#xff09;的进展、应用和面临的挑战。大型语言模型如ChatGPT在理解和生成人类语言方面显示出了显著的能力&#xff0c;引起了广泛关注。在医学领域&#xff0c;研究人员正致力于利用LLM支持各种医疗任务&#xff0c…

13 Redis-- MySQL 和 Redis 的数据一致性

Redis-- MySQL 和 Redis 的数据一致性 先抛一下结论&#xff1a;在满足实时性的条件下&#xff0c;不存在两者完全保存一致的方案&#xff0c;只有最终一致性方案。

FlinkX学习

FlinkX学习 FlinkX安装 由于flinkx已经改名chunjun 官网已不存在 (https://gitee.com/lugela/flinkx#flinkx)这里可以看到flinkx的操作文档 1、上传并解压 unzip flinkx-1.10.zip -d /usr/local/soft/2、配置环境变量 FLINKX_HOME/usr/local/soft/flinkx-1.10 export PATH$F…