Spring--基于注解管理bean

news/2024/5/14 22:46:38/文章来源:https://blog.csdn.net/weixin_43903745/article/details/127824909

基于注解管理bean

实验一:标记与扫描

  1. 注解
    和 XML 配置文件一样,注解本身并不能执行,注解本身仅仅只是做一个标记,具体的功能是框架检测到注解标记
    的位置,然后针对这个位置按照注解标记的功能来执行具体操作。
    本质上:所有一切的操作都是Java代码来完成的,XML和注解只是告诉框架中的Java代码如何执行。

举例:元旦联欢会要布置教室,蓝色的地方贴上元旦快乐四个字,红色的地方贴上拉花,黄色的地方贴上气球。
在这里插入图片描述
班长做了所有标记,同学们来完成具体工作。墙上的标记相当于我们在代码中使用的注解,后面同学们做的工作,相当于框架的具体操作。

  1. 扫描
    Spring 为了知道程序员在哪些地方标记了什么注解,就需要通过扫描的方式,来进行检测。然后根据注解进行后
    续操作。

  2. 新建Maven Module
    在这里插入图片描述

  3. 创建Spring配置文件

  4. 标识组件常用的注解
    @Component:将类标识为普通组件
    @Controller:将类标识为控制层组件
    @Service:将类标识为业务层组件
    @Repository:将类标识为持久层组件

区别:
通过查看源码我们得知,@Controller、@Service、@Repository这三个注解只是在@Component注解的基础上起了三个新的名字。
对于Spring使用IOC容器管理这些组件来说没有区别。所以@Controller、@service、@Repository这三个注解只是给开发人员看的,让我们能够便于分辦组件的作用。

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

  1. 创建组件
@Controller
public class UserController {
}
@Repository
public class UserDaoImpl implements UserDao {
}
@Service
public class UserServiceImpl implements UserService {
}
  1. 扫描组件
