spring框架学习记录(2)

news2024/11/19 8:49:35

文章目录

    • 注解开发
      • 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.xsd
            http://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的初始化方法
        @PostConstruct
        public void init() {
            System.out.println("init ...");
        }
        //@PreDestroy设置bean的销毁方法
        @PreDestroy
        public void destroy() {
            System.out.println("destroy ...");
        }
    
    }
    

依赖注入相关

依赖注入
  • 使用@Autowired注解开启自动装配模式(按类型装配)
@Service
public class BookServiceImpl implements BookService {
    //@Autowired:注入引用类型,自动装配模式,默认按类型装配
    @Autowired
    private 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来自于配置文件property
    private 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 {
	@Bean
    public 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 {
	@Bean
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName(driver);
        ds.setUrl(url);
        ds.setUsername(userName);
        ds.setPassword(password);
        return ds;
    }
}
  • 将独立的配置类加入核心配置

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

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

    @Configuration
    @Import({JdbcConfig.class})
    public class SpringConfig {
    }
    
    • 方式二:扫描式**(不推荐使用,隐藏性强,不知道在config中导入过哪些配置类)**
    @Configuration
    public class JdbcConfig {
    	@Bean
        public 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修饰的方法,形参根据类型自动装配
    @Bean
    public 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;
    }
}
  • 引用类型依赖注入
@Bean
    public 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.coloradmin.cn/o/1642277.html

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

相关文章

大语言模型中的第一性原理:Scaling laws

大语言模型的尺度定律在大语言模型的训练过程中起到了非常重要的作用。即使读者不参与大语言模型的训练过程&#xff0c;但了解大语言模型的尺度定律仍然是很重要的&#xff0c;因为它能帮助我们更好的理解未来大语言模型的发展路径。 1. 什么是尺度定律 尺度定律&#xff08…

现代循环神经网络(GRU、LSTM)(Pytorch 14)

一 简介 前一章中我们介绍了循环神经网络的基础知识&#xff0c;这种网络 可以更好地处理序列数据。我们在文本数据上实现 了基于循环神经网络的语言模型&#xff0c;但是对于当今各种各样的序列学习问题&#xff0c;这些技术可能并不够用。 例如&#xff0c;循环神经网络在…

【错题集-编程题】十字爆破(预处理 + 模拟)

牛客对于题目链接&#xff1a;十字爆破 (nowcoder.com) 一、分析题目 暴力模拟会超时。 预处理&#xff0c;先把每一行以及每一列的和存起来。 模拟即可&#xff0c;但是由于数据量过⼤&#xff0c;我们可以提前把每⼀⾏以及每⼀列的和存起来&#xff0c;⽅便统计总和。 二、代…

(centos)yum安装mysql8.4

1.MySQL官方已经提供了适用于不同Linux发行版的预构建软件包&#xff0c;包括适用于CentOS的Yum Repository MySQL :: MySQL Community Downloads 2.在/usr/local文件夹下创建mysql文件夹&#xff0c;将下载的rpm文件放到目录下 3.执行安装命令 yum install mysql-community-…

思科防火墙查如何查看现有ipsec隧道信息

环境&#xff1a; 思科ASA5555 问题描述&#xff1a; 思科防火墙查如何看现有ipsec隧道信息 解决方案&#xff1a; 1.进入特权模式&#xff1a; enable 查看isakmp信息 show crypto isakmp sa2.查看ipsec信息 show crypto ipsec sa上述命令将显示当前的ISAKMP安全关联…

leetCode69. x 的平方根

leetCode69. x 的平方根 题目思路 常见的二分法模板&#xff08;背过就行&#xff0c;模板而已&#xff09; // 区间[L,R]被划分为[L,mid]和[mid 1, R]时使用这个模板 int bsearch_1(int l, int r){while(l < r){int mid l r >> 1;if(check(mid)) r mid; //che…

08 IRF技术 华三交换机实现

IRF 详细介绍 我知道 AI IRF 技术是指集成路由功能(Integrated Routing and Bridging)技术,是惠普(Hewlett Packard)公司开发的一种基于硬件的虚拟化技术。IRF 技术可以将多台物理设备组合成一个逻辑设备,实现设备的高可用性和灵活性。 IRF 技术主要有以下特点: 1. …

【强训笔记】day9

NO.1 思路&#xff1a;利用两个string&#xff0c;一个输入数据&#xff0c;一个做逗号处理&#xff0c;如果该字符的位数减去下标减去1等于3的倍数的话&#xff0c;该位置就插入逗号。 代码实现&#xff1a; #include<iostream> #include<string> using names…

