其实这篇笔记在云笔记里记载好久了,忽然看到,分享出来帮自己复习也希望能帮到需要的人(ΦωΦ)

springboot优点:
1.快速构建项目
2.对主流开发框架的无配置集成
3.项目可独立运行,无需外部依赖Servlet容器
4.提供运行时的应用监控
5.极大的提高了开发、部署效率
6.与云计算的天然集成

启动类@SpringbootApplication 是一个组合注解,主要的注解组成有@EnableAutoConfiguration、@Configuration、@ComponentScan
@EnableAutoConfiguration:让springboot根据类路径下的jar包依赖进行自动配置
例如,添加了spring-boot-starter-web依赖,会自动添加tomcat和spring mvc 的依赖,那么springboot就会对tomcat和springmvc进行自动配置
Sptingboot会自动扫描@SpringbootApplication所在类的同级包以及下级包里的bean(若为JPA项目还可以扫描到@Entity的实体类)。建议将入口放在groupId+arctifactId的组合包名下
@Configuration:一般用来初始化配置类使用,通过@Configuration注解标注的类会在项目初始化的时候加载,也可理解为用spring的时候xml里面的标签
@ComponentScan告诉Spring 哪个packages 的用注解标识的类 会被spring自动扫描并且装入bean容器。

一、配置篇
1.配置文件:application.properties或者application.yml 在目录src/main/resources/下

2.配置读取:
如果spring启动时没有读取配置文件,需在pom.xml文件里加:

<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>

① Environment 读取

注意:Environment 不仅仅是从配置文件中获取,还要其他的一些配置信息来源(比如本机配置)

springboot聚合项目不识别子工程 springboot聚合项目的优点_加载


② @Value 读取

springboot聚合项目不识别子工程 springboot聚合项目的优点_java_02


③ 对象映射方式

springboot聚合项目不识别子工程 springboot聚合项目的优点_spring boot_03


自定义配置文件需用@PropertySource(“classpath:xxx.properties”)去读取,除yml文件

3.多环境选择

springboot聚合项目不识别子工程 springboot聚合项目的优点_加载_04


4.配置文件的优先级:

①外置,在相对于应用程序运行目录的 /config 子目录中

②外置,在应用程序运行的目录中

③内置,放在config包下(即 src/main/resources/config)目录下

④内置,放在classpath根目录下(即默认的 src/main/resources/目录下)

上面的优先级是从高到低来的,即外置的改与内置的;config下面的高于根目录下的

(即应用外的配置文件优先于应用内,config目录下的优先于根目录下的)

bootstrap.yml(bootstrap.properties)先加载

application.yml(application.properties)后加载

bootstrap.yml 用于应用程序上下文的引导阶段。

bootstrap.yml 由父Spring ApplicationContext加载。

父ApplicationContext 被加载到使用 application.yml 的之前

(是不是有点绕口,其实很好记)更改环境选择的方式:

①命令行参数

注意:命令行参数传入时,请注意写法形同 --key=value

springboot聚合项目不识别子工程 springboot聚合项目的优点_java_05

springboot聚合项目不识别子工程 springboot聚合项目的优点_spring boot_06


②外置配置文件方式4.加载自定义配置文件

指定根目录下配置文件名

springboot聚合项目不识别子工程 springboot聚合项目的优点_java_07


5.配置内引用

①random随机数

springboot聚合项目不识别子工程 springboot聚合项目的优点_java_08

springboot聚合项目不识别子工程 springboot聚合项目的优点_spring_09


②配置引用

使用 ${xxx} 来表示引用配置 xxx的值

springboot聚合项目不识别子工程 springboot聚合项目的优点_java_10


6.配置动态刷新

借助springcloud中ContextRefresher类

再使用**@RefreshScope**注解

springboot聚合项目不识别子工程 springboot聚合项目的优点_配置文件_11


使用refresh()方法即可刷新

springboot聚合项目不识别子工程 springboot聚合项目的优点_加载_12


7.配置变更监听

利用springboot的事件通知机制,配置config变更的监听

springboot聚合项目不识别子工程 springboot聚合项目的优点_加载_13

二、日志篇

日志级别:trace<debug<info<warn<error<fatal

info 一般处理业务逻辑的时候使用,就跟 system.err打印一样,用于说明此处是干什么的。slf4j使用的时候是可以动态的传参的,使用占位符 {} 。后边一次加参数,会挨个对应进去。

