spring框架学习记录(2)

文章目录

    • 注解开发
      • 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.mzph.cn/web/6513.shtml

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

相关文章

C++11:lambda表达式及function包装器

目录 1、什么是lambda表达式 2、lambda表达式 2.1 lambda表达式语法 2.2 捕获列表说明 3、function包装器 bind 1、什么是lambda表达式 Lambda表达式是一种在C11中引入的功能&#xff0c;允许我们定义匿名函数。它的语法比较简洁&#xff0c;可以方便地在需要函数对象的地…

Idea 自动生成测试

先添加测试依赖&#xff01;&#xff01; <!--Junit单元测试依赖--><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter</artifactId><version>5.9.1</version><scope>test</scope><…

2024年手把手教你安装iMazing3 中文版图文激活教程

热门苹果设备备份管理软件iMazing日前正式发布了全新的 3.0 版本。它采用了全新的设计和架构&#xff0c;并且率先支持Apple Vision Pro安装软件和导入数据。团队表示&#xff0c;这是市场首个第三方支持Apple Vision Pro的管理工具。 iMazing是一款兼容Win和Mac的iOS设备管理…

什么是sql注入攻击?

什么是sql注入攻击? 就是在对用户的输入的数据没有进行很好的处理,从而导致输入变成了sql语句的一部分了,正常来说用户输入的数据只是参数,但是不是的 举个例子吧 比如在登录的时候,用户名是fjg,密码是123456,但是黑客了,不知道密码,但是知道你sql的相关处理的不好,黑客这样操…

杭电 OJ 1000-1009 Java解法

Problem Set 1000 高精度 import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scnew Scanner(System.in);while(sc.hasNext()){System.out.println(sc.nextBigInteger().add(sc.nextBigInteger()));}} } 1001 位运算防爆 1000…

解决Linux中磁盘满/dev/vda1使用率100%问题

发现根目录下占用100%&#xff0c;具体还要排场到底是有哪些大文件占用 那么就在根目录下查询各个子文件夹的占用状态&#xff0c;有过大不用的即可删除 df -h *我的磁盘是100G&#xff0c;但这些总共加起来也接近不了这个数值 那就是有可能出现 已删除空间却没有释放的进程…

嵌入式学习day09

每日面试题 堆栈溢出的原因有哪些 ①函数调用层次太深&#xff0c;函数递归调用时&#xff0c;系统要在栈中不断保存函数调用时的线程和产生的变量&#xff0c;递归调用太深&#xff0c;会造成栈溢出&#xff0c;这时递归无法返还。 ②动态申请空间使用后没有释放。由于C语言…

(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-…

Vue3 + Vite + TypeScript + Element-Plus创建管理系统项目

官方文档 Vue3官网 Vite官方中文文档 创建项目 使用npm命令创建项目&#xff1a; npm create vitelatest输入项目名称&#xff1a; ? Project name:项目名选择vue&#xff1a; ? Select a framework: - Use arrow-keys. Return to submit.Vanilla > VueReactPrea…

jupyter notebook 设置密码报错ModuleNotFoundError: No module named ‘notebook.auth‘

jupyter notebook 设置密码报错ModuleNotFoundError: No module named ‘notebook.auth‘ 原因是notebook新版本没有notebook.auth 直接输入以下命令即可设置密码 jupyter notebook password

「JavaEE」线程安全2:内存可见性问题 wait、notify

&#x1f387;个人主页&#xff1a;Ice_Sugar_7 &#x1f387;所属专栏&#xff1a;JavaEE &#x1f387;欢迎点赞收藏加关注哦&#xff01; 内存可见性问题& wait、notify &#x1f349;Java 标准库的线程安全类&#x1f349;内存可见性问题&#x1f34c;volatile 关键字 …

M2M vs. IoT?

有任何关于GSMA\IOT\eSIM\RSP\业务应用场景相关的问题&#xff0c;欢迎W: xiangcunge59 一起讨论, 共同进步 (加的时候请注明: 来自CSDN-iot). 连接设备已经开辟了创造价值和解决重大世界问题的广泛机会&#xff0c;例如可持续发展。 今天&#xff0c;我们网络设备的方式可…

【linuxC语言】vfork、wait与waitpid函数

文章目录 前言一、函数使用1.1 vfork1.2 wait1.3 waitpid 二、示例代码总结 前言 在Linux系统编程中&#xff0c;vfork()、wait() 和 waitpid() 函数是处理进程管理和控制流的重要工具。这些函数允许我们创建新进程、等待子进程结束并获取其退出状态&#xff0c;从而实现进程间…

GDPU JavaWeb 猜字母游戏

他在对你重定向打卡的大饼与立即跳转到你面前的谎言之间反复横跳。 sendRedirect与forward sendRedirect与forward区别 sendRedirect用于将请求重定向到另一个资源&#xff0c;可以是同一个应用程序内的其他 Servlet&#xff0c;也可以是其他 Web 应用程序的资源&#xff0c;…

配电网光伏储能双层优化配置模型(选址定容)

随着主动配电网中不可控分布式电源(distributed generation,DG)渗透率的不断提高,其给配电网规划运行提 出了更大的挑战,可能导致配电网电压越限、清洁能源弃电 等问题。基于此,该文在规划阶段充分应用不同类型 DG 和 负荷的时序性和潮流计算特性,以及引入不同恢复率的激励…

telement-plus中table合并行或者列

#element-plus中会有自带的合并方法 通过给 table 传入span-method方法可以实现合并行或列&#xff0c; 方法的参数是一个对象&#xff0c;里面包含当前行 row、当前列 column、当前行号 rowIndex、当前列号 columnIndex 四个属性。 该函数可以返回一个包含两个元素的数组&…

农作物害虫检测数据集VOC+YOLO格式18975张97类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;18975 标注数量(xml文件个数)&#xff1a;18975 标注数量(txt文件个数)&#xff1a;18975 标…

minio忘记密码

安装minio 对象存储minio-CSDN博客 cat << EOF > /etc/default/minio# Volume to be used for Minio server. MINIO_VOLUMES"/data"# Use if you want to run Minio on a custom port. #MINIO_OPTS"--address :9001" MINIO_OPTS"--address …

卷积神经网络要点和难点实际案例和代码解析

卷积神经网络(Convolutional Neural Networks,CNN)是一类包含卷积计算且具有深度结构的前馈神经网络,是深度学习的代表算法之一。卷积神经网络仿造生物的视知觉机制构建,可以进行监督学习和非监督学习,其隐含层内的卷积核参数共享和层间连接的稀疏性使得卷积神经网络能够…

Boost读写xml

Boost读写xml 文章目录 Boost读写xml写在前面准备工作简单读写写xml读xml键值查找遍历 设置默认值异常处理 具有属性的xml写xml读xml键值查找遍历 知识补充 写在前面 ​ 前面我们讲过了如何使用Boost读写ini文件&#xff0c;这一篇我们将介绍如何用Boost读写xml文件。 ​ XML…