Redis事务,管道,发布订阅

Redis事务 redis事务本质上是一组命令的集合,按照顺序串行化执行命令而不被其他命令打断 redis事务开启后将要执行的命令放到事务队列中,提交事务后一次性顺序排他地执行所有命令 关键词:单线程,无隔离级别,不保证原子性,排他性,顺序性 要注意和mysql的acid进行区分 怎么用…

C++:智能指针(RAII思想)

目录 1、什么是智能指针&#xff1f; 2、为什么需要智能指针 3、RAII思想及智能指针的原理 4、智能指针的发展 4.1 auto_ptr 4.2 unique_ptr 4.3 share_ptr 5、share_ptr的模拟实现 6、循环引用问题 7、share_ptr中的自定义删除器 1、什么是智能指针&#xff1f; 智能…

java spring 09 Bean的销毁过程

1.Bean销毁是发送在Spring容器关闭过程中的 AnnotationConfigApplicationContext context new AnnotationConfigApplicationContext(AppConfig.class);UserService userService (UserService) context.getBean("userService");userService.test();// 容器关闭cont…

LeetCode题练习与总结:最大矩形--85

一、题目描述 给定一个仅包含 0 和 1 、大小为 rows x cols 的二维二进制矩阵&#xff0c;找出只包含 1 的最大矩形&#xff0c;并返回其面积。 示例 1&#xff1a; 输入&#xff1a;matrix [["1","0","1","0","0"],[&quo…

C++入门系列-类对象模型this指针

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 类对象模型 如何计算类对象的大小 class A { public:void printA(){cout << _a << endl;} private:char _a; }; 算算看&#xff0c;这个类的大小是多少 我们知道…

Typora编辑markdown的技巧

参考视频的B站链接&#xff1a; 手把手教你撰写Typora笔记 在其中选择了常用的部分做标记。 一、标题 使用ctrl数字键&#xff0c;可以快捷的把一行文字变成n级标题 二、源代码模式 可以在下图所示进入 三、设置typora能够自动显示粘贴的图片 打开“偏好设置”&#xff0…

Android使用kts发布aar到JitPack仓库

Android使用kts发布aar到JitPack 之前做过sdk开发&#xff0c;需要将仓库上传到maven、JitPack或JCenter,但是JCenter已停止维护&#xff0c;本文是讲解上传到JitPack的方式,使用KTS语法&#xff0c;记录使用过程中遇到的一些坑.相信Groovy的方式是大家经常使用的&#xff0c;…

力扣每日一题106:从中序与后序遍历序列构造二叉树

题目 中等 相关标签 相关企业 给定两个整数数组 inorder 和 postorder &#xff0c;其中 inorder 是二叉树的中序遍历&#xff0c; postorder 是同一棵树的后序遍历&#xff0c;请你构造并返回这颗 二叉树 。 示例 1: 输入&#xff1a;inorder [9,3,15,20,7], postorder …

R语言学习—6—多元相关与回归分析

1、引子 xc(171,175,159,155,152,158,154,164,168,166,159,164) #身高 yc(57,64,41,38,35,44,41,51,57,49,47,46) #体重 par(marc(5,4,2,1)) #设定图距离画布边缘的距离&#xff1a;下5&#xff0c;左4&#xff0c;上2&#xff0c;右1 plot(x,y) 2、相关…

Web API之DOM

DOM 一.认识DOM二.获取元素三.事件基础四.操作元素(1).改变元素内容(2).修改元素属性(str、herf、id、alt、title&#xff09;(3).修改表单属性(4).修改样式属性操作(5).小结 五.一些思想(1).排他思想(2).自定义属性的操作 六.节点操作1.认识2.节点层级关系3.创建和添加、删除、…

PR2019软件下载教程

打开下载网址&#xff1a;rjctx.com 选择Premiere&#xff1a; 选择PR2019&#xff0c;并点击&#xff1a; 拉到最后&#xff0c;选择百度网盘下载&#xff1a; 下载到本地。 二&#xff0c;软件安装 解压缩后&#xff0c;双击set_up 选择位置后&#xff0c;进行安装&…

直播素材安卓情侣飞行棋v2.22 仿dofm 支持自定义模式—可用直播素材

一个情侣间增进友谊的小游戏非常好玩&#xff0c;适合男孩女孩之间增进感情&#xff01;快和你暗恋的女孩一块玩吧&#xff0c;极速升温 永久免费&#xff01;解锁激活码内容全部畅玩&#xff01;全网最强超级给力&#xff01;真人说书音频 网盘自动获取 链接&#xff1a;http…