debug: 一般放于程序的某个关键点的地方,用于打印一个变量值或者一个方法返回的信息之类的信息

error: 用户程序报错,必须解决的时候使用此级别打印日志。

warn:警告,不会影响程序的运行,但是值得注意

fatal: 重大错误

1.debug日志支持

默认是不输出debug日志的,如果需要,则需要在配置文件中添加 debug=true 属性;同样可以设置trace=true,就可以看应用输出的trace日志

2.log levels

springboot聚合项目不识别子工程 springboot聚合项目的优点_加载_14


3.输出格式

logging.pattern.cnotallow=%date{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n

效果如下:

springboot聚合项目不识别子工程 springboot聚合项目的优点_spring boot_15


4.输出文件

springboot聚合项目不识别子工程 springboot聚合项目的优点_spring boot_16


5.logback配置

①appender标签

a.class属性选择输出的地方

springboot聚合项目不识别子工程 springboot聚合项目的优点_spring_17


b.输出格式:

如:%d [%t] %-5level %logger{36}.%M(%file:%line) - %msg%n

%m输出的信息,

%p日志级别,

%t线程名,

%d日期,

%c类的全名,

%i索引【从数字0开始递增】

%M方法名

%lines输出日志的行数

%F/%file源码文件名

c.日志归档:

springboot聚合项目不识别子工程 springboot聚合项目的优点_java_18


②logger标签

springboot聚合项目不识别子工程 springboot聚合项目的优点_spring boot_19


三、bean篇

1.自定义bean的加载条件:

通过@Conditional注解配合Condition接口,来决定给一个bean是否创建和注册到Spring容器中,从而实现有选择的加载bean

springboot聚合项目不识别子工程 springboot聚合项目的优点_java_20


满足条件则加载bean

springboot聚合项目不识别子工程 springboot聚合项目的优点_配置文件_21


也可加在类上

springboot聚合项目不识别子工程 springboot聚合项目的优点_java_22


使用注解不需自己实现Condition接口

springboot聚合项目不识别子工程 springboot聚合项目的优点_java_23


@ConditionalOnBean注解属性:

value:bean类型

type:bean类型

annotation:要求bean上拥有指定的注解

name:bean名称

@ConditionalOnProperty

prefix:配置前缀

havingValue:要求配置存在,且包含某个值

name:配置名

matchIfMissing:即便没有配置,也依然创建(true时)2.多实例选择

springboot聚合项目不识别子工程 springboot聚合项目的优点_java_24


存在@Primary注解时:

@Resource注解指定name时,根据name来查找对应的bean

@Autowired注解,全部都用@Primary标识的注解

@Primary注解要求唯一(一个接口的子类中,只能有一个实现上有这个注解)

不存在@Primary注解时:

@Resource注解指定name时,根据name来查找对应的bean

@Autowired注解时,根据属性名去查对应的Bean,如果查不到则抛异常;如果查到,那即是它了

3.同名bean的两种解决方式:

①指定其中一个bean的名称

②排除掉其中一个同名bean的自动加载四、AOP篇

1.基本概念:

① advice

before: 在方法执行之前被调用

after: 在方法执行之后调用

after returning: 方法执行成功之后

after throwing: 方法抛出异常之后

around: 环绕,自己在内部决定方法的执行时机,因此可以在之前之后做一些业务逻辑

② joint point

连接点,比如方法调用,方法执行,字段设置/获取、异常处理执行、类初始化、甚至是 for 循环中的某个点

但 Spring AOP 目前仅支持方法执行 (method execution),PointCut就是那个被拦截的方法

③ pointcut

切点,用来描述满足什么规则的方法会被拦截

④ aspect

切面是切点和通知的结合。通知和切点共同定义了关于切面的全部内容,它是什么时候,在何时和何处完成功能

⑤ introduction

引入允许我们向现有的类添加新的方法或者属性

⑥ weaving

生成一个代理类,在调用被拦截的方法时,实际上执行的是代理类,这个代理类内部执行切面逻辑

一个方法执行时,只要满足条件,多个相同或不同类型的advice都可以拦截

2.基本使用:

springboot聚合项目不识别子工程 springboot聚合项目的优点_配置文件_25


3.注解拦截方式

springboot聚合项目不识别子工程 springboot聚合项目的优点_java_26


相同类型可都拦截

springboot聚合项目不识别子工程 springboot聚合项目的优点_配置文件_27

springboot聚合项目不识别子工程 springboot聚合项目的优点_spring_28


4.嵌套拦截

① 如果有切面的方法被没切面的方法调用,那他将不被拦截

springboot聚合项目不识别子工程 springboot聚合项目的优点_加载_29


②调用本类中,满足被拦截的方法,也不会走切面逻辑;调用其他类中的满足切面拦截的方法,会走切面逻辑

springboot聚合项目不识别子工程 springboot聚合项目的优点_java_30


③如果调用的方法上加了拦截的注解,则内部调用的方法全被正常拦截

springboot聚合项目不识别子工程 springboot聚合项目的优点_加载_31


小结:

a.执行的目标方法,如果调用了本类中一个满足切面规则的方法A时,在执行方法A的过程中,不会触发切面逻辑

b.执行的目标方法,如果调用其他类中一个满足切面规则的方法B时,在执行方法B的过程中,将会触发切面逻辑

5.AOP拦截方法的作用域

内部调用不走切面逻辑,所有private修饰符不可用

public, protected, default 作用域的方法都可以被拦截

6.AOP优先级

①同一切面,不同类型ddvice优先级

springboot聚合项目不识别子工程 springboot聚合项目的优点_加载_32


② 同一切面,同一类型切面

如定义了三个@Before切面,输出顺序是根据方法名决定

springboot聚合项目不识别子工程 springboot聚合项目的优点_加载_33


Order注解尝试

测试结果并未改变优先级

springboot聚合项目不识别子工程 springboot聚合项目的优点_配置文件_34


springboot聚合项目不识别子工程 springboot聚合项目的优点_加载_35


③不同切面,相同类型的advice

A切面中的advice会优先B切面中同类型的advice

可以通过 Order 注解来解决不同切面的优先级问题,依然是值越小,优先级越高

④不同切面,不同advice顺序

优先级高的切面中的advice执行顺序会呈现包围优先级低的advice的情况

五、JdbcTemplate篇
两种sql传参方式:
一个是写完整的sql语句,问题是存在注入的风险
其次是使用占位符(?), 实际的值通过参数方式传入

1.查询:

单条查询:

①queryForMap 返回一条记录,返回的结果塞入Map<String, Object>, key为固定的String对应查询的列名;value为实际值

②queryForObject 同样返回一条数据,与上面的区别在于可以借助RowMapper来实现返回结果转换为对应的POJO

springboot聚合项目不识别子工程 springboot聚合项目的优点_spring boot_36



springboot聚合项目不识别子工程 springboot聚合项目的优点_spring_37


注意:上面的查询,必须有一条记录返回,如果查不到,则抛异常

批量查询:

queryForList :一次查询>=0条数据,返回类型为 List<Map<String, Object>>

queryForRowSet:返回SqlRowSet对象,需要遍历获取所有的结果

query:

①提供三种结果处理方式:

a.不返回结果的回调姿势

b.对结果批量处理的方式 ResultSetExtractor

c.对结果单个迭代处理方式 RowMapper

②可以返回>=0条数据

③如果需要对查询的连接参数进行设置,使用PreparedStatementCreator来创建PreparedStatement方式处理2.新增:

update(sql)

update(sql, param1, param2…)

update(sql, new PreparedStatementCreator(){})

update(new PreparedStatementSetter(){})

update(new PreparedStatementCreator(){}, new GeneratedKeyHolder())

插入并返回主键:

springboot聚合项目不识别子工程 springboot聚合项目的优点_spring_38


六、Feign篇

关于springCloud的有关整理还没做好,所以先把feign的放这:

启动类加@EnableFeignClients

Feign的源码实现的过程如下:

1.首先通过@EnableFeignCleints注解开启FeignCleint

2.根据Feign的规则实现接口,并加@FeignCleint注解

3.程序启动后,会进行包扫描,扫描所有的@ FeignCleint的注解的类,并将这些信息注入到ioc容器中。

4.当接口的方法被调用,通过jdk的代理,来生成具体的RequesTemplate

5.RequesTemplate在生成Request

6.Request交给Client去处理,其中Client可以是HttpUrlConnection、HttpClient也可以是Okhttp

7.最后Client被封装到LoadBalanceClient类,这个类结合类Ribbon做到了负载均衡。

有个坑点:feign调用接口传递LocalDateTime值时会自动转化为上午下午的时间,无法解析(放在对象中传递无此问题)