spring框架学习记录(2)

news/2024/5/18 23:59:42

文章目录

    • 注解开发
      • bean相关
        • 注解开发定义bean
        • 纯注解开发
        • 纯注解开发中bean的管理
      • 依赖注入相关
        • 依赖注入
        • 第三方bean管理
        • 第三方bean依赖注入
    • AOP(Aspect Oriented Programming)面向切面编程
      • AOP简介
      • AOP核心概念
      • AOP工作流程
      • AOP切入点表达式
      • 通知类型
      • AOP通知获取数据

注解开发

bean相关

注解开发定义bean
  • 使用@Component定义bean
@Component("bookDao")
public class BookDaoImpl implements BookDao {
}
@Component
public class BookServiceImpl implements BookService {
}
  • 核心配置文件中通过组件扫描加载bean
<context:component-scan base-package="com.itheima"/>
  • String提供@Component注解的三个衍生注解
    • @Controller:用于表现层bean定义
    • @Service:用于业务层bean定义
    • @Repository:用于数据层bean定义
@Repository("bookDao") // 数据层的bean
public class BookDaoImpl implements BookDao {
}
@Service // 业务层的bean
public class BookServiceImpl implements BookService {
}
纯注解开发
  • 在纯注解开发中,使用java类代替spring核心配置文件

    • 核心配置文件如下
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><!--    核心配置文件中通过组件扫描加载bean--><context:component-scan base-package="com.itheima"/></beans>
    
    • java类如下
    package com.itheima.config;import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;//声明当前类为Spring配置类
    @Configuration
    //设置bean扫描路径,多个路径书写为字符串数组格式
    @ComponentScan({"com.itheima.service","com.itheima.dao"})
    public class SpringConfig {
    }

其中,java类中的@Configuration完全代替了原来核心配置文件的结构

  • @Configuration注解用于设定当前类为配置类
  • @ConponentScan注解用于设定扫描路径,此注解只能添加一次,多个数据用数组格式
//设置bean扫描路径,多个路径书写为字符串数组格式
@ComponentScan({"com.itheima.service","com.itheima.dao"})
  • 读取spring核心配置文件初始化容器对象切换为读取java配置类初始化容器对象
