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

Spring学习笔记注解式开发(3)

Spring学习笔记(3)

  • 一、Bean的注解式开发
    • 1.1、注解开发的基本和@Component
    • 1.2 注解式开发
    • 8.3、@Component的三个衍生注解
  • 二、Bean依赖注入注解开发
    • 2.1、依赖注入相关注解
    • 2.2、@Autowired扩展
  • 三、非自定义Bean注解开发
  • 四、Bean配置类的注解开发
  • 五、Spring注解的解析原理
  • 六、Spring注解式开发第三方框架

一、Bean的注解式开发

1.1、注解开发的基本和@Component

Spring除了xml配置文件进行配置之外,还可以使用注解方式进行配置,注解方式慢慢成为xml配置的替代方案。我们有了xml开发的经验,学习注解开发就方便了许多,注解开发更加快捷方便。

  • Spring提供的注解有三个版本:
    • 2.0时代,Spring开始出现注解
    • 2.5时代,Spring的Bean配置可以使用注解完成
    • 3.0时代,Spring其他配置也可以使用注解完成,我们进入全注解时代

基本Bean注解,主要是使用注解的方式替代原有xml的<bean>标签及其标签属性的配置

<bean id="" name="" class="" scope="" lazy-init="" init-method="" destroy-method=""abstract="" autowire="" factory-bean="" factory-method=""></bean>

使用@Component注解替代<bean>标签

xml配置注解描述
<bean id="" class="">@Component被该注解表示的类,会在指定扫描范围内被Spring加载并实例化
//<bean id="userDao" class="com.Smulll.Dao.Impl.UserDaoImpl"></bean>
@Component("userDao")
public class UserDaoImpl implements UserDao{@Overridepublic void show() {}
}
<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><!--注解组件扫描--><!--扫描指定的基本包及其子包下的类,识别使用@Component注解--><context:component-scan base-package="com.huanglei"/>
</beans> 
public class test1 {@Testpublic void ComponentTest(){ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("beans.xml");Object bean = classPathXmlApplicationContext.getBean("userDao");System.out.println(bean);}
} 

1.2 注解式开发

如果@Component不设置name属性,那会回自动将首字母小写的类名转化成name,在访问的时候就用其首字母小写的类名进行访问

  • 相关属性用注解开发替代的标签
xml配置注解描述
<bean scope="">@Scope在类上或使用了@Bean标注的方法上,标注Bean的作用范围,取值为singleton或prototype
<bean lazy-init="">@Lazy在类上或使用了@Bean标注的方法上,标注Bean是否延迟加载,取值为true和false
<bean init-method="">@PostConstruct在方法上使用,标注Bean的实例化后执行的方法
<bean destroy-method="">@PreDestroy在方法上使用,标注Bean的销毁前执行方法

8.3、@Component的三个衍生注解

由于JavaEE开发是分层的,为了每层Bean标识的注解语义化更加明确,可以乱写,但是为了让注解语义化明确,建议按照标准书写

  • @Component又衍生出如下三个注解:
@Component衍生注解描述
@Repository在Dao层类上使用
@Service在Service层类上使用
@Controller在Web层类上使用
//service层
@Service("userService")
public class UserServiceImpl implements UserService{}
//dao层
@Repository("userDao")
public class UserDaoImpl implements UserDao{}
//web层
@Controller("userService")
public class UserController{} 

二、Bean依赖注入注解开发

2.1、依赖注入相关注解

Bean依赖注入的注解,主要是使用注解的方式替代xml的标签完成属性的注入操作

<bean id=" "class=""><property name="" value=""/><property name="" ref=""/>
</bean> 
  • Spring主要提供如下注解,用于在Bean内部进行属性注入的:
属性注入注解描述
@Value使用在字段或方法上,用于注入普通数据
@Autowired使用在字段或方法上,用于根据类型(byType)注入引用数据
@Qualifier使用在字段或方法上,结合@Autowired,根据名称注入
@Resource使用在字段或方法上,根据类型或名称进行注入
  • @Value一般会引用Spring容器里面的一些值,根据key进行获取
  • @Autowired根据类型进行注入,如果同一类型的Bean有多个,尝试根据书写的名字进行二次匹配,如果匹配不成功则会报错
  • 配合使用@Qualifier注解,可以在同一类型的多个Bean中根据名称注入相应的Bean
  • @Resource不指定名称参数时,根据类型注入,指定名称则根据名称注入
