文章目录
- Maven
- Maven仓库
- Maven坐标
- 为什么Maven进行了依赖管理,依然会出现依赖冲突?处理依赖冲突的手段是什么?
- 详细讲讲scope依赖范围
- Maven的生命周期
- Maven高级
- 分模块设计
- 继承
- 版本锁定
- 聚合
- Maven的继承与聚合的异同
- 私服
- Tomcat
- servlet
- 分层解耦
- 三层架构
- IOC(控制反转)与DI(依赖注入)
- IOC详解
- Bean组件扫描
- DI详解
- Mybatis
- 配置流程
- JDBC(Java DataBase Connectivity)
- 数据库连接池
- lombok工具包
- Mybatis基础操作
- 删除
- 预编译SQL
- 新增
- 修改
- 查询
- XML映射文件
- Mybatis动态SQL
- Restful 风格 API
- properties配置文件
- 参数配置
- yml配置文件
- ConfigurationProperties
- 案例实现 - 登录校验
- 会话技术
- cookie
- session
- 令牌(token)技术
- JWT令牌
- Filter
- Filter执行流程详解
- 过滤器链
- 登录校验Filter流程
- 拦截器
- 过滤器和拦截器区别
- 异常处理
- 全局异常处理器
- Spring事务管理
- 事务进阶
- AOP(面向切面编程)
- AOP核心概念
- AOP进阶
- 通知类型
- 通知顺序
- 切入点表达式
- execution
- annotation
- 连接点
- Spring
- 配置优先级
- Bean管理
- 获取Bean
- bean作用域
- 第三方bean
- SpringBoot原理
- 自动配置原理
- @SpringBootConfiguration
- @Conditional
- 自定义starter
- 案例:自定义阿里云OSS启动器
- 总结
Maven
Maven是一个项目管理工具,它包含了一个项目对象模型(Project Object Model, pom文件),一个项目生命周期(命令),一个依赖管理系统(坐标)。
使用Maven的好处:
1、方便对项目进行模块构建,简化项目结构,便于开发分工,提高开发效率。
2、Maven可以将不同系统的依赖进行统一管理,并且可以进行依赖之间的传递和继承,便于项目升级。
3、Maven还有很多插件,便于功能拓展,例如maven-shade,用于把多个jar包,打成1个jar包;maven-compiler-plugin,用于编译项目的源代码等。
Maven仓库
Maven仓库用于存储资源,管理各种jar包。
仓库分成三种:
- 中央仓库:由Maven团队维护的全球唯一的
- 本地仓库:自己计算机上的一个目录
- 远程仓库:一般由公司团队搭建的私有仓库
Maven坐标
- groupId :组织ID,定义当前Maven项目隶属组织名称(通常是域名反写,例如:com.qjk)
- artifactId :项目ID,定义当前Maven项目名称(通常是模块名称,例如 order-service、goods-service)
- version :定义当前项目版本号
- packaging :定义 Maven 项目打包的方式,如没有 packaging ,则默认为 jar 包。
- classifier :该元素用来帮助定义构建输出的一些附件。附属构件与主构件对应。
为什么Maven进行了依赖管理,依然会出现依赖冲突?处理依赖冲突的手段是什么?
出现依赖冲突的原因:
- 传递依赖导致不同版本的jar包冲突,Maven采用就近原则排除了依赖路径较远的jar包,导致出现
ClassNotFound
这类的错误。 - 不同的jar包,出现了相同的类路径。
jar包冲突的解决方案:
- idea 可以按照Maven Helper插件,帮助分析出现冲突的jar包。
- 使用Ctrl + shift + alt + n 查找类路径所在的jar包,把对应的jar包在pom中排除。
详细讲讲scope依赖范围
- compile:默认的scope,运行期有效,需要打入包中
- test:仅在测试程序中有效,不会打入包中
- provided:编译期有效,运行期不需要提供,不会打入包中
- runtime:编译期不需要,运行期有效,需要打入包中
Maven的生命周期
Maven的生命周期就是对所有Maven项目构建过程进行抽象和统一。
在idea中我们终点关注下面的5个阶段(按照先后顺序):
- clean:移除上一次构建生成的文件
- compile:编译项目源代码
- test:使用合适的单元测试框架进行测试,如Junit
- package:将编译的文件打包为jar或者war包
- install:安装项目到本地仓库
注意:在同一套生命周期中,当运行后边的阶段时,前面的阶段都会运行。
在idea中点击lifecycle下的生命周期的某个阶段,实际上也是由对应的Maven插件完成的。
Maven高级
分模块设计
模块化设计便于开发分工,也便于后期项目的管理、扩展和维护,也便于其他项目集成现有模块功能。集成时,只需要引入相应的Maven依赖即可。
继承
不同的模块可能需要引入相同的依赖,那么我们可以将模块的公共依赖抽取出来,构建一个父工程,其他需要该依赖的子模块只需要继承父工程的依赖即可。
Maven工程的继承与Java中的继承类似,不允许多继承,即一个模块工程只能继承一个父工程
tips:打包方式总结:
因此我们在用Maven实现工程继承关系时,应该使用pom方式打包:
使用标签<packaging> pom </packaging>
指定,如果不指定默认为jar包。
继承关系实现:
版本锁定
在父工程中通过标签< dependencyManagement > 来统一管理依赖版本,这样子工程无需指定版本号,当需要版本变更时,只需要在父工程中统一变更。
< dependencies > 标签是直接依赖,在父工程配置了该标签,子工程会直接继承。
< dependencyManagement >是统一依赖管理版本,不会直接依赖,如果子工程需要该依赖,需要在pom文件中引入,只是无需再指定版本号,会使用父工程中指定管理的版本号。
但是在父工程中,各个依赖的版本号也是零散分布在各个依赖的version标签中,为了集中管理版本标签。可以使用Maven提供的自定义属性和引用属性
功能。
聚合
聚合的目的是为了将多个模块组织为一个整体,这样在执行Maven的生命周期操作(比如clean compile test install package )就可以一键执行。
Maven的继承与聚合的异同
私服
私服就是公司内部统一管理的Maven依赖库。
这个过程与Github远程仓库类似。。。
第一步:设置私服的访问用户名和密码:使用server标签
第二步:指定配置上传(发布)地址。
第三步:设置私服依赖下载的仓库组地址
同时设置允许从私服下载。(默认情况下snapshots版本无法从私服下载。)
Tomcat
Tomcat是一个轻量级的web服务器,也被称为web容器,servlet容器,web服务器对HTTP协议操作进行封装,简化了web程序开发,用于部署web项目,对外提供网上信息浏览服务。
servlet
分层解耦
三层架构
基于单一职责原则,采用三层架构来完成后端对于业务数据访问、逻辑处理与响应各自的功能。
- Controller:控制层,接收前端发送的请求,对请求进行处理,并响应数据。
- Service:业务逻辑层,处理具体的业务逻辑。
- Dao:(data access object,数据访问对象层),负责数据访问操作,包括数据库的增删查改。
按照三层架构思想,前端的请求先通过Controller层,接收请求,然后通过Service层进行逻辑处理,Service层逻辑处理的对象需要借助Dao层获取到数据对象,业务操作完成后再由Controller层响应数据给到前端。
IOC(控制反转)与DI(依赖注入)
按照三层架构编写的代码,中间的service层分别与上层的Controller层和下层的Dao层相互耦合依赖。
为了实现分层解耦,Spring提供了控制反转(inversion of control,IOC)和依赖注入(dependency injection,DI)技术。
控制反转将对象交由容器管理,依赖注入则将对象注入到需要使用的地方。
- 控制反转(IOC):对象的创建控制权由程序转移到外部(容器)。
- 依赖注入(DI):容器为应用程序提供运行时所依赖的资源。
- 容器中创建、管理的对象,称为
bean
具体实现过程:
- 使用
@Component
注解将service层和dao层的实现类,交给IOC容器管理。 - 在controller层需要依赖service层实现类的地方和service层需要依赖dao层实现类的地方,使用
@Autowired
注解。
IOC详解
IOC就是将对象交由容器管理,在实际开发中,除了上边使用的@Component
注解,实际上我们用到的更多的注解为@Controller
、@Service
、@Repository
,分别对应controller层、service层和dao层。
查看@Service
注解会发现,它由@Component
注解和元注解构成,因此,实际上,它是Component的衍生注解。
- 使用注解会在容器中声明一个Java bean对象,声明 bean 时,可以通过value属性,指定bean的名字,如果没有指定,默认为类名首字母小写。
- 使用上边四个注解都可以声明bean,但在springboot集成web开发中,声明控制器的bean只能用
@Controller
,此外由于注解@RestController
是一个集成了@Controller
和@Requestbody
的复合注解,所以它也是可以用于声明controller类型的bean对象。
Bean组件扫描
- 声明的bean的四大注解,如果想要生效,还需要被组件扫描注解
@ComponentScan
扫描。 @ComponentScan
注解虽然没有显示配置,但实际上已经包含在了启动类声明注解@SpringBootApplication
中,默认扫描的范围是启动类所在包及其子包。
如果想要在启动类所在包以外扫描bean组件,需要在启动类处使用@ComponentScan
注解,参数为包名,注意使用@ComponentScan
注解后会使得默认注解失效,因此需要重新指定启动类所在包。
DI详解
DI依赖注入@Autowired
注解是从容器中根据类型来获取到相应的bean对象,如果存在多个相同类型的bean,将会报错:
通过以下几种方案解决;
- @Primary:当存在多个相同类型的注解时,优先注入使用该注解声明的bean对象。
- @Qualifier:使用该注解配合@autowired注解,指定bean的名字。
- @Resource:单独使用该注解,指定bean名称。
@Autowired
和 @Resource
注解的区别:
@Autowired
是spring框架提供的注解,而@Resource
是JDK提供的注解@Autowired
默认是按照类型注入,而@Resource
是默认按照名称注入
Mybatis
- MyBatis 是一款优秀的持久层框架
- MyBatis 避免了几乎所有的 JDBC (Java Database Connect)代码和手动设置参数以及获取结果集的过程
- MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 实体类 【Plain Old Java Objects,普通的 Java对象】映射成数据库中的记录。
- MyBatis 本是apache的一个开源项目ibatis, 2010年这个项目由apache 迁移到了google code,并且改名为MyBatis 。
- Mybatis官方文档 : http://www.mybatis.org/mybatis-3/zh/index.html
- GitHub : https://github.com/mybatis/mybatis-3
配置流程
@Mapper
注解会在将接口的实现类放入容器中管理,因此当我们想要使用该接口的实现类对象时,只需要声明一个实现类对象,并使用@Autowired
注解自动注入,就会得到该Mapper
注解声明的对象。
JDBC(Java DataBase Connectivity)
传统的jdbc操作,有很多重复代码块,比如数据取出时的封装,数据库建立连接等等,而Mybatis的作用在于基于框架帮助程序员将数据存入数据库中和从数据库中取出数据。
数据库连接池
lombok工具包
通过注解@Data
简化实体类编写。
Mybatis基础操作
在Mybatis中配置SQL语句有两种方式:
- 基于注解
- 基于XML映射文件
删除
预编译SQL
- 预编译SQL性能更好,例如同一条SQL,仅仅是参数不同,使用预编译的SQL可以将SQL缓存,应用缓存替换参数,直接执行。使用缓存可以跳过SQL语法解析检查、SQL优化和SQL编译,因此性能更高。
- 防止SQL注入,更加安全。SQL注入是通过操作输入的数据来修改事先定义好的SQL语句,以达到执行代码对服务器进行攻击的方法
SQL注入攻击案例:
在登录中输入:账号名任意,密码为'or '1' = '1'
后台校验时:
可以看到 ==or ‘1’ = ‘1’==永远成立,那么自然永远可以登录成功!
除了使用#
参数占位符,还可以使用$
占位,区别如下:
新增
主键返回:
使用@Options
注解,useGeneratedKeys = true,令主键赋值给 id 属性。
修改
查询
数据封装:
实体类属性名与字段名不一致时,没法自动将字段值封装到类的属性值。
解决方案如下:
- 方案1:给字段起别名,让别名与实体类属性一致。
- 方案2:通过@Result注解手动映射封装
- 方案3:在spring的配置文件(
application.properties
)开启mybatis的驼峰命名自动映射开关 mybatis.configuration.map-underscore-to-camel-case =true
在模糊查询时使用%
来通配,需要使用单引号拼接,而使用#
的通配符,不能存在于引号中,为了继续使用#
提供的SQL预编译功能,使用concat
字符拼接方法。
XML映射文件
通过XML映射文件也可以用于配置SQL。
按照规范编写的XML文件,文件才可以被正常的定位并执行其中的SQL语句。
使用mybatis的注解,主要是完成一些简单的增删改查的功能,如果需要实现复杂的SQL功能,建议使用XML来配置SQL语句。
Mybatis动态SQL
随着用户输入或者外部条件的变化而变化的SQL语句,称为动态SQL。
编写动态SQL主要借助一些标签语句:
- < if >:用于判断条件是否成立,使用test属性进行条件判断,如果条件为true,则拼接SQL。
- < where > :where元素只会在子元素有内容的情况下才插入where子句,并且会自动取出子句的开头的and或者or。
- < set > :动态地在行首插入set关键字,并且删除额外的逗号。(用于update语句中)
- < foreach >:
- collection:遍历的集合
- item:遍历出的元素
- separator:分隔符
- open:遍历开始前拼接的SQL片段
- close:遍历结束后拼接的SQL片段
该标签主要用在需要批量操作的场景,例如下面的疲劳删除的例子:
- < sql > 和 < include >:对于大量重复使用SQL片段,可以使用< sql > 标签将高频重复标签提取处理,并设置id名,在需要使用的地方,采用< include >标签,设置refid为id名,引用替换。
Restful 风格 API
Representation State Transfer,表述性状态转换,一种软件架构风格。
使用URL定位资源,HTTP动词(请求方式)描述操作:
- 查询:Get
- 新增:Post
- 修改:Put
- 删除:Delete
properties配置文件
参数配置
在application.properties文件中设置配置信息属性值,在Java文件通过@Value
注解将外部配置文件的属性值注入。
yml配置文件
使用yml或者yaml格式的配置文件,更加简洁,层级结构更清晰。
ConfigurationProperties
使用@Value
注入配置属性较为繁琐,有没有可能简化该步骤?
通过@ConfigurationProperties
注解,将配置文件中的属性值注入到对象中。
可以在Maven中加入依赖:
案例实现 - 登录校验
服务端接收到请求时,校验是否为登录状态,如果是,则正常处理请求,如果不是,则进行拦截。
服务端对于登录校验功能的实现,一般会采用统一拦截,如果登录了,则进行标记。
会话技术
cookie
cookie:客户端会话跟踪技术,http协议支持的技术,在登录成功后,服务端通过set-cookie响应,将cookie发送给浏览器,浏览器在本地缓存cookie,后边的请求头中都携带cookie,验证登录状态。
cookie的缺点:
- 移动端APP不可使用
- 不安全,用户可以禁用cookie
- cookie不能跨域
- 跨域分为三个维度,协议、IP、端口
session
session是服务端会话跟踪技术,session存放在服务端,其底层还是基于cookie的。
session跟踪原理:
浏览器登录请求给定JSESSION,即session的id,服务端通过 set-cookie,设置该session id,并将其保存在服务端,后边浏览器发送请求时携带的cookie中查看session id与服务器保存的是否一致,即可判断是否为一次会话。
session的缺点:
因为session存放在服务器上,则服务器集群中无法使用session。
令牌(token)技术
浏览器登录成功后,服务器为客户端生成一个令牌,客户端将令牌保存,后续请求中都携带令牌,同一次会话中如果需要共享信息,就把信息保存在令牌中。
优点:
- token令牌可以保存在cookie中,也可以保存在客户端本地,因此支持PC端、移动端。
- 可以解决集群环境下的认证问题。
缺点:token令牌需要自己实现
JWT令牌
JWT(Json Web Token),json网络令牌,定义了一种简洁的】自包含的格式,用于在通信双方以json数据格式安全地传输信息,由于数字签名的存在,这些消息是可靠的。
JWT令牌主要由三部分组成,由两个点.
连接:
- header(头),记录令牌类型,签名算法
- payload(有效载荷),携带一些自定义信息,默认信息。
- signature(签名),防止token被篡改,确保安全性,将header、payload并加入指定秘钥,通过指定签名算法计算而来。
JWT本来是一个json,是怎么转变为字符串的呢?
通过base64编码,所谓base64编码是以(0-9,a-z,A-Z,+,/)共64个字符构成的一个编码方式。任何数据经过base64编码,都会转为以该64个字符组成的一串编码。
可以在下面这个网站来进行jwt令牌的base64编解码:
https://jwt.io/
基于Java代码生成JWT:
载荷部分用一个哈希表存放,构造器模式构建。
生成的JWT在过期时间内,可以由秘钥解析出来:
如果令牌过期或者被篡改,都会保错!
Filter
Filter:过滤器,把对资源的请求拦截下来,从而实现一些特殊的功能。过滤器一般完成一些通用的操作,比如:登录校验、统一编码处理、敏感字符处理等。
构建拦截的步骤:
- 定义Filter:定义Filter类实现Filter接口,重写其所有方法。
- 配置Filter:Filter类上加@WebFilter注解,配置拦截资源路径,引导类(main函数所在)加@ServletComponentScan开启Servlet组件支持。
@WebFilter注解中添加urlPatterns
属性,配置拦截的请求路径。
Filter执行流程详解
Filter接口需要我们重写三个方法:
- init:初始化,只执行一次
- doFilter:拦截请求后调用,可以调用多次,可以在这里通过执行
chain.doFilter()
放行请求。 - destroy:销毁方法,只调用一次。
过滤器链
过滤器链的执行顺序优先级是按照过滤器类名(字符串)的自然排序
登录校验Filter流程
拦截器
拦截器是与过滤器类似的机制,但拦截器是Spring框架中所提供的。
在Java中使用拦截器:
- 定义拦截器类实现HandlerInterceptor接口,重写方法。由于拦截器是Spring框架提供的,所以可以直接使用
@Component
注解来将该类交由容器管理。 - 注册拦截器:使用@Configutation注解,声明一个配置类,在这个配置类中实现
WebMvcConfigurer
接口,将上边的拦截器类使用注解AutoWired
注入,然后在addInterceptors方法中,给拦截器类添加拦截路径模式。
拦截器模式:
过滤器和拦截器区别
- 接口规范不同:过滤器实现Filter接口,拦截器实现的是HandlerInterceptor接口
- 拦截范围不同:过滤器Filter会拦截所有的资源,而拦截器只会拦截Spring环境中的资源,如果项目中同时有过滤器和拦截器,那么会优先执行过滤器Filter。
异常处理
spring框架中,如果发生异常了,层层之间都会产生影响。推荐使用全局异常处理器,统一处理异常情况。
全局异常处理器
使用@RestControllerAdvice注解。
Spring事务管理
应用案例:删除部门的同时,应该同时删除部门下的所有员工。
实现方法:采用注解@Transactional
该注解放在业务层(Service)层的方法上、类上、接口上。
作用:将当前方法交给spring进行事务管理,方法执行前,开启事务,成功执行完毕,提交事务,出现异常,回滚事务。
开启事务管理的日志配置:
事务进阶
上边的案例中,我们直接在删除的方法上使用@Transactional注解,开启一个事务。
默认情况下,只有出现运行时异常才回回滚异常,在@Transactional中指定rollbackFor
属性,就可以用于控制出现何种异常类型,回滚事务。
除了rollbackFor
属性,事务注解@Transactional还可以指定传播行为propagation
属性。
默认的事务传播行为是有事务则将方法加入到已经存在的事务,没有事务则创建新的事务。
这样会有什么问题呢?
考虑下边的需求:
因为无论事务成功或者失败,都需要操作日志,那么我们应该把操作日志的方法放入到try-catch-finally中的final中来实现。
然而,实际执行过程中,如果事务执行失败,造成回滚,会使得finally代码块中执行操作日志的方法的也回滚!
解决方法是:
将操作插入日志的方法的事务注解,指定传播方式为propagation = Propgation.REQUEST_NEW
。
这样操作日志的方法会开启新的事务,不受失败事务回滚的影响。
AOP(面向切面编程)
AOP(Aspect Oriented Programming,面向切面编程),其实就是面向特定方法编程,可以是对原来方法的增强,也可以是对原有方法的改编。
AOP面向切面编程是通过动态代理模式来实现的。
AOP核心概念
- 连接点:JoinPoint,可以被AOP控制的方法(暗含方法执行时的相关信息)
- 通知:Advice,指哪些重复的逻辑,也就是共性功能(最终体现为一个方法)
- 切入点:PointCut,匹配连接点的条件,通知仅会在切入点方法执行时被应用。通常使用切入点表达式,来匹配切入的方法。
- 切面:Aspect,描述通知与切入点的对应关系(通知 + 切入点)
- 目标对象:Target,通知所应用的对象。
AOP进阶
通知类型
切入点表达式可以通过注解@Pointcut
抽取出来。然后在需要的地方复用:
通知顺序
切入点表达式
execution
根据方法的返回值、包名、类名、方法名、方法参数等信息匹配,使用execution
切入点表达式通配符:
annotation
用于匹配标识有特定注解的方法使用annotation。
定义一个注解:
在需要通知的方法上加上这个注解:
连接点
用于获取实际运行方法的信息。
Spring
配置优先级
Sping属性配置:
Bean管理
获取Bean
实际步骤:
- 采用注入的方式(使用注解@Autowired)获取到IOC容器对象 applicationContext。
- 由applicationContext对象提供的API获取bean。
bean作用域
默认的作用域创建出的获取到的bean对象是单例的,可以使用@Scope注解,配置作用域。
第三方bean
第三方依赖也可以产生bean。需要使用@Bean注解。
SpringBoot原理
SpringBoot简化了Spring Framework,主要原理是底层提供了起步依赖和自动配置。
起步依赖的原理就是Maven的依赖传递。
自动配置原理
在spring项目的启动类会默认给启动类加上注解@ComponentScan
,扫描启动类所在包下的Component
注解,将有该注解的类添加到IOC容器中。
那么第三方库的配置类,想要实现自动装配,方案一就是,使用注解@ComponentScan
组件扫描。
但这种方案的缺点在于,每声明一个注解@ComponentScan
,就需要扫描一个包下所有的文件,使用繁琐,性能低。
方案二:采用@Import注解。
- @Import可以声明在普通类上,也可以声明在被@Configuration注解的配置类上。都可以直接导入到IOC容器中。
- 创建一个导入类,实现ImportSelecter接口,该接口提供的方法,需要我们重写,返回需要导入进IOC容器中的全类名字符串数组。
- 上边的方法,我们需要明确知道,哪些类需要被导入到IOC容器中。第三方依赖其实是最清楚,哪些类需要导入到IOC容器中的,因此,第三方依赖可以提供注解
@EnableXxxx
,里边是封装了@Import
注解的。我们在使用时,只需要在启动类处加上注解@EnableXxxx
即可。
@SpringBootConfiguration
@SpringBootConfiguration注解:
- 集成了@ComponentScan注解,因此会扫描启动类所在包以及子包中所有包含@Component注解的类。
- 集成@Configuration注解,因此,也可以在启动类为第三方依赖声明配置@Bean,它也是一个配置注解。
- 最重要的:它包含了EnableAutoConfiguration注解,该注解中实现了将spring-boot-autoconfigure包下的两份文件,以字符串列表的形式返回,而这两份文件中记录的都是需要导入进IOC容器的类的全限类名。
@Conditional
按照一定的条件进行判断,在满足给定条件后才会注册bean对象到Spring的IOC容器中。
- ConditionalOnClass:判断环境中是否有该字节码文件,有才将Bean加入到IOC容器。
- ConditionalOnMissingBean:判断环境中是否有该Bean,没有才会将bean注册到IOC容器中。一般用于默认的Bean的声明
- ConditionalOnProperty:配置文件中是否存在对应的属性和值,有才注册Bean到IOC容器中。
自定义starter
命名规范:
Spring官方提供的启动依赖包名命名时都是spring-boot-starter-功能。
其他的技术提供的启动依赖包名则会将功能命名置前:功能-spring-boot-starter
自定义starter需要完成两个包:启动依赖和自动配置,分别完成依赖管理功能和自动配置功能。
案例:自定义阿里云OSS启动器
第一步:创建两个模块,启动器和自动配置。
启动器是依赖于自动配置的:
第二步:完成阿里云OSS逻辑功能的实现。
先导入依赖,包含spring-web与阿里云oss依赖:
实现AliOSSUtills类的编写,这个类使用时需要传递配置信息。
配置信息也是需要自定义一个类对象,它的属性值通过注解@ConfigurationProperties
,引用配置文件中以“aliyun.oss”为前缀的对象属性。
第三步:构建自动配置类。
使用@EnableConfigurationProperties注解,仿照者spring的自动配置路径,创建一份配置文件,列出需要注册到容器的类名:
第四步:测试使用
测试模块只需要引入刚刚的启动器模块依赖。
在配置文件中,配置阿里云oss的配置属性:
然后在使用时就可以直接注入啦!
总结