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.rhkb.cn/news/366035.html

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

相关文章

Linux开发讲课29---Linux USB 设备驱动模型

Linux 内核源码&#xff1a;include\linux\usb.h Linux 内核源码&#xff1a;drivers\hid\usbhid\usbmouse.c 1. BUS/DEV/DRV 模型 "USB 接口"是逻辑上的 USB 设备&#xff0c;编写的 usb_driver 驱动程序&#xff0c;支持的是"USB 接口"&#xff1a; US…

Linux:系统安全及应用

目录 一、系统账号管理 1.1、系统账号清理 1.2、密码安全控制 1.3、命令历史限制 二、限制su命令用户 三、PAM安全认证 四、sudo机制提升权限 4.1、sudo机制介绍 4.2、用户别名案例 4.3、启用sudo操作日志 4.4、其他案列sudo 4.5、开关机安全控制 4.6、限制更改GR…

无线物联网练习题

文章目录 选择填空简答大题 选择 不属于物联网感知技术的是(A) A:ZigBee B:红外传感器 C:FRID D:传感器 ZigBee是一种无线通信技术&#xff0c;虽然它常用于物联网中作为设备之间的通信手段&#xff0c;但它本身并不是一种感知技术 关于物联网于与互联网的区别的描述&#xff…

昇思第6天

函数式自动微分 神经网络的训练主要使用反向传播算法&#xff0c;模型预测值&#xff08;logits&#xff09;与正确标签&#xff08;label&#xff09;送入损失函数&#xff08;loss function&#xff09;获得loss&#xff0c;然后进行反向传播计算&#xff0c;求得梯度&#…

一站式uniapp优质源码项目模版交易平台的崛起与影响

一、引言 随着信息技术的飞速发展&#xff0c;软件源码已成为推动行业进步的重要力量。源码的获取、交易和流通&#xff0c;对于开发者、企业以及项目团队而言&#xff0c;具有极其重要的意义。为满足市场对高质量源码资源的迫切需求&#xff0c;一站式uniapp优质源码项目模版…

501、二叉搜索树中的众数

给你一个含重复值的二叉搜索树&#xff08;BST&#xff09;的根节点 root &#xff0c;找出并返回 BST 中的所有 众数&#xff08;即&#xff0c;出现频率最高的元素&#xff09;。如果树中有不止一个众数&#xff0c;可以按 任意顺序 返回。 假定 BST 满足如下定义&#xff1…

Java的Object类

概述:所有类的根类(父类),所有的类都会直接或者间接继承Object类 Object中的toString()方法&#xff1a; 如果不重写这个toString方法&#xff1a;默认形式是&#xff1a; return getClass().getName() "" Integer.toHexString(hashCode()); 这个我们可以进到Obj…

鸿蒙开发岗位就业前景分析

在信息技术飞速发展的今天&#xff0c;操作系统作为计算机的灵魂&#xff0c;一直是技术创新和市场竞争的焦点。随着华为鸿蒙操作系统的推出&#xff0c;鸿蒙开发岗位逐渐成为IT行业的热门话题。本文将深入探讨鸿蒙开发岗位的就业前景&#xff0c;揭示这一领域的就业新趋势&…

MSVCR120.DLL丢失的多种修复方法,助你快速解决dll问题

在日常生活和工作中&#xff0c;电脑已经成为我们不可或缺的工具。然而&#xff0c;在使用电脑的过程中&#xff0c;我们常常会遇到一些问题&#xff0c;其中之一就是电脑运行软件时提示找不到msvcr120.dll。如果该文件缺失或损坏&#xff0c;可能会导致依赖它的应用程序无法启…

在WSL Ubuntu中启用root用户的SSH服务

在 Ubuntu 中&#xff0c;默认情况下 root 用户是禁用 SSH 登录的&#xff0c;这是为了增加系统安全性。 一、修改配置 找到 PermitRootLogin 行&#xff1a;在文件中找到 PermitRootLogin 配置项。默认情况下&#xff0c;它通常被设置为 PermitRootLogin prohibit-password 或…