<?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"><!--    扫描组件--><!--context:exclude-filter:排除扫描type:设置排除扫描的方式type="annotation|assignable"annotation:根据注解的类型进行排除,expression中需要设置排除的注解的全类名assignable:根据类的类型进行排除,expression中需要设置排除的类的全类名context:include-filter:包含扫描注意:需要在context:component-scan标签中设置use-default-filters = "false"use-default-filters = "true",默认,所设置的包下的所有类都扫描,此时可以使用排除扫描use-default-filters = "false",所设置的包下的所有类都不扫描,此时可以使用包含扫描--><context:component-scan base-package="com.bijing.spring" use-default-filters="true"><!--        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>--><!--        <context:exclude-filter type="assignable" expression="org.springframework.stereotype.Controller"/>--><!--        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>--></context:component-scan>
</beans>
  1. 测试
    @Testpublic void testIOCByAnnotation() {ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc-annotation.xml");UserController userController = ioc.getBean(UserController.class);System.out.println(userController);UserService userService = ioc.getBean(UserService.class);System.out.println(userService);UserDao userDao = ioc.getBean(UserDao.class);System.out.println(userDao);}
  1. 组件所对应的bean的id
    通过注解+扫描所配置的bean的id,默认值为类的小驼峰,即类名首字母为小写
    可以在注解后面配置id
@Controller("controller")
public class UserController {
}
public class IOCByAnnotationTest {/*** @Component:将类标识为普通组件* @Controller:将类标识为控制层组件* @Service:将类标识为业务层组件* @Repository:将类标识为持久层组件 @* 通过注解+扫描所配置的bean的id,默认值为类的小驼峰,即类名首字母为小写*/@Testpublic void testIOCByAnnotation() {ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc-annotation.xml");UserController userController = ioc.getBean("controller", UserController.class);System.out.println(userController);UserService userService = ioc.getBean(UserService.class);System.out.println(userService);UserDao userDao = ioc.getBean(UserDao.class);System.out.println(userDao);}
}

实验二:基于注解的自动装配

  1. 场景模拟
    在这里插入图片描述

  2. @Autowired注解

这个注解的功能就是为我们注入一个定义好的 bean

@Controller()
public class UserController {@Autowired
//    @Qualifier("userServiceImpl")private UserService userService;public void saveUser() {userService.saveUser();}
}
@Repository()
public class UserDaoImpl implements UserDao {@Override()public void saveUser() {System.out.println("保存成功");}
}
@Service
public class UserServiceImpl implements UserService {@Autowired// @Qualifier("userDaoImpl")private UserDao userDao;public UserServiceImpl(UserDao userDao) {this.userDao = userDao;}public UserDao getUserDao() {return userDao;}public void setUserDao(UserDao userDao) {this.userDao = userDao;}@Overridepublic void saveUser() {userDao.saveUser();}
}
  1. @Autowired注解其他细节
  • @Autowired注解能够标识的位置
    • 标识在成员变量上,此时不需要设置成员变量的set方法
    • 标识在set方法上
    • 为当前成员变量赋值的有参构造器上
  • @Autowired注解的原理
    • 默认通过byType的方式,在IOC容器中通过类型匹配某个bean为属性赋值
    • 若有多个类型匹配的bean,此时会自动转换为byName的方式实现自动装配的效果, 即将要赋值的属性的属性名作为bean的id匹配某个bean的属性值
    • 若byType和byName的方式都无法实现自动装配,即IOC容器中有多个类型匹配的bean,且这些bean的id和要赋值的属性的属性名都不一致
    • 此时可以在要赋值的属性上添加一个@Qualifier注解,通过该注解的value属性值指定某个bean的id,用这个bean给属性赋值
  • @Qualifier注解
@Controller()
public class UserController {@Autowired@Qualifier("userServiceImpl")private UserService userService;public void saveUser() {userService.saveUser();}
}
@Service
public class UserServiceImpl implements UserService {@Autowired@Qualifier("userDaoImpl")private UserDao userDao;public UserServiceImpl(UserDao userDao) {this.userDao = userDao;}public UserDao getUserDao() {return userDao;}public void setUserDao(UserDao userDao) {this.userDao = userDao;}@Overridepublic void saveUser() {userDao.saveUser();}
}
    <context:component-scan base-package="com.bijing.spring"><!--        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>--><!--        <context:exclude-filter type="assignable" expression="org.springframework.stereotype.Controller"/>--><!--        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>--></context:component-scan><!--经过上面的扫描后IOC中已经有了相应的bean了,此时再添加bean,@Autowired就会根据name装配--><!--    没有@Qualifier注解时,本应该根据name找userService,找不到,但是userService上@Qualifier("userServiceImpl")指定了userServiceImpl,所以找到了--><bean id="userServiceImpl" class="com.bijing.spring.service.impl.UserServiceImpl"></bean><bean id="userDaoImpl" class="com.bijing.spring.dao.impl.UserDaoImpl"></bean>
  • 注意:若IOC容器中没有任何一个类型匹配的bean,此时抛出异常:NoSuchBeanDefinitionException
    • 在@Autowired注解中有个属性required,默认值为true,要求必须完成自动装配
    • 可以将required设置为false,此时能装配就装配,无法装配则使用属性默认值
  1. @Autowired工作流程
package com.bijing.spring.test;import com.bijing.spring.controller.UserController;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;/*** @author 毕晶* @date 2022/11/12 20:45*/
public class IOCByAnnotationTest {/*** @Component:将类标识为普通组件* @Controller:将类标识为控制层组件* @Service:将类标识为业务层组件* @Repository:将类标识为持久层组件 #* 通过注解+扫描所配置的bean的id,默认值为类的小驼峰,即类名首字母为小写* 可以通过标识组件的注解的value属性值设置bean的自定义id* @Autowired: 实现自动装配功能的注解 #* 1.@Autowired注解能够标识的位置* a>标识在成员变量上,此时不需要设置成员变量的set方法* b>标识在set方法上* c>为当前成员变量赋值的有参构造器上* 2.@Autowired注解的原理* a>默认通过byType的方式,在IOC容器中通过类型匹配某个bean为属性赋值* b>若有多个类型匹配的bean,此时会自动转换为byName的方式实现自动装配的效果* 即将要赋值的属性的属性名作为bean的id匹配某个bean的属性值* c>若byType和byName的方式都无法实现自动装配,即IOC容器中有多个类型匹配的bean,且这些bean的id和要赋值的属性的属性名都不一致* d>此时可以在要赋值的属性上添加一个@Qualifier注解,通过该注解的value属性值指定某个bean的id,用这个bean给属性赋值* ##* 注意:若IOC容器中没有任何一个类型匹配的bean,此时抛出异常:NoSuchBeanDefinitionException* 在@Autowired注解中有个属性required,默认值为true,要求必须完成自动装配* 可以将required设置为false,此时能装配就装配,无法装配则使用属性默认值*/@Testpublic void testIOCByAnnotation() {ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc-annotation.xml");UserController userController = ioc.getBean(UserController.class);System.out.println(userController);userController.saveUser();
//        UserService userService = ioc.getBean(UserService.class);
//        System.out.println(userService);
//        UserDao userDao = ioc.getBean(UserDao.class);
//        System.out.println(userDao);}
}

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

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

相关文章

【ASM】字节码操作 工具类与常用类 asm-utils 与 asm-commons

1.概述 本章节主要是对 ASM中的 工具类与常用类 ,包asm-utils 与 asm-commons 两个包中的一些类进行讲解的介绍。 2. asm-util 在asm-util.jar当中,主要介绍CheckClassAdapter和TraceClassVisitor类。在TraceClassVisitor类当中,会涉及到Printer、ASMifier 和Textifier类。…

Vue中 引入使用 element-resize-detector 监听 Dom 元素 宽度、高度 变化

1. 前言 很多做pc端平台的小伙伴都遇到过这样一个问题&#xff1a;在做侧边栏菜单时会有一个收缩和展开的一个功能&#xff0c;在伸缩的过程中右边的页面的宽度就会随之改变。我上网查了查 &#xff0c;也动手试了试 window.onresize ()>{}。却不尽人意&#xff0c;因为它…

进程管理命令 动态监控进程 rpm yum

学习视频:074_韩顺平Linux_服务管理(2)_哔哩哔哩_bilibili 目录 进程管理命令基本介绍 PS命令 显示系统执行的进程 终止进程kill和killall 查看进程树pstree 服务管理 服务管理 打开或者关闭指定端口 动态监控进程 监控网络状态 …

数字IC手撕代码-XX公司笔试真题(脉冲密度调制)

前言&#xff1a; 本专栏旨在记录高频笔面试手撕代码题&#xff0c;以备数字前端秋招&#xff0c;本专栏所有文章提供原理分析、代码及波形&#xff0c;所有代码均经过本人验证。 目录如下&#xff1a; 1.数字IC手撕代码-分频器&#xff08;任意偶数分频&#xff09; 2.数字I…

nginx之https加密网站

目录 一、密钥算法 二、SSL虚拟主机 一、密钥算法 常见密钥算法&#xff1a; 对称加密&#xff1a;AES、DES 非对称加密&#xff1a;RSA、DSA 【注】对称加密的加密和解密使用的是同一把钥匙&#xff0c;非对称加密的加密和解密使用的不是一把钥匙&#xff0c;在对网…

0093 二分查找算法,分治算法

/* * 二分查找算法 * 前提&#xff1a;数组必须有序 * 1.确定该数组的中间值下标 mid(leftright)/2 * 2.让需要查找的数target和arr[mid]比较 * * 非递归算法 * 递归算法 */ public class BinarySearch_ { public static void main(String[] args) { int[…

【Python】常量和变量类型

目录 1.常量和表达式 2. 变量和类型 2.1 变量是什么 2.2 变量的语法 2.3 变量的类型 2.4 动态类型特性 1.常量和表达式 我们可以把Python当成一个计算器&#xff0c;来进行一些算式运算&#xff0c;如 print(1 2 - 1) print(1 2 * 2) print(1 2 / 2) 注&#xff1a;在…

pta-sql补题(2)

目录​​​​​​​ 插入insert&#xff1a; 两种语法形式&#xff1a; 插入记录&#xff08;一&#xff09; 表结构: 表样例 输出 插入记录&#xff08;二&#xff09; 表结构: 表样例 结果判定: 更新update 语法 更新记录&#xff08;一&#xff09; 表结构: …

Python——正则表达式的应用

文章目录前言正则表达式方法re.search方法group方法re.match方法re.findall方法re.finditer方法re.split方法re.sub方法正则表达式的应用前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 正则表达式是字符串处理的有力工具和技术。 使用正在表达式的目的…

Hackthebox系列 Starting point Tier0 Meow记录

免责声明&#xff1a;本教程仅限学术讨论使用&#xff0c;请勿作用于非法用途&#xff01;&#xff01;&#xff01;如有用于非法用途&#xff0c;本人概不负责。 目录题目来源题目TASK 1TASK 2TASK 3TASK 4TASK 5TASK 6NMAP端口扫描TASK 7Telnet访问TASK 8TASK 9参考题目来源 …

【RPC框架、RPC框架必会的基本知识、手写一个RPC框架案例、优秀的RPC框架Dubbo、Dubbo和SpringCloud框架比较】

一.RPC框架必会的基本知识 1.1 什么是RPC&#xff1f; RPC&#xff08;Remote Procedure Call ——远程过程调用&#xff09;&#xff0c;它是一种通过网络从远程计算机程序上请求服务&#xff0c;而不需要了解底层网络的技术。 一次完整的RPC同步调用流程&#xff1a; 服务…

rust编程语言(chapter 1)

目录 1. rust安装 2. Hello Rust 3. Cargo包管理器 3.1 cargo简介 3.2 cargo创建项目 3.3 构建和运行项目 3.4 debug和release版本构建 1. rust安装 rust提供了一个命令行的工具rustup&#xff0c;可以用来管理和安装rust的版本以及相关的工具集。 那么首先&#xff0c…

python游戏库pygame经典教程

目录 一.Pygame程序基本搭建过程 1.初始化化程序 2.创建Surface对象 3.事件监听 4.游戏循环 二.Pygame Display显示模块详解 1.将Surface对象粘贴至主窗口上 2.设置窗口主窗口 3.填充主窗口背景&#xff0c;参数值RGB 4.设置窗口标题 5.更新屏幕内容 6.pygame.display其他方…

java家政服务中心网站mysql

目 录 第一章 绪论 5 1.1 课题开发背景 5 1.2 课题研究意义 5 1.3 本课题主要工作 5 第二章 相关技术介绍 6 2.1 JSP技术 6 2.2 MyEclipse 6 2.3 MySQL数据库 7 2.4 J2EE 技术 8 2.5 B/S架构 9 第三章 系统分析 12 3.1 系统可行性分…

Python 考试练习题 2

一、选择题 1、下列是 python 合法标识符的是&#xff08; B&#xff09;。 A. 2variable B. variable2 C. $anothervar D. if 2、在 python 中字符串的表示方式是&#xff08;D &#xff09;。 A.采用单引号包裹 B.采用双引号包裹 C.采用三重单引号包裹 D.ABC 都是 3、设有…

nginx调度器

目录 源码安装nginx rpm安装nginx 调度器配置 节点服务器配置 源码包下载&#xff1a;http://nginx.org/en/download.html &#xff08;mainline:开发版 stable&#xff1a;稳定版&#xff09; rpm包的yum源&#xff1a;http://nginx.org/packages/centos/7/x86_64/ 本次通…

爬取医药卫生知识服务系统的药品数据——超详细流程

爬取医药卫生知识服务系统的药品数据——超详细流程 文章目录爬取医药卫生知识服务系统的药品数据——超详细流程前言一、寻找药品数据二、爬取药品ID1.资源获取2.数据提取3.资源保存4.主函数5.总体代码三、爬取药品信息1.加载资源ID2.获取数据3.数据提取4.保存信息5.主函数6.总…

Python统治编程界?Java第一个不服

要问现在什么程序设计语言最火&#xff1f;当然是——Python。 近日&#xff0c;TIOBE公布了2022年11月的编程语言排行榜&#xff0c;Python稳居第1名&#xff01;在Python之后&#xff0c;排第2名的是C语言&#xff0c;第3名是Java。但要说Python统治了编程界&#xff0c;Jav…

IDE安装后配置项--类/方法注释

匹配大小写 设置字体大小 设置注释模板 mapper模板 <?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <m…

java毕业设计教学平台(附源码、数据库)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; Springboot mybatis Maven Vue 等等组成&#xff0c;B/…