@Service("userService")
public class UserServiceImpl implements UserService{@Value("zhangsan")private String username;//@Autowired,如果同一类型的Bean有多个,尝试根据名字进行二次匹配,如果匹配不成功则会报错//@Qualifier("userDao2"),配合使用@Autowired注解,可以在同一类型的多个Bean中根据名称注入相应的Bean@Resource private UserDao userDao;@Overridepublic void show() {System.out.println(username);System.out.println(userDao);}
} 

2.2、@Autowired扩展

@Autowired使用该注解时,所查看的是参数的类型,跟方法的名称无关

@Service("userService")
public class UserServiceImpl implements UserService{@Autowired public void xxx(UserDao userDao) {System.out.println("xxx:"+userDao);}
} 

该注解同样可以获取一个集合,可以将同一类型的多个Bean打印出来

@Service("userService")
public class UserServiceImpl implements UserService{@Autowired public void yyy(List<UserDao> userDaoList) {System.out.println("yyy:"+userDaoList);}
} 

三、非自定义Bean注解开发

非自定义Bean不能像自定义Bean一样使用@Component进行管理,非自定义Bean要通过工厂的方式进行实例化,使用@Bean标注方法即可,@Bean的属性为beanName,如不指定为当前工厂方法名称

//将方法返回值Bean实例以@Bean注解指定的名称存储到spring容器中
@Bean ("datasource")
public DataSource dataSource (){DruidDataSource dataSource = new DruidDataSource();dataSource.setDriverClassName("com.mysql.jdbc.Driver");dataSource.setUrl("jdbc:mysql://localhost:3306/itheima");dataSource.setUsername("root");dataSource.setPassword("123456");return dataSource;
}

@Bean标注后面不加name值,则将类名赋值为name属性值

  • 在参数中注入
@Component
public class otherBean {@Bean("dataSource")public DataSource dataSource(@Value("${jdbc.driver}") String driver@Qualifier("userDao") UserDao UserDao//不需要写@Autowired){DruidDataSource dataSource = new DruidDataSource();dataSource.setDriverClassName(driver);dataSource.setUrl("jdbc:mysql://localhost:3306/mybatis");dataSource.setUsername("root");dataSource.setPassword("123456");return dataSource;}
} 

四、Bean配置类的注解开发

@component --> <bean>
@Configuration --> 表示上面配置的文件
下面是其他的标签注解开发展示:

	<!--扫描Spring管理的包--><context:component-scan base-package="com.huanglei"/><!--加载properties文件---><context:properties-placeholder location="classpath:jdbc.properties"/><!--引入其他的xml文件--><import resource="classpath:beans.xml"/>

在用注解式开发的时候需要在配置类上加 @Configuration
作用:

  1. 表明这是一个配置类
  2. 使其就具备@Component的功能
xml配置注解描述
<context:component-scan base-package="com.huanglei"/>@ComponentScan组件扫描配置
<context:property-placeholder location="classpath:jdbc.properties"/>@PropertySource获取到properties文件里的信息
<import resource="classpath:beans.xml">@Import导入其他的xml配置文件

base-package的配置方法:

  • 可以配置一个或者多个包:扫描的为该包及其子包下使用注解的类
  • 不配置包名:扫描当前@componentScan注解配置类所在包及其子包下的类
@Component
@Configuration
@ComponentScan(backages={"com.huanglei","com.itheima"})
@PropertySource({"classpath:jdbc.properties"})
//<import resource=""/>
@Import(otherBean.class)
public class SpringConfig {}

其他的注解式开发:

@Primary 这个是来调节同类型Bean优先顺序的,就是说在利用ByTybe调用bean对象的时候有多个对象,如果没有@primary,那么就按照之前的调用规则进行调用,如果存在@Primary那么就有限调用这个Bean对象

@Repository("userDao")
public class UserDaoImpl implements UserDao{}
@Repository("userDao2")
@Primary
public class UserDaoImpl2 implements UserDao{} 
@Bean("dataSource")
public DataSource dataSource(){}@Bean("dataSource2")
@Primary //如果没添加这个,那么在调用的时候,就会按照名字调用上面那个Bean对象
public DataSource dataSource2(){} 

扩展:@Profile注解的作用同于xml配置时学习profile属性,是进行环境切换使用的

<beans profile="test">

注解@Profile标注在类或方法上,标注当前产生的Bean从属于哪个环境,只有激活了当前环境,被标注的Bean才能被注册到Spring容器里,不指定环境的Bean,任何环境下都能注册到Spring容器里

@Repository("userDao")
@Profile("test") //表面实在test环境下面
public class UserDaoImpl implements UserDao{}
@Repository("userDao2")
public class UserDaoImpl2 implements UserDao{} 
  • 可以使用以下两种方式指定被激活的环境:
    • 使用命令行动态参数,虚拟机参数位置加载 -Dspring.profiles.active=test
    • 使用代码的方式设置环境白能量System.setProperty("profiles.active","test");
@Test
public void test2(){System.setProperty("spring.profiles.active","test");AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);Object userDao = annotationConfigApplicationContext.getBean("userDao");System.out.println(userDao);
} 