代码随想录算法训练营第55天(py)| 单调栈 | 42. 接雨水*、84.柱状图中最大的矩形

42. 接雨水* 力扣链接 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 思路1 暴力 按列来计算。每一列雨水的高度&#xff0c;取决于&#xff0c;该列 左侧最高的柱子和右侧最高的柱子中&#xff0c;…

Study--Oracle-05-Oracler体系结构

一、oracle 体系概览 Oracle数据库的体系结构通常包括以下主要组件&#xff1a; 1、实例&#xff08;Instance&#xff09;&#xff1a;运行数据库的软件环境&#xff0c;包括内存结构&#xff08;SGA&#xff09;和进程结构&#xff08;Background Processes and User Proces…

【电路笔记】-A类放大器

A类放大器 文章目录 A类放大器1、A类放大器概述2、A类放大器基本通用发射极配置3、变压器耦合配置4、总结在 放大器类型简介的文章中,我们介绍了不同类别的放大器。 在本文中,我们将更详细地介绍A类放大器。 在介绍不同的A类放大器配置前,首先的是要记住放大器类别的选择标…

从新手到高手:Scala函数式编程完全指南,Scala 数据类型(4)

1、Scala 数据类型 Scala 与 Java有着相同的数据类型&#xff0c;下表列出了 Scala 支持的数据类型&#xff1a;

【程序大侠传】异步架构应用回调数据接收接口偶发NPE

前序 在这片浩瀚的代码江湖中&#xff0c;各大门派林立&#xff0c;各自修炼独门绝技&#xff0c;江湖中的侠士们分别担任着开发、测试、产品和运维的角色&#xff0c;共同守护着这片数字化的疆域。 开发门派&#xff1a;代码剑宗 代码剑宗的弟子们精通各种编程语言&#xff…

【性能优化】Android冷启动优化

文章目录 常见现象APP的启动流程计算启动时间Displayed Timeadb dump 启动优化具体策略总结参考链接 常见现象 各种第三方工具初始化和大量业务逻辑初始化&#xff0c;影响启动时间&#xff0c;导致应用启动延迟、卡顿等现象 APP的启动流程 加载和启动应用程序&#xff1b; …

PTFE铲子聚四氟乙烯物料特氟龙铲粉料铲耐酸碱塑料药铲

四氟铲子主要适用于药厂、药企、医药行业专用&#xff0c;用于粉末状及颗粒物状样品的铲取和搅匀等。因为粉料物料对铲子材质要求无污染、本底值低&#xff0c;所以四氟材质成为选择。 其主要特点有&#xff1a; 1.外观纯白色。 2.耐高低温性&#xff1a;可使用温度-200℃&am…

docker 部署jitsi meet

1. 部署环境&#xff1a; 1.1 vm 虚拟机 安装的 centos 7 1.2 centos7安装docker 和 docker-compose 2.docker命令 官网部署文档地址&#xff1a;&#xff08;文档地址有可能失效&#xff09; Self-Hosting Guide - Docker | Jitsi Meet 2.1Download and extract the late…

基于yolo的物体识别坐标转换

一、模型简介: 1.1、小孔成像模型简图如下:不考虑实际相机中存在的场曲、畸变等问题 相对关系为: 为了表述与研究的方便,我们将像面至于小孔之前,且到小孔的距离仍然是焦距f,这样的模型与原来的小孔模型是等价的 相对关系为: 二、坐标系简介: **世界坐标系(world coo…

旋转变压器软件解码simulink仿真

1.介绍 旋转变压器是一种精密的位置、速度检测装置&#xff0c;尤其适用于高温、严寒、潮湿、高速、振动等环境恶劣、旋转编码器无法正常工作的场合。旋转变压器在使用时并不能直接提供角度或位置信息&#xff0c;需要特殊的激励信号和解调、计算措施&#xff0c;才能将旋转变压…