// 加载配置文件初始化容器
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
// 加载配置类初始化容器
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
纯注解开发中bean的管理
  • bean的作用范围

    • 使用@Scope定义bean作用范围
    //@Scope设置bean的作用范围
    @Scope("singleton")
    public class BookDaoImpl implements BookDao {
    }
    
  • bean的生命周期

    • 使用@PostConstruct、@PreDestroy定义bean生命周期
    @Repository
    //@Scope设置bean的作用范围
    @Scope("singleton")
    public class BookDaoImpl implements BookDao {public void save() {System.out.println("book dao save ...");}//@PostConstruct设置bean的初始化方法@PostConstructpublic void init() {System.out.println("init ...");}//@PreDestroy设置bean的销毁方法@PreDestroypublic void destroy() {System.out.println("destroy ...");}}
    

依赖注入相关

依赖注入
  • 使用@Autowired注解开启自动装配模式(按类型装配)
@Service
public class BookServiceImpl implements BookService {//@Autowired:注入引用类型,自动装配模式,默认按类型装配@Autowiredprivate BookDao bookDao;public void save() {System.out.println("book service save ...");bookDao.save();}
}

注意:自动装配基于反射设计创建对象并暴力反射对应属性为私有属性初始化数据,因此无需提供setter方法

注意:自动装配建议使用无参构造方法创建对象(默认),如果不提供对应构造方法,请提供唯一的构造方法

  • 使用@Qualifier注解开启指定名称装配bean
@Service
public class BookServiceImpl implements BookService {//@Autowired:注入引用类型,自动装配模式,默认按类型装配@Autowired//@Qualifier:自动装配bean时按bean名称装配@Qualifier("bookDao")private BookDao bookDao;
}

注意:@Qualifier注解无法单独使用,必须配合@Autowired注解使用

  • 对于简单类型注入,使用@Value进行装配
@Repository("bookDao")
public class BookDaoImpl implements BookDao {//@Value:注入简单类型(无需提供set方法)@Value("${name}") // name来自于配置文件propertyprivate String name;public void save() {System.out.println("book dao save ..." + name);}
}
  • 使用@PropertySource注解加载properties文件
@Configuration
@ComponentScan("com.itheima")
//@PropertySource加载properties配置文件
@PropertySource({"jdbc.properties"})
public class SpringConfig {
}

注意:路径仅支持单一文件配置,多文件要使用数组格式配置,不允许使用通配符*

第三方bean管理
  • 使用@Bean配置第三方bean
@Configuration
public class SpringConfig {@Beanpublic DataSource dataSource(){DruidDataSource ds = new DruidDataSource();ds.setDriverClassName(driver);ds.setUrl(url);ds.setUsername(userName);ds.setPassword(password);return ds;}
}
  • 使用独立的配置类管理第三方bean
@Configuration
public class JdbcConfig {@Beanpublic DataSource dataSource(){DruidDataSource ds = new DruidDataSource();ds.setDriverClassName(driver);ds.setUrl(url);ds.setUsername(userName);ds.setPassword(password);return ds;}
}
  • 将独立的配置类加入核心配置

    • 方式一:导入式(推荐使用)
    public class JdbcConfig {@Beanpublic DataSource dataSource(){DruidDataSource ds = new DruidDataSource();// 相关配置return ds;}
    }
    

    使用@Import注解手动加入配置类到核心配置,此注解只能添加一次,多个数据请用数组格式

    @Configuration
    @Import({JdbcConfig.class})
    public class SpringConfig {
    }
    
    • 方式二:扫描式**(不推荐使用,隐藏性强,不知道在config中导入过哪些配置类)**
    @Configuration
    public class JdbcConfig {@Beanpublic DataSource dataSource(){DruidDataSource ds = new DruidDataSource();// 相关配置return ds;}
    }
    

    使用@ComponentScan注解扫描配置类所在的包,加载对应的配置类信息

    @Configuration
    @ComponentScan({"com.itheima.config", "com.itheima.service", "com.itheima.dao"})
    public class SpringConfig {
    }
    
第三方bean依赖注入
  • 简单类型依赖注入
public class JdbcConfig {//1.定义一个方法获得要管理的对象@Value("com.mysql.jdbc.Driver")private String driver;@Value("jdbc:mysql://localhost:3306/spring_db")private String url;@Value("root")private String userName;@Value("root")private String password;//2.添加@Bean,表示当前方法的返回值是一个bean//@Bean修饰的方法,形参根据类型自动装配@Beanpublic DataSource dataSource(BookDao bookDao){System.out.println(bookDao);DruidDataSource ds = new DruidDataSource();ds.setDriverClassName(driver);ds.setUrl(url);ds.setUsername(userName);ds.setPassword(password);return ds;}
}
  • 引用类型依赖注入
@Beanpublic DataSource dataSource(BookDao bookDao){System.out.println(bookDao);DruidDataSource ds = new DruidDataSource();// 属性设置return ds;}

引用类型注入只需要为bean定义方法设置形参即可,容器会根据类型自动装配对象

AOP(Aspect Oriented Programming)面向切面编程

AOP简介

  • AOP:面向切面编程,一种编程范式,指导开发者如何组织程序结构

  • 作用:在不改变原始设计的基础上为其进行功能增强

  • spring理念:无入侵式编程

AOP核心概念

  • 连接点:程序执行过程中的任意位置,粒度为执行方法、抛出异常、设置变量等
    • 在SpringAOP中,理解为方法的执行
  • 切入点:匹配连接点的式子
    • 在SpringAOP中,一个切入点可以只描述一个具体方法,也可以匹配多个方法
  • 通知:在切入点处执行的操作,也就是共性功能
    • 在SpringAOP中,功能最终以方法的形式呈现
  • 通知类:定义通知的类
  • 切面:描述通知与切入点的对应关系

在这里插入图片描述

AOP工作流程

1.Spring容器启动

2.读取所有切面配置中的切入点

//通知类必须配置成Spring管理的bean
@Component
//设置当前类为切面类类
@Aspect
public class MyAdvice {// 设置切入点,要求配置在方法上方@Pointcut("execution(void com.itheima.dao.BookDao.update())")private void ptx(){}@Pointcut("execution(void com.itheima.dao.BookDao.update())")private void pt(){}// 设置在切入点pt()的前面运行当前操作(前置通知)@Before("pt()")public void method(){System.out.println(System.currentTimeMillis());}
}

3.初始化bean,判定bean对应的类中的方法是否匹配到任意切入点

  • 匹配失败,则创建对象
  • 匹配成功,则创建原始对象(目标对象)的代理对象

注:只要有一个切入点匹配成功,就算匹配上了

4.获取bean执行方法

  • 获取bean,调用方法并执行,完成操作
  • 获取的bean是代理对象时,根据代理对象的运行模式运行原始方法与增强的内容,完成操作

AOP切入点表达式

切入点:要进行增强的方法

切入点表达式:要进行增强的方法的描述方式

  • 方式一:执行接口中的无参数方法
  • 方式二:执行实现类中的无参数方法

切入点表达式标准格式:动作关键字(访问修饰符 返回值 包名.类/接口名.方法名(参数)异常名)

execution(public User com.itheima.service.UserService.findById(int))
  • 动作关键字:描述切入点的行为动作,例如execution表示执行到指定切入点
  • 访问修饰符:public、private等,可省略
  • 返回值
  • 包名
  • 类/接口名
  • 方法名
  • 参数
  • 异常名:方法定义中抛出指定异常,可以省略

可以使用通配符描述切入点,实现快速描述

  • *****:单个独立的任意符号,可以独立出现,也可以作为前缀或者后缀的匹配符出现
execution(public * com.itheima.*.UserService.find*(*))

匹配com.itheima包下的任意包中的UserService类或接口中所有find开头的带有一个参数的方法

  • :多个连续地任意符号,可以对出现,常用于化简包名与参数的书写
execution(public User com..UserService.findById(..))

匹配com包下的任意包中的UserService类或接口中所有名称为findById的方法

  • +:专用于匹配子类类型
execution(* *..*Service+.*(..))

书写技巧

  • 描述切入点通常描述接口,而不描述实现类,可以降低耦合度
  • 访问控制修饰符针对接口开发均采用public描述(可省略public)
  • 返回值类型对于增删改类使用精准类型加速匹配,对于查询类使用*通配快速描述
  • 包名书写尽量不使用…匹配,效率过低,常用*做单个包描述匹配,或精准匹配
  • 接口名/类名书写名称与模块相关的采用*****匹配,例如UserService书写成:*Service,绑定业务层接口名
  • 方法名书写以动词进行精准匹配,名词采用*****匹配,例如getById书写成getBy*,selectAll书写成selectAll
  • 通常不使用异常作为匹配规则

通知类型

  • AOP通知描述了抽取的共性功能,根据共性功能抽取的位置不同,最终运行代码时要将其加入到合理的位置

  • AOP通知共分为5种类型

    • 前置通知

    • 后置通知

    • 环绕通知(常用)

      • 名称:@Around
      • 类型:方法注解
      • 位置:通知方法定义上方
      • 作用:设置当前通知方法与切入点之间的绑定关系,当前通知方法在原始切入点方法前后运行
      • 范例
      @Around("pt()")
      public Object around(ProceedingJoinPoint pjp) throws Throwable {System.out.println("around before advice ...");Object ret = pjp.proceed(); // 表示对原始操作的调用System.out.println("around after advice ...");return ret;
      }
      
    • 返回后通知(不常用)

    • 抛出异常后通知(不常用)

@Around注意事项

  • 环绕通知必须依赖形参ProceedingJoinPoint才能实现对原始方法的调用,进而实现原始方法调用前后同时添加通知
  • 通知中如果未使用ProceedingJoinPoint对原始方法进行调用,将跳过原始方法的执行
  • 对原始方法的调用可以不接收返回值,通知方法设置成void即可,如果接收返回值,通知方法必须设定为Object类型
  • 原始方法的返回值如果是void类型,通知方法的返回值可以设置成void,也可以设置成Object
  • 由于无法预知原始方法运行后是否会抛出异常,因此环绕通知方法必须抛出Throwable对象

AOP通知获取数据

  • 获取切入点方法的参数

    • JoinPoint:适用于前置、后置、返回后、抛出异常后通知
    @Before("pt()")
    public void before(JoinPoint jp) {Object[] args = jp.getArgs();System.out.println(Arrays.toString(args));System.out.println("before advice ..." );
    }
    
    • ProceedingJointPoint:适用于环绕通知
    @Around("pt()")
    public Object around(ProceedingJoinPoint pjp) {Object[] args = pjp.getArgs();System.out.println(Arrays.toString(args));args[0] = 666;Object ret = null;try {ret = pjp.proceed(args);} catch (Throwable t) {t.printStackTrace();}return ret;
    }
    

    注:ProceedingJointPoint是JointPoint的子类

  • 获取切入点方法返回值

    • 返回后通知
    • 环绕通知
  • 获取切入点方法运行异常信息

    • 抛出异常后通知
    • 环绕通知

http://www.mrgr.cn/p/02040440

相关文章

Phone List

题目描述输入格式输出格式样例 样例输入 2 3 911 97625999 91125426 5 113 12340 123440 12345 98346 样例输出 NO YES 数据范围与提示这道题的三条判断是否存在前缀的标准:当在建树字符串已经到结尾时,如果该点有结束标记,那肯定是前缀(不是真前缀)当在建树字符串已经到结…

《自动机理论、语言和计算导论》阅读笔记:p352-P401

《自动机理论、语言和计算导论》学习第 12 天&#xff0c;p352-P401总结&#xff0c;总计 50 页。 一、技术总结 1.Turing Machine ™ 2.undecidability ​ a.Ld(the diagonalization language) 3.reduction p392, In general, if we have an algorithm to convert insta…

MySQL双层游标嵌套循环方法

文章目录 1、需求描述2、思路3、创建存储过程 1、需求描述 1、在项目中&#xff0c;需要将A表中主键id&#xff0c;逐个取出&#xff0c;作为条件&#xff0c;在B表中去逐一查询&#xff0c;将B表查询到的结果集&#xff08;A表B表关系&#xff1a;一对多&#xff09;&#xf…

SSM教务管理系统设计与实现(附源码下载地址)

@目录01 项目背景02 使用技术03 运行环境04 功能分析05 数据库设计06 项目工程结构07 部分功能展示及源码7.1 登录页7.2 管理员端--首页7.3 管理员端--课程管理7.4 管理员端--学生管理7.5 教师端--首页7.6 教师端--个人信息7.7 学生端--已修课程7.8 学生端--公告管理08 运行教程…

AutoCAD C# 两不平行直线倒圆弧算法

参考的博客:https://www.cnblogs.com/JJBox/p/14300098.html 下面是计算示例主要计算代码:var peo = new PromptEntityOptions("选择直线1"){AllowNone = false,AllowObjectOnLockedLayer = false};peo.SetRejectMessage("请选择直线Line");peo.AddAllow…

挖矿流量分析之Stratum挖矿协议

目录前言区块链和挖矿相关概念挖矿木马挖矿协议StratumStratum工作过程 前言 之前做了一个关于“挖矿行为检测”的大创训练项目,在这里记录一下我关于挖矿检测相关内容的学习。 区块链和挖矿相关概念 区块链 首先需要了解一些关于区块链的内容。注意,区块链和挖矿是两个紧密相…

分类预测 | MATLAB实现LSSVM最小二乘支持向量机多分类预测

分类预测 | MATLAB实现LSSVM最小二乘支持向量机多分类预测 目录 分类预测 | MATLAB实现LSSVM最小二乘支持向量机多分类预测分类效果基本介绍程序设计参考资料分类效果 基本介绍 MATLAB实现LSSVM最小二乘支持向量机多分类预测。最小二乘支持向量机(Least Squares Support Vecto…

人脸识别概念解析

目录 1. 概述 2. 人脸检测 3. 人脸跟踪 4. 质量评价 5. 活体检测 6. 特征提取 7. 人脸验证 8. 人脸辨识 1. 概述 人脸识别在我们的生活中随处可见&#xff0c;例如在大楼门禁系统中&#xff0c;它取代了传统的门禁卡或密码&#xff0c;提高了进出的便捷性和安全性。在商…

15_Scala面向对象编程_访问权限

文章目录 Scala访问权限1.同类中访问2.同包不同类访问3.不同包访问4.子类权限小结 Scala访问权限 知识点概念 private --同类访问private[包名] --包私有&#xff1b; 同类同包下访问protected --同类&#xff0c;或子类 //同包不能访问(default)(public)默认public --公…

Sentinel 控制台学习

引言 上篇文章已经讲过 SpringCloud Sentinel集成到微服务项目中&#xff0c;接下来我们继续学习怎么使用sentinel控制台对微服务进行限流&#xff0c;熔断&#xff0c;降级等一系列操作。 控制台 接下来我们单独讲解每一个菜单按钮 实时监控 实时监控&#xff1a; 可以看到…

|Python新手小白中级教程|第二十七章:面向对象编程(示例操作)(3)使用turtle库与类结合

文章目录 前言一、项目&#xff1a;使用类Circle画出圆形&#xff08;不调用turtle库&#xff09;1.基础指令class2.使用turtle画出大圆与小圆3.使用其他功能画一只眼睛 二、使用turtle库画正方形总结 前言 hello&#xff0c;我是BoBo仔&#xff0c;welcome来看我的文章 这节课…

二叉树四种遍历方法

目录 树基本概念 二叉树二叉树的五种形态特殊二叉树二叉链表创建四种遍历方法代码实现 树 树是一个n个节点的有限集&#xff0c;当n0时称之为空树 基本概念 性质 1. 树的定义是递归的&#xff0c;树的定义中又用到了自身 2. 树的根节点没有前驱&#xff0c;除根结点外&#x…

sublime设置默认打开侧边栏(失败)

描述 每次使用sublime打开某个目录,总是不显示侧边栏,还得手动打开。 过程 在设置里找了半天似乎没有这个选项,有点离谱,网上搜到的全是手动打开侧边栏。看来只能Ctrl+KB按得勤快些了。// Display the toggle sidebar button in the status bar"show_sidebar_button&q…

Stable Diffusion AI绘画

我们今天来了解一下最近很火的SD模型 ✨在人工智能领域&#xff0c;生成模型一直是研究的热点之一。随着深度学习技术的飞速发展&#xff0c;一种名为Stable Diffusion的新型生成模型引起了广泛关注。Stable Diffusion是一种基于概率的生成模型&#xff0c;它可以学习数据的潜…

传媒论坛编辑部传媒论坛杂志社传媒论坛杂志2024年第7期目录

专题│场景传播研究 场景传播&#xff1a;一场遮盖自我与寻找自我的博弈 胡沈明; 3 基于CiteSpace的中国场景传播研究热点分析 管倩;粟银慧; 4-610《传媒论坛》投稿&#xff1a;cnqikantg126.com 数字世界的美与危&#xff1a;场景传播的失范与应对之举 王依晗;章洁…

Matlab安装教程(Linux)

解压安装包 在虚拟机中,文件直接通过拖拽文件的方式将安装包拉入虚拟机时,文件通常存放在/tmp/VMwareDnD中,因此需要将存放文件位置的文件转移到/home/<用户名>/<存放目录>中 参考命令如下: mv /tmp/VMwareDnD/<文件存放目录>/* /home/<用户名>/&l…

动态sql

本文参考mybatis看这一篇就够了&#xff0c;简单全面一发入魂 动态SQL 可以根据具体的参数条件&#xff0c;来对SQL语句进行动态拼接。 比如在以前的开发中&#xff0c;由于不确定查询参数是否存在&#xff0c;许多人会使用类似于where 1 1 来作为前缀&#xff0c;然后后面用…

54.HarmonyOS鸿蒙系统 App(ArkTS)tcp socket套接字网络连接收发测试

工程代码https://download.csdn.net/download/txwtech/89258409?spm1001.2014.3001.5501 54.HarmonyOS鸿蒙系统 App(ArkTS)tcp socket套接字网络连接收发测试 import socket from ohos.net.socket; import process from ohos.process; import wifiManager from ohos.wifiMana…

2. 基础配置

1. 配置文件格式 1.1 配置文件自动提示功能消失解决方案 ​​ 1.2 SpringBoot配置文件加载顺序(了解) application.properties > application.yml > application.yaml 1.3 注意事项 SpringBoot核心配置文件名为application SpringBoot内置属性过多,且所有属性集中…

Qt/C++音视频开发72-倍速推流/音视频同步倍速推流/不改变帧率和采样率/低倍速和高倍速

一、前言 最近多了个新需求,需要倍速推流,推流界的扛把子obs也有倍速推流功能,最高支持到两倍速。这里所说的倍速,当然只限定在文件,只有文件才可能有倍速功能,因为也只有文件才能倍速解码播放。实时视频流是不可能倍速的,因为没有时长,有时长的才可以按照播放进度来。…