五、Spring注解的解析原理

在这里插入图片描述
结论:只要将Bean对应的BeanDefinition注册到beanDefinitionMap中,就可以经历整个SpringBean的生命周期,最终实例化进入单例池中

使用@Component等注解配置完毕后,要配置组件扫描才能使注解生效

六、Spring注解式开发第三方框架

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property><property name="url" value="jdbc:mysql://localhost:3306/mybatis2"></property><property name="username" value="root"></property><property name="password" value="123456"></property>
</bean>
<!--配置SqlSessionFactoryBean,作用将SqlSessionFactory存储到spring容器-->
<bean class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource"></property>
</bean>
<!--MapperScannerConfigurer,作用扫描指定的包,产生Mapper对象存储到Spring容器-->
<bean  class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="com.Smulll.mapper"></property>
</bean> 

使用注解方式:
注解方式,Spring整合MyBatis的原理,关键在于**@MapperScan**,@MapperScan不是Spring提供的注解,是MyBatis为了整合Spring,在整合包org.mybatis.spring.annotation中提供的注解,源码如下:

package com.huanglei.listener;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.w3c.dom.css.CSSPrimitiveValue;import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;public class ContextLoaderListener implements ServletContextListener {private String CONTEXT_LOCATION = "configLocation";@Overridepublic void contextInitialized(ServletContextEvent sec) {//获取到全局变量configLocationServletContext servletContext = sec.getServletContext();String contextLocation = servletContext.getInitParameter(CONTEXT_LOCATION);contextLocation = contextLocation.substring("classpath:".length());//首先创建Spring容器ApplicationContext applicationContext = new ClassPathXmlApplicationContext(contextLocation);//将Spring容器放到ServletContext域当中servletContext.setAttribute("applicationContext",applicationContext);}@Overridepublic void contextDestroyed(ServletContextEvent servletContextEvent) {}
} 

重点关注一下@lmport({MapperScannerRegistrar.class),当@MapperScan被扫描加载时,会解析@Import注解,从而加载指定的类,此处就是加载了MapperScannerRegistrar

相关文章:

Spring学习笔记注解式开发(3)

Spring学习笔记&#xff08;3&#xff09; 一、Bean的注解式开发1.1、注解开发的基本和Component1.2 注解式开发8.3、Component的三个衍生注解 二、Bean依赖注入注解开发2.1、依赖注入相关注解2.2、Autowired扩展 三、非自定义Bean注解开发四、Bean配置类的注解开发五、Spring注…...

vue3后台管理框架之技术栈

vue3全家桶技术 基础构建&#xff1a; vue3vite4TypeScript 代码格式 &#xff1a; eslintprettystylelint git生命周期钩子&#xff1a; husky css预处理器&#xff1a; sass ui库&#xff1a; element-plus 模拟数据: mock 网络请求&#xff1a; axios 路由&#xff1a; vue…...

7、Linux驱动开发:设备-自动创建设备节点

目录 &#x1f345;点击这里查看所有博文 随着自己工作的进行&#xff0c;接触到的技术栈也越来越多。给我一个很直观的感受就是&#xff0c;某一项技术/经验在刚开始接触的时候都记得很清楚。往往过了几个月都会忘记的差不多了&#xff0c;只有经常会用到的东西才有可能真正记…...

用Python解析HTML页面

用Python解析HTML页面 文章目录 用Python解析HTML页面HTML 页面的结构XPath 解析CSS 选择器解析简单的总结 在前面的课程中&#xff0c;我们讲到了使用 request三方库获取网络资源&#xff0c;还介绍了一些前端的基础知识。接下来&#xff0c;我们继续探索如何解析 HTML 代码&…...

官方认证:研发效能(DevOps)工程师职业技术认证

培养端到端的研发效能人才 为贯彻落实《关于深化人才发展体制机制改革的意见》&#xff0c;推动实施人才强国战略&#xff0c;促进专业技术人员提升职业素养、补充新知识新技能&#xff0c;实现人力资源深度开发&#xff0c;推动经济社会全面发展&#xff0c;根据《中华人民共…...

搭建GPFS双机集群

1.环境说明&#xff1a; 系统主机名IP地址内存添加共享磁盘大小Centos7.9gpfs1192.168.10.1012G20GCentos7.9gpfs2192.168.10.1022G20G 2.环境配置&#xff1a; 配置网路IP地址&#xff1a; 修改网卡会话&#xff1a; nmcli connection modify ipv4.method manual ipv4.addre…...

【试题032】C语言关系运算符例题

1.题目&#xff1a;设int a2,b4,c5;&#xff0c;则表达式ab!c>b>a的值为&#xff1f; 2.代码分析&#xff1a; //设int a2,b4,c5;&#xff0c;则表达式ab!c>b>a的值为?int a 2, b 4, c 5;printf("%d\n", (a b ! c > b > a));//分析&#xff…...

系列四、FileReader和FileWriter

一、概述 FileReader 和 FileWriter 是字符流&#xff0c;按照字符来操作IO。 1.1、继承体系 二、FileReader常用方法 new FileReader(File/String)# 每次读取单个字符就返回&#xff0c;如果读取到文件末尾返回-1 read()# 批量读取多个字符到数组&#xff0c;返回读取的字节…...

【C++面向对象】2.构造函数、析构函数

文章目录 【 1. 构造函数 】1.1 带参构造函数--传入数据1.2 无参构造函数--不传入数据1.3 实例1.4 拷贝构造函数 【 2. 析构函数 】 【 1. 构造函数 】 类的构造函数是类的一种特殊的成员函数&#xff0c;它会 在每次创建类的新对象时执行。 构造函数的名称与类的名称是完全相同…...

uniapp:使用subNVue原生子窗体在map上层添加自定义组件

我们想要在地图上层添加自定义组件&#xff0c;比如一个数据提示框&#xff0c;点一下会展开&#xff0c;再点一下收起&#xff0c;在h5段显示正常&#xff0c;但是到app端真机测试发现组件显示不出来&#xff0c;这是因为map是内置原生组件&#xff0c;层级最高&#xff0c;自…...

Flutter开发GridView控件详解

GridView跟ListView很类似&#xff0c;Listview主要以列表形式显示数据&#xff0c;GridView则是以网格形式显示数据&#xff0c;掌握ListView使用方法后&#xff0c;会很轻松的掌握GridView的使用方法。 在某种界面设计中&#xff0c;如果需要很多个类似的控件整齐的排列&…...

Vue3.0里为什么要用 Proxy API 替代 defineProperty API ?

一、Object.defineProperty 定义&#xff1a;Object.defineProperty() 方法会直接在一个对象上定义一个新属性&#xff0c;或者修改一个对象的现有属性&#xff0c;并返回此对象 为什么能实现响应式 通过defineProperty 两个属性&#xff0c;get及set get 属性的 getter 函…...

pytest利用request fixture实现个性化测试需求详解

这篇文章主要为大家详细介绍了pytest如何利用request fixture实现个性化测试需求,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起了解一下− 前言 在深入理解 pytest-repeat 插件的工作原理这篇文章中&#xff0c;我们看到pytest_repeat源码中有这样一段 import pyt…...

算法练习16——O(1) 时间插入、删除和获取随机元素

LeetCode 380 O(1) 时间插入、删除和获取随机元素 实现RandomizedSet 类&#xff1a; RandomizedSet() 初始化 RandomizedSet 对象 bool insert(int val) 当元素 val 不存在时&#xff0c;向集合中插入该项&#xff0c;并返回 true &#xff1b;否则&#xff0c;返回 false 。 …...

实时数据更新与Apollo:探索GraphQL订阅

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 「推荐专栏」&#xff1a; ★java一站式服务 ★ ★ React从入门到精通★ ★前端炫酷代码分享 ★ ★ 从0到英雄&#xff0c;vue成神之路★ ★ uniapp-从构建到提升★ ★ 从0到英雄&#xff…...

VMware Workstation里面安装ubuntu20.04的流程

文章目录 前言一、获取 desktop ubuntu20.04 安装镜像二、VMware Workstation下安装ubuntu20.041. VMware Workstation 创建一个新的虚拟机2. ubuntu20.04的安装过程3. 登录ubuntu20.044. 移除 ubuntu20.04 安装镜像总结参考资料前言 本文主要介绍如何在PC上的虚拟机(VMware W…...

pnpm的环境安装以及安装成功后无法使用的问题

文章目录 前言1、使用npm 安装2、安装后的注意点3、遇到问题4、配置path的环境变量&#xff08;1&#xff09;找到环境变量&#xff08;2&#xff09;找到并双击path的系统变量&#xff08;3&#xff09;复制第1步中使用npm安装的红框部分的路径&#xff08;4&#xff09;将第&…...

华为eNSP配置专题-浮动路由及BFD的配置

文章目录 华为eNSP配置专题-浮动路由及BFD的配置0、参考文档1、前置环境1.1、宿主机1.2、eNSP模拟器 2、基本环境搭建2.1、基本终端构成和连接2.2、基本终端配置 3、浮动路由配置3.1、浮动路由的基本配置3.2、浮动路由的负载均衡问题3.3、浮动路由的优先级调整 4、BFD的配置4.1…...

光储并网直流微电网simulink仿真模型,光伏采用mppt实现最大功率输出研究

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

面试题-React(十六):理解Redux及其工作原理

在现代前端开发中&#xff0c;状态管理是一个关键的问题。Redux是一个广泛使用的状态管理库&#xff0c;可以帮助开发者更有效地管理应用的状态。 一、什么是Redux&#xff1f; Redux是一个JavaScript状态管理库&#xff0c;用于管理应用中的状态&#xff08;state&#xff0…...

PHP和Node.js哪个更爽?

先说结论&#xff0c;rust完胜。 php&#xff1a;laravel&#xff0c;swoole&#xff0c;webman&#xff0c;最开始在苏宁的时候写了几年php&#xff0c;当时觉得php真的是世界上最好的语言&#xff0c;因为当初活在舒适圈里&#xff0c;不愿意跳出来&#xff0c;就好比当初活在…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

电脑插入多块移动硬盘后经常出现卡顿和蓝屏

当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时&#xff0c;可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案&#xff1a; 1. 检查电源供电问题 问题原因&#xff1a;多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

多种风格导航菜单 HTML 实现(附源码)

下面我将为您展示 6 种不同风格的导航菜单实现&#xff0c;每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元&#xff08;GRU&#xff09;长短期记忆神经网络&#xff08;LSTM&#xff09…...

基于IDIG-GAN的小样本电机轴承故障诊断

目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) ​梯度归一化(Gradient Normalization)​​ (2) ​判别器梯度间隙正则化(Discriminator Gradient Gap Regularization)​​ (3) ​自注意力机制(Self-Attention)​​ 3. 完整损失函数 二…...

Android写一个捕获全局异常的工具类

项目开发和实际运行过程中难免会遇到异常发生&#xff0c;系统提供了一个可以捕获全局异常的工具Uncaughtexceptionhandler&#xff0c;它是Thread的子类&#xff08;就是package java.lang;里线程的Thread&#xff09;。本文将利用它将设备信息、报错信息以及错误的发生时间都…...

flow_controllers

关键点&#xff1a; 流控制器类型&#xff1a; 同步&#xff08;Sync&#xff09;&#xff1a;发布操作会阻塞&#xff0c;直到数据被确认发送。异步&#xff08;Async&#xff09;&#xff1a;发布操作非阻塞&#xff0c;数据发送由后台线程处理。纯同步&#xff08;PureSync…...

Tauri2学习笔记

教程地址&#xff1a;https://www.bilibili.com/video/BV1Ca411N7mF?spm_id_from333.788.player.switch&vd_source707ec8983cc32e6e065d5496a7f79ee6 官方指引&#xff1a;https://tauri.app/zh-cn/start/ 目前Tauri2的教程视频不多&#xff0c;我按照Tauri1的教程来学习&…...

Linux操作系统共享Windows操作系统的文件

目录 一、共享文件 二、挂载 一、共享文件 点击虚拟机选项-设置 点击选项&#xff0c;设置文件夹共享为总是启用&#xff0c;点击添加&#xff0c;可添加需要共享的文件夹 查询是否共享成功 ls /mnt/hgfs 如果显示Download&#xff08;这是我共享的文件夹&#xff09;&…...