lambada表达式和sprignboot

This commit is contained in:
法然
2022-11-14 15:47:13 +08:00
parent 845c285931
commit 1adf3c2cb6
20 changed files with 1590 additions and 187 deletions

View File

@@ -1,21 +1,20 @@
## 1 简介
### 日志组件
logback是一个开源的日志组件是log4j的作者开发的用来替代log4j的。logback由三个部分组成logback-core, logback-classic, logback-access。
* 其中logback-core是其他两个模块的基础。
* logback-classic它是log4j的一个改良版本同时它完整实现了slf4j API使我们可以在其他日志系统如log4j和JDK14 Logging中进行转换
* logback-access访问模块和Servlet容器集成提供通过Http来访问日志的功能
logback 是一个开源的日志组件,是 log4j 的作者开发的用来替代 log4j 的。logback 由三个部分组成logback-core, logback-classic, logback-access。
- 其中 logback-core 是其他两个模块的基础。
- logback-classic它是 log4j 的一个改良版本,同时它完整实现了 slf4j API使我们可以在其他日志系统如 log4j 和 JDK14 Logging 中进行转换
- logback-access访问模块和 Servlet 容器集成,提供通过 Http 来访问日志的功能
### 日志级别
级别包括TRACE < DEBUG < INFO < WARN < ERROR
### 配置流程
1. 添加maven依赖
1. 添加 maven 依赖
2. 查找配置文件。logback-spring.xml、logback.xml、BasicConfigurator。
3. 加载配置内容。configuration
@@ -25,7 +24,7 @@ logback是一个开源的日志组件是log4j的作者开发的用来替代lo
</configuration>
```
### maven依赖
### maven 依赖
```xml
<!--log-->
@@ -47,35 +46,31 @@ logback是一个开源的日志组件是log4j的作者开发的用来替代lo
</dependency>
```
## 2 配置内容
### configuration
日志配置的根节点
```
<configuration></configuration>
```
### contextName
<contextName>是<configuration>的子节点。各个logger都被关联到一个loggerContext中loggerContext负责制造logger也负责以树结构排列个logger。
<contextName>是<configuration>的子节点。各个 logger 都被关联到一个 loggerContext loggerContext 负责制造 logger也负责以树结构排列个 logger。
```
<contextName>atguiguSrb</contextName>
```
### property
<property>是<configuration>的子节点,用来定义变量。
<property> 有两个属性namevaluename的值是变量的名称value是变量的值。
通过<property>定义的值会被插入到logger上下文中。定义变量后可以使“${}”来使用变量。
<property> 有两个属性namevaluename 的值是变量的名称value 是变量的值。
通过<property>定义的值会被插入到 logger 上下文中。定义变量后,可以使“${}”来使用变量。
```xml
<!-- 日志的输出目录 -->
@@ -100,16 +95,17 @@ logback是一个开源的日志组件是log4j的作者开发的用来替代lo
```
### appender
`<appender>``<configuration>`的子节点,是负责写日志的组件.主要用于指定日志输出的目的地目的地可以是控制台、文件、远程套接字服务器、MySQL、PostreSQL、Oracle和其他数据库、JMS和远程UNIX Syslog守护进程等。
不同的appender有不同的属性可以配置
`<appender>``<configuration>`的子节点,是负责写日志的组件.主要用于指定日志输出的目的地目的地可以是控制台、文件、远程套接字服务器、MySQL、PostreSQL、Oracle 和其他数据库、JMS 和远程 UNIX Syslog 守护进程等。
不同的 appender 有不同的属性可以配置
### ConsoleAppender
* `<appender>`有两个必要属性name和classname指定appender名称class指定appender的全限定名
* `<encoder>`对日志进行格式化
* `<pattern>`定义日志的具体输出格式
* `<charset>`编码方
- `<appender>`有两个必要属性 name 和 classname 指定 appender 名称class 指定 appender 的全限定名
- `<encoder>`对日志进行格式
- `<pattern>`定义日志的具体输出格
- `<charset>`编码方式
```xml
<!-- 控制台日志 -->
@@ -120,12 +116,20 @@ logback是一个开源的日志组件是log4j的作者开发的用来替代lo
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>${ENCODING}</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>${logging.level}</level>
</filter>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>DENY</onMatch>
</filter>
</appender>
```
输出模式说明
* 输出模式:%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%msg%n
* 输出模式解释:时间日期格式-调用的线程-日志界别-调用对象-日志信息-换行
- 输出模式%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%msg%n
- 输出模式解释:时间日期格式-调用的线程-日志界别-调用对象-日志信息-换行
```
%d{HH:mm:ss.SSS}日志输出时间red
@@ -136,10 +140,14 @@ logback是一个开源的日志组件是log4j的作者开发的用来替代lo
%n平台的换行符
```
过滤器说明
* filter可以过滤指定级别的日志进行打印
### FileAppender
* `<file>`表示日志文件的位置,如果上级目录不存在会自动创建,没有默认值。\
* `<append>`默认 true日志被追加到文件结尾如果是 false服务重启后清空现存文件。
- `<file>`表示日志文件的位置,如果上级目录不存在会自动创建,没有默认值。\
- `<append>`默认 true日志被追加到文件结尾如果是 false服务重启后清空现存文件。
```xml
<!-- 文件日志 -->
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
@@ -153,14 +161,15 @@ logback是一个开源的日志组件是log4j的作者开发的用来替代lo
```
### RollingFileAppender
表示滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将旧日志备份到其他文件
* `<rollingPolicy>``<appender>`的子节点,用来定义滚动策略。
- `<rollingPolicy>``<appender>`的子节点,用来定义滚动策略。
* TimeBasedRollingPolicy最常用的滚动策略根据时间来制定滚动策略。
- TimeBasedRollingPolicy最常用的滚动策略根据时间来制定滚动策略。
* `<fileNamePattern>`:包含文件名及转换符, “%d”可以包含指定的时间格式%d{yyyy-MM-dd}。如果直接使用 %d默认格式是 yyyy-MM-dd。
* `<maxHistory>`:可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件。假设设置每个月滚动,且`<maxHistory>`是6则只保存最近6个月的文件,删除之前的旧文件。注意,删除旧文件是,那些为了归档而创建的目录也会被删除。
- `<fileNamePattern>`:包含文件名及转换符, “%d”可以包含指定的时间格式%d{yyyy-MM-dd}。如果直接使用 %d默认格式是 yyyy-MM-dd。
- `<maxHistory>`:可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件。假设设置每个月滚动,且`<maxHistory>` 6则只保存最近 6 个月的文件,删除之前的旧文件。注意,删除旧文件是,那些为了归档而创建的目录也会被删除。
```xml
<appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
@@ -178,21 +187,92 @@ logback是一个开源的日志组件是log4j的作者开发的用来替代lo
<maxHistory>15</maxHistory>
</rollingPolicy>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${log_path}/userlog-%d{yyyyMMddHHmm}-%i.log</fileNamePattern>
<maxFileSize>300KB</maxFileSize>
<maxHistory>60</maxHistory>
</rollingPolicy>
</appender>
```
* 放在`<rollingPolicy>`的子节点的位置,基于实践策略的触发滚动策略`<maxFileSize>`设置触发滚动条件单个文件大于100M时生成新的文件
- 放在`<rollingPolicy>`的子节点的位置,基于实践策略的触发滚动策略`<maxFileSize>`设置触发滚动条件:单个文件大于 100M 时生成新的文件
### AsyncAppender
```
<appender name="async" class="ch.qos.logback.classic.AsyncAppender">
<!--指定某个具体的Appender实现-->
<appender-ref ref="rolling"/>
</appender>
```
### SiftingAppender
之前在介绍常用appender时已经记录过了SiftingAppender可用于根据给定的运行时属性来分离(或筛选)日志记录。
比如可以按照业务功能生成独立的日志文件、按照用户会话id为每个用户生成独立的日志文件等。
按照业务功能生成独立的日志文件
上面我们通过为每个业务类配置<logger>的方式实现了按照业务功能生成独立的日志文件下面我们使用SiftingAppender来实现此功能代码如下
修改下UserService
```java
@Service
public class UserService {
private static final Logger logger = LoggerFactory.getLogger(UserService.class);
public void testLogger() throws InterruptedException {
for (int i = 0; i < 10; i++) {
Thread.sleep(2);
MDC.put("logKey","userLog"); // logKey设置值后在logback.xml中使用
logger.info("user logger!" + i);
}
}
```
```xml
<property name="log_path" value="D:/logs"/>
<appender name="SIFTING" class="ch.qos.logback.classic.sift.SiftingAppender">
<discriminator>
<key>logKey</key> <!-- logKey对应 MDC 中设置的值 -->
<defaultValue>general</defaultValue><!-- 设置的默认值 -->
</discriminator>
<sift>
<appender name="FILE-${logKey}"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- ${logKey}取出 MDC 中设置的值 -->
<file>${log_path}/db/${logKey}.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log_path}/db/${logKey}.%d{yyyyMMddHHmm}.log</fileNamePattern>
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%msg%n</pattern>
</encoder>
</appender>
</sift>
</appender>
<root level="DEBUG">
<appender-ref ref="SIFTING" />
</root>
```
### logger
`<logger>`可以是`<configuration>`的子节点,用来设置日志打印级别、指定`<appender>`
- name用来指定受此 logger 约束的某一个包或者具体的某一个.
- level用来设置打印级别大小写无关TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF。默认继承上级的级别。logger 日志级别。级别包括TRACE < DEBUG < INFO < WARN < ERROR定义于 ch.qos.logback.classic.Level 类中。
- `<logger>`可以包含零个或多个`<appender-ref>`元素,标识这个 appender 将会添加到这个 logger
* name用来指定受此logger约束的某一个包或者具体的某一个.
* level用来设置打印级别大小写无关TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF。默认继承上级的级别
* logger日志级别。级别包括TRACE < DEBUG < INFO < WARN < ERROR定义于ch.qos.logback.classic.Level类中。如果logger没有被分配级别name它将从有被分配级别的最近的父类那里继承级别root logger默认级别是DEBUG。
* `<logger>`可以包含零个或多个`<appender-ref>`元素标识这个appender将会添加到这个logger
logger继承问题
* 根据name进行继承。name=com.ykl 继承了name=com继承了root
* 继承上级日志级别。logger 没有被分配级别name 它将从有被分配级别的最近的父类那里继承级别root logger 默认级别是 DEBUG。
* 向上传递日志信息。类似于拦截器拦截到消息后是否会放回additivity="false"表示不放回。additivity="true"表示放回。root能够截取所有的消息。
```xml
<!-- 日志记录器 -->
@@ -202,7 +282,23 @@ logback是一个开源的日志组件是log4j的作者开发的用来替代lo
</logger>
```
* logger的取得通过org.slf4j.LoggerFactorygetLogger()方法取得。getLogger(Class obj)方式是通过传入一个类的形式来进行logger对象和类的绑定getLogger(String name)方式是通过传入一个contextName的形式来指定一个logger用同一个名字调用该方法获取的永远都是同一个logger对象的引用。
- logger 的取得:通过 org.slf4j.LoggerFactorygetLogger()方法取得。getLogger(Class obj)方式是通过传入一个类的形式来进行 logger 对象和类的绑定getLogger(String name)方式是通过传入一个 contextName 的形式来指定一个 logger用同一个名字调用该方法获取的永远都是同一个 logger 对象的引用。
### root
配置默认的日志打印
也是<loger>元素但是它是根loger。只有一个level属性应为已经被命名为"root".
level:用来设置打印级别大小写无关TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF不能设置为INHERITED或者同义词NULL。默认是DEBUG。
* 没有设置addtivity默认为true将此loger的打印信息向上级传递
```xml
<root level="ALL">
<appender-ref ref="async"></appender-ref>
</root>
```
## 3 配置文件
### 配置文件实例
@@ -424,4 +520,4 @@ logback是一个开源的日志组件是log4j的作者开发的用来替代lo
<appender-ref ref="consoleAppender" />
</root>
</configuration>
```
```

View File

@@ -6,17 +6,21 @@
- [原理](#原理)
- [2 注解使用](#2-注解使用)
- [注解的实现原理](#注解的实现原理)
- [元注解](#元注解)
- [注解的使用步骤](#注解的使用步骤)
- [属性的数据类型及特别的属性value和数组](#属性的数据类型及特别的属性value和数组)
- [总结](#总结)
- [3 JDK中的标准注解](#3-jdk中的标准注解)
- [3 注解](#3-注解)
- [@Target](#target)
- [@Retention](#retention)
- [@Documented](#documented)
- [@Inherited](#inherited)
- [4 JDK中的标准注解](#4-jdk中的标准注解)
- [@Override](#override)
- [@Deprecated](#deprecated)
- [@SuppressWarnings](#suppresswarnings)
- [@SafeVarargs](#safevarargs)
- [@FunctionalInterface](#functionalinterface)
- [4 Spring框架下一个注解的实现](#4-spring框架下一个注解的实现)
- [5 Spring框架下一个注解的实现](#5-spring框架下一个注解的实现)
- [登录校验——定义注解](#登录校验定义注解)
- [登录校验——使用注解](#登录校验使用注解)
- [登录校验——实现注解](#登录校验实现注解)
@@ -121,16 +125,6 @@ public @interface MyAnnotation{
### 元注解
加在注解上的注解。
* @Documented:用于制作文档
* @Target:加在注解上,限定该注解的使用位置。`@Target(ElementType.Field,ElementType.Method)`。它指明了它所修饰的注解使用的范围 如果自定义的注解为含有@Target元注解修饰,那么默认可以是在(除类型参数之外的)任何项之上使用,若有@Target元注解修饰那么根据ValueElementType枚举常量的指定的目标进行规定。
* @Retention:注解的保留策略`@Retention(RetentionPolicy.CLASS/RetentionPolicy.RUNTIME/RetentionPolicy.SOURCE)`。分别对应java编译执行过程的三个阶段。源代码阶段.java-->编译后的字节码阶段.class-->JVM运行时阶段.
* 一般来说普通开发者使用注解的时机都是运行时比如反射读取注解也有类似Lombok这类编译期注解。既然反射是运行时调用那就要求注解的信息必须保留到虚拟机将.class文件加载到内存为止。如果你需要反射读取注解却把保留策略设置为RetentionPolicy.SOURCE、RetentionPolicy.CLASS
* @Inherited被该元注解修饰的自定义注解再使用后会自动继承如果使用了该自定义注解去修饰一个class那么这个注解也会作用于该class的子类。就是说如果某个类使用了被@Inherited修饰的注解,则其子类将会自动具有该注释。@Inherited annotation类型是被标注过的class的子类所继承。类并不从它所实现的接口继承annotation方法并不从它所重载的方法继承annotation。
### 注解的使用步骤
@@ -276,7 +270,38 @@ public class Demo {
![](image/2022-07-12-10-04-38.png)
## 3 JDK中的标准注解
## 3 注解
加在注解上的注解。
### @Target
加在注解上,限定该注解的使用位置,它指明了它所修饰的注解使用的范围。@Target元注解修饰那么根据ValueElementType枚举常量的指定的目标进行规定。
* @Target(ElementType.TYPE) //接口、类、枚举
* @Target(ElementType.FIELD) //字段、枚举的常量
* @Target(ElementType.METHOD) //方法
* @Target(ElementType.PARAMETER) //方法参数
* @Target(ElementType.CONSTRUCTOR) //构造函数
* @Target(ElementType.LOCAL_VARIABLE)//局部变量
* @Target(ElementType.ANNOTATION_TYPE)//注解
* @Target(ElementType.PACKAGE) ///包
### @Retention
注解的保留策略`@Retention(RetentionPolicy.CLASS/RetentionPolicy.RUNTIME/RetentionPolicy.SOURCE)`。分别对应java编译执行过程的三个阶段。源代码阶段.java-->编译后的字节码阶段.class-->JVM运行时阶段.
* 一般来说普通开发者使用注解的时机都是运行时比如反射读取注解也有类似Lombok这类编译期注解。既然反射是运行时调用那就要求注解的信息必须保留到虚拟机将.class文件加载到内存为止。如果你需要反射读取注解却把保留策略设置为RetentionPolicy.SOURCE、RetentionPolicy.CLASS
### @Documented
用于制作文档
### @Inherited
被该元注解修饰的自定义注解再使用后会自动继承如果使用了该自定义注解去修饰一个class那么这个注解也会作用于该class的子类。就是说如果某个类使用了被@Inherited修饰的注解,则其子类将会自动具有该注释。@Inherited annotation类型是被标注过的class的子类所继承。类并不从它所实现的接口继承annotation方法并不从它所重载的方法继承annotation。
## 4 JDK中的标准注解
### @Override
@@ -336,7 +361,7 @@ public class Demo {
@FunctionalInterface作用就是用来指定某一个接口必须是函数式接口的,所以@FunctionalInterface只能修饰接口
## 4 Spring框架下一个注解的实现
## 5 Spring框架下一个注解的实现
> 定义注解、使用注解、实现注解。和定义接口、使用接口、实现接口。与OpenApi中定义服务、使用服务、实现服务。具有相同的含义。

View File

@@ -0,0 +1,387 @@
## lambda表达式概述
### 简介
lambda运行将函数作为一个方法的参数也就是函数作为参数传递到方法中。使用lambda表达式可以让代码更加简洁。
Lambda表达式的使用场景用以简化接口实现。
### 接口实现
* 设计接口的实现类
```
Interface B{}
Class A implements B{
}
new A();
```
* 使用匿名内部类
```
//直接创建匿名内部类。
Interface B{}
new B(){
}
```
* lambda表达式
```
//使用lambda表达式实现接口
Interface B{}
Test test = () -> {
System.out.println("test");
};
test.test();
```
### 注意事项
这⾥类似于局部内部类、匿名内部类,依然存在闭包的问题。
如果在lambda表达式中使用到了局部变量那么这个局部变量会被隐式的声明为 final。是⼀个常量不能修改值。
## 2 函数式接口
### 函数式接口
lambda表达式只能实现函数式接口。
函数式接口:如果说,⼀个接口中,要求实现类必须实现的抽象方法,有且只有⼀个!
```java
//有且只有一个实现类必须要实现的抽象方法,所以是函数式接口
interface Test{
public void test();
}
```
lambda表达式毕竟只是⼀个匿名方法。当实现的接口中的方法过多或者多少的时候lambda表达式都是不适用的。
### @FunctionalInterface
* 编译时检查的注解。
是⼀个注解,用在接口之前,判断这个接口是否是⼀个函数式接口。 如果是函数式接口,没有任何问题。如果不是函数式接口,则会报错。功能类似于 @Override
```java
@FunctionalInterface
interface Test{
public void test();
}
```
## 3 Lambda表达式的语法
使用lambda表带是实现一个函数式接口
### 基础语法
不需要关注参数类型或者返回值类型。
```java
(参数1,参数2,) -> {
方法体
};
```
* 参数部分:方法的参数列表,要求和实现的接口中的方法参数部分⼀致,包括参数的数量和类型。
* 方法体部分 方法的实现部分,如果接口中定义的方法有返回值,则在实现的时候,注意返回值的返回。
* -> : 分隔参数部分和方法体部分。
```
// 1. 不需要参数,返回值为 2
() -> 2
// 2. 接收一个参数(数字类型),返回其2倍的值
x -> 2 * x
// 3. 接受2个参数(数字),并返回他们的和
(x, y) -> x + y
// 4. 接收2个int型整数,返回他们的乘积
(int x, int y) -> x * y//可以加类型
// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)
(String s) -> System.out.print(s)
```
```java
package test;
/**
* @author: Mercury
* Date: 2022/3/20
* Time: 17:48
* Description:Lambda表达式
* Version:1.0
*/
public class Test04 {
public static void main(String[] args) {
//使用lambda表达式实现接口
//有参+返回值
Test test = (name,age) -> {
System.out.println(name+age+"岁了!");
return age + 1;
};
int age = test.test("小新",18);
System.out.println(age);
}
}
//有参 有返回值
interface Test{
public int test(String name,int age);
}
```
### 语法进阶
1. 参数的类型可以省略不写。由于在接口的方法中已经定义了每⼀个参数的类型是什么。而且在使用lambda表达式实现接口的时候必须要保证参数的数量和类 型需要和接口中的方法保持⼀致。要省略, 每⼀个参数的类型都必须省略不写。绝对不能出现,有的参数类型省略了,有的参数类型没有省略。
```java
//有参+返回值
Test test = (name,age) -> {
System.out.println(name+age+"岁了!");
return age + 1;
};
int age = test.test("小新",18);
System.out.println(age);
```
2. 参数的小括号可以省略不写。如果方法的参数列表中的参数数量 有且只有⼀个,此时,参数列表的小括号是可以省略不写的。
```java
//一个参数
Test test = name -> {
System.out.println(name+"test");
};
test.test("小新");
```
3. return可以省略不写。如果⼀个方法中唯⼀的⼀条语句是⼀个返回语句 此时在省略掉大括号的同时, 也必须省略掉return。
```java
Test test = (a,b) -> a+b;
```
## 4 函数引用
### 函数引用的概念
lambda表达式是为了简化接口的实现的。在lambda表达式中不应该出现比较复杂的逻辑。如果在lambda表达式中出现了过于复杂的逻辑会对程序的可读性造成非常大的影响。如果在lambda表达式中需要处理的逻辑比较复杂⼀般情况会单独的写⼀个方法。在lambda表达式中直接引用这个方法即可
函数引用引用⼀个已经存在的方法使其替代lambda表达式完成接口的实现
### 静态方法的引用
```
类::静态方法
```
* 引用方法后面,不要添加小括号。
* 引用方法、参数和返回值,必须要跟接口中定义的一致。
```java
package test;
/**
* @author: Mercury
* Date: 2022/3/20
* Time: 18:17
* Description:lambda表达式静态方法引用
* Version:1.0
*/
public class Test05 {
public static void main(String[] args) {
//实现多个参数,一个返回值的接口
//对一个静态方法的引用,语法:类::静态方法
Test1 test1 = Calculator::calculate;
System.out.println(test1.test(4,5));
}
}
class Calculator{
public static int calculate(int a,int b ){
// 稍微复杂的逻辑计算a和b的差值的绝对值
if (a > b) {
return a - b;
}
return b - a;
}
}
interface Test1{
int test(int a,int b);
}
```
### 非静态方法的引用
```
对象::非静态方法
```
* 在引用的方法后⾯,不要添加小括号。
* 引用的这个方法, 参数(数量、类型) 和 返回值, 必须要跟接口中定义的⼀致。
```
package test;
/**
* @author: Mercury
* Date: 2022/3/21
* Time: 8:14
* Description:lambda表达式对非静态方法的引用
* Version:1.0
*/
public class Test06 {
public static void main(String[] args) {
//对非静态方法的引用,需要使用对象来完成
Test2 test2 = new Calculator()::calculate;
System.out.println(test2.calculate(2, 3));
}
private static class Calculator{
public int calculate(int a, int b) {
return a > b ? a - b : b - a;
}
}
}
interface Test2{
int calculate(int a,int b);
}
```
### 构造方法的引用
使用场景
如果某⼀个函数式接口中定义的方法,仅仅是为了得到⼀个类的对象。此时我们就可以使用构造方法的引用,简化这个方法的实现。
```
语法:类名::new
```
注意事项:可以通过接口中的方法的参数, 区分引用不同的构造方法。
```java
package com.cq.test;
/**
* @author: Mercury
* Date: 2022/4/27
* Time: 10:31
* Description:lambda构造方法的引用
* Version:1.0
*/
public class Test {
private static class Dog{
String name;
int age;
//无参构造
public Dog(){
System.out.println("一个Dog对象通过无参构造被实例化了");
}
//有参构造
public Dog(String name,int age){
System.out.println("一个Dog对象通过有参构造被实例化了");
this.name = name;
this.age = age;
}
}
//定义一个函数式接口,用以获取无参的对象
@FunctionalInterface
private interface GetDog{
//若此方法仅仅是为了获得一个Dog对象而且通过无参构造去获取一个Dog对象作为返回值
Dog test();
}
//定义一个函数式接口,用以获取有参的对象
@FunctionalInterface
private interface GetDogWithParameter{
//若此方法仅仅是为了获得一个Dog对象而且通过有参构造去获取一个Dog对象作为返回值
Dog test(String name,int age);
}
// 测试
public static void main(String[] args) {
//lambda表达式实现接口
GetDog lm = Dog::new; //引用到Dog类中的无参构造方法获取到一个Dog对象
Dog dog = lm.test();
System.out.println("修狗的名字:"+dog.name+" 修狗的年龄:"+dog.age); //修狗的名字null 修狗的年龄0
GetDogWithParameter lm2 = Dog::new;//引用到Dog类中的有参构造来获取一个Dog对象
Dog dog1 = lm2.test("萨摩耶",2);
System.out.println("修狗的名字:"+dog1.name+" 修狗的年龄:"+dog1.age);//修狗的名字:萨摩耶 修狗的年龄2
}
}
```
## 4 集合中的使用
### forEach( )方法演示:
```java
public static void main(String[] args) {
ArrayList<String>list=new ArrayList<>();
list.add("a");
list.add("bc");
list.add("def");
list.add("hello");
//写法1不用Lambda表达式
list.forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
//写法2用Lambda表达式
list.forEach(s-> System.out.println(s));
//效果和写法1一样
}
```
### sort()方法的演示
```java
public static void main(String[] args) {
ArrayList<String>list=new ArrayList<>();
list.add("hh");
list.add("hi");
list.add("def");
list.add("abc");
//写法1不用Lambda表达式
list.sort(new Comparator<String>() {
@Override
public int compare(String o1,String o2) {
return o1.compareTo(o2);
}
});
list.forEach(s-> System.out.println(s));
System.out.println("======分割线======");
//写法2用Lambda表达式
list.sort(((o1, o2) -> o1.compareTo(o2)));
//效果和写法1一样
list.forEach(s-> System.out.println(s));
}//Lambda表达式可以大大缩短代码量但是相应的可读性比较差
```
### HashMap 的 forEach()
```
public static void main(String[] args) {
HashMap<Integer,String>map=new HashMap<>();
map.put(1,"hello");
map.put(2,"I");
map.put(3,"love");
map.put(4,"china");
//法一不用Lambda
map.forEach(new BiConsumer<Integer, String>() {
@Override
public void accept(Integer integer, String s) {
System.out.println("key:"+integer+"value:"+s);
}
});
System.out.println("======分割线======");
//法二用Lambda
map.forEach((key,value)-> System.out.println("key:"+key+"value:"+value));
}
```

View File

@@ -246,7 +246,7 @@ public class Bootstrap {
## 5 自动配置原理
### maven继承关系
* 在parent中管理版本信息
```xml
依赖管理
<parent>

View File

@@ -1,23 +1,14 @@
## 1 配置基础
## 1 properties配置基础
### 默认配置文件
### properties默认配置文件
用于配置容器端口名、数据库链接信息、日志级别。pom是项目编程的配置properties是软件部署的配置。
移除特殊字符、全小写。在环境变量中通过小写转换与.替换_来映射配置文件中的内容比如环境变量SPRING_JPA_DATABASEPLATFORM=mysql的配置会产生与在配置文件中设置spring.jpa.databaseplatform=mysql一样的效果。
```
src/main/resources/application.properties
```
### yaml配置文件实例
```
environments:
dev:
url: http://dev.bar.com
name: Developer Setup
prod:
url: http://foo.bar.com
name: My Cool App
```
### 等价的properties配置文件
```
environments.dev.url=http://dev.bar.com
environments.dev.name=Developer Setup
@@ -25,91 +16,11 @@ environments.prod.url=http://foo.bar.com
environments.prod.name=My Cool App
```
### yaml的自定义参数
* 定义自定义的参数
```
book.name=SpringCloudInAction
book.author=ZhaiYongchao
```
* 通过占位符的方式加载自定义的参数
```
@Component
public class Book {
@Value("${book.name}")
private String name;
@Value("${book.author}")
private String author;
// 省略getter和setter
}
```
* 通过SpEL表达式加载自定义参数
'''
#{...}
'''
### 使用随机数配置
${random}的配置方式主要有一下几种,读者可作为参考使用。
```
# 随机字符串
com.didispace.blog.value=${random.value}
# 随机int
com.didispace.blog.number=${random.int}
# 随机long
com.didispace.blog.bignumber=${random.long}
# 10以内的随机数
com.didispace.blog.test1=${random.int(10)}
# 10-20的随机数
com.didispace.blog.test2=${random.int[10,20]}
```
### 通过命令行配置
在启动java应用是添加配置参数
```
java -jar xxx.jar --server.port=8888
```
## 2 多环境配置
### 配置方法
对于多环境的配置,各种项目构建工具或是框架的基本思路是一致的,通过配置多份不同环境的配置文件,再通过打包命令指定需要打包的内容之后进行区分打包。
在Spring Boot中多环境配置文件名需要满足application-{profile}.properties的格式其中{profile}对应你的环境标识,比如:
* application-dev.properties开发环境
* application-test.properties测试环境
* application-prod.properties生产环境
### 配置加载顺序
1. 命令行中传入的参数。
1. SPRING_APPLICATION_JSON中的属性。SPRING_APPLICATION_JSON是以JSON格式配置在系统环境变量中的内容。
1. java:comp/env中的JNDI属性。
1. Java的系统属性可以通过System.getProperties()获得的内容。
1. 操作系统的环境变量
1. 通过random.*配置的随机属性
1. 位于当前应用jar包之外针对不同{profile}环境的配置文件内容例如application-{profile}.properties或是YAML定义的配置文件
1. 位于当前应用jar包之内针对不同{profile}环境的配置文件内容例如application-{profile}.properties或是YAML定义的配置文件
1. 位于当前应用jar包之外的application.properties和YAML配置内容
1. 位于当前应用jar包之内的application.properties和YAML配置内容
1. 在@Configuration注解修改的类中,通过@PropertySource注解定义的属性
1. 应用默认属性使用SpringApplication.setDefaultProperties定义的内容1.
## 3 配置文件属性绑定
### Spring Boot 2.0 新特性
* 移除特殊字符
* 全小写
### 列表类型
> 必须使用连续下标索引进行配置。
* properties中使用[]在定位列表类型
```
pring.my-example.url[0]=http://example.com
@@ -156,39 +67,179 @@ spring:
hello: world
```
## 4 环境属性绑定
### 简单类型
在环境变量中通过小写转换与.替换_来映射配置文件中的内容比如环境变量SPRING_JPA_DATABASEPLATFORM=mysql的配置会产生与在配置文件中设置spring.jpa.databaseplatform=mysql一样的效果。
### List类型
由于环境变量中无法使用[和]符号所以使用_来替代。任何由下划线包围的数字都会被认为是[]的数组形式
### 使用随机数配置
`${random}`的配置方式主要有一下几种,读者可作为参考使用
```
# 随机字符串
com.didispace.blog.value=${random.value}
# 随机int
com.didispace.blog.number=${random.int}
# 随机long
com.didispace.blog.bignumber=${random.long}
# 10以内的随机数
com.didispace.blog.test1=${random.int(10)}
# 10-20的随机数
com.didispace.blog.test2=${random.int[10,20]}
```
## 2 yaml配置文件
### yaml基本语法
* key: valuekv之间有空格
* 大小写敏感
* 使用缩进表示层级关系
* 缩进不允许使用tab只允许空格
* 缩进的空格数不重要,只要相同层级的元素左对齐即可
* '#'表示注释
* 字符串无需加引号,如果要加,''与""表示字符串内容 会被 转义/不转义
```
environments:
dev:
url: http://dev.bar.com
name: Developer Setup
prod:
url: http://foo.bar.com
name: My Cool App
```
### yaml基本类型
* 字面量单个的、不可再分的值。date、boolean、string、number、null
```
k: v
```
* 对象键值对的集合。map、hash、set、object
```
行内写法: k: {k1:v1,k2:v2,k3:v3}
#或
k:
k1: v1
k2: v2
k3: v3
```
* 数组一组按次序排列的值。array、list、queue
```
行内写法: k: [v1,v2,v3]
#或者
k:
- v1
- v2
- v3
```
### yaml的实例
```
@Data
public class Person {
private String userName;
private Boolean boss;
private Date birth;
private Integer age;
private Pet pet;
private String[] interests;
private List<String> animal;
private Map<String, Object> score;
private Set<Double> salarys;
private Map<String, List<Pet>> allPets;
}
@Data
public class Pet {
private String name;
private Double weight;
}
```
对应的yaml配置
```
# yaml表示以上对象
person:
userName: zhangsan
boss: false
birth: 2019/12/12 20:12:33
age: 18
pet:
name: tomcat
weight: 23.4
interests: [篮球,游泳]
animal:
- jerry
- mario
score:
english:
first: 30
second: 40
third: 50
math: [131,140,148]
chinese: {first: 128,second: 136}
salarys: [3999,4999.98,5999.99]
allPets:
sick:
- {name: tom}
- {name: jerry,weight: 47}
health: [{name: mario,weight: 47}]
```
## 3 其他配置方式
### 系统环境变量
* 列表形式:由于环境变量中无法使用[和]符号所以使用_来替代。任何由下划线包围的数字都会被认为是[]的数组形式。
```
MY_FOO_1_ = my.foo[1]
MY_FOO_1_BAR = my.foo[1].bar
MY_FOO_1_2_ = my.foo[1][2]
```
## 5 系统属性绑定
### 简单类型
系统属性与文件配置中的类似,都以移除特殊字符并转化小写后实现绑定
### list类型
系统属性的绑定也与文件属性的绑定类似,通过[]来标示,比如:
### 通过命令行配置
在启动java应用是添加配置参数。系统属性绑定也与文件属性的绑定类似,通过[]来标示,同样的,他也支持逗号分割的方式
```
java -jar xxx.jar --server.port=8888
-D"spring.my-example.url[0]=http://example.com"
-D"spring.my-example.url[1]=http://spring.io"
```
同样的,他也支持逗号分割的方式,比如:
```
-Dspring.my-example.url=http://example.com,http://spring.io
```
## 6 属性读取
## 4 多环境配置
### 配置方法
对于多环境的配置,各种项目构建工具或是框架的基本思路是一致的,通过配置多份不同环境的配置文件,再通过打包命令指定需要打包的内容之后进行区分打包。
在Spring Boot中多环境配置文件名需要满足application-{profile}.properties的格式其中{profile}对应你的环境标识,比如:
* application-dev.properties开发环境
* application-test.properties测试环境
* application-prod.properties生产环境
### 配置加载顺序
1. 命令行中传入的参数。
1. SPRING_APPLICATION_JSON中的属性。SPRING_APPLICATION_JSON是以JSON格式配置在系统环境变量中的内容。
1. java:comp/env中的JNDI属性。
1. Java的系统属性可以通过System.getProperties()获得的内容。
1. 操作系统的环境变量
1. 通过random.*配置的随机属性
1. 位于当前应用jar包之外针对不同{profile}环境的配置文件内容例如application-{profile}.properties或是YAML定义的配置文件
1. 位于当前应用jar包之内针对不同{profile}环境的配置文件内容例如application-{profile}.properties或是YAML定义的配置文件
1. 位于当前应用jar包之外的application.properties和YAML配置内容
1. 位于当前应用jar包之内的application.properties和YAML配置内容
1. 在@Configuration注解修改的类中,通过@PropertySource注解定义的属性
1. 应用默认属性使用SpringApplication.setDefaultProperties定义的内容1.
## 5 自定义配置文件/加载配置文件/属性绑定
### 读取规则
将配置文件中的值引入到java程序中。
在Spring应用程序的environment中读取属性的时候每个属性的唯一名称符合如下规则
@@ -204,9 +255,57 @@ MY_FOO_1_2_ = my.foo[1][2]
this.environment.containsProperty("spring.jpa.database-platform")
```
## 7 新的绑定API
### 引入依赖
简单类型
```xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
```
### @Value
* 通过占位符的方式加载自定义的参数
```
@Component
public class Book {
@Value("${book.name}")
private String name;
@Value("${book.author}")
private String author;
// 省略getter和setter
}
```
* @Value支持的表达式格式
```
#{...}
${...}
```
### @ConfigurationProperties
假设在propertes配置中有这样一个配置
```

View File

@@ -1,5 +1,19 @@
## 注解说明
注解体系
1. 元注解@Rentention @Docemented,@Inherited,@Target
2. JDK标准注解
3. Spring标准注解@Bean @Component @Serivce,@Controller,@Configuration,@Import,@Autowire
4. springboot补充注解
### @SpringbootConfiguration
```
@SpringBootConfiguration springboot启动
@EnableAutoConfiguration 通过properties自动加载
@ComponentScan("com.atguigu.boot")扫描范围
```
springboot项目中的启动注解。
### @Configuration&@Bean
1. 配置类本身也是组件相当于将组件注册到Spring当中。即把类的对象交给Spring管理。
@@ -10,10 +24,10 @@
1. 配置类实用@Bean标注方法上给容器注册组件默认也是单实例。id默认为方法名。可以通过参数指定
2. 外部类可以从Spring的容器中取出在Configuration类中注册的实例。而且都是单实例对象。
```
@Component @Controller @Service @Repository 都是以前的用法
@ComponetScan
```
### @Import
@@ -23,14 +37,12 @@
### @conditional
1. 条件装配。满足Conditional指定的条件则进行组件注入。
2. 这里的条件可以是多种形式
![](image/2022-11-12-15-49-46.png)
@ConditionalOnBean(name="bean")当容器中存在指定名称的容器的时候,才会进行注册。
* @ConditionalOnBean(name="bean")当容器中存在指定名称的容器的时候,才会进行注册。
```
@ConditionalOnBean(name="")
```
### @ImportResource

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

33
maven/maven源码/code/.gitignore vendored Normal file
View File

@@ -0,0 +1,33 @@
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/

Binary file not shown.

View File

@@ -0,0 +1,2 @@
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.6/apache-maven-3.8.6-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar

316
maven/maven源码/code/mvnw vendored Executable file
View File

@@ -0,0 +1,316 @@
#!/bin/sh
# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
# Maven Start Up Batch script
#
# Required ENV vars:
# ------------------
# JAVA_HOME - location of a JDK home dir
#
# Optional ENV vars
# -----------------
# M2_HOME - location of maven2's installed home dir
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
# e.g. to debug Maven itself, use
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
# ----------------------------------------------------------------------------
if [ -z "$MAVEN_SKIP_RC" ] ; then
if [ -f /usr/local/etc/mavenrc ] ; then
. /usr/local/etc/mavenrc
fi
if [ -f /etc/mavenrc ] ; then
. /etc/mavenrc
fi
if [ -f "$HOME/.mavenrc" ] ; then
. "$HOME/.mavenrc"
fi
fi
# OS specific support. $var _must_ be set to either true or false.
cygwin=false;
darwin=false;
mingw=false
case "`uname`" in
CYGWIN*) cygwin=true ;;
MINGW*) mingw=true;;
Darwin*) darwin=true
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
if [ -z "$JAVA_HOME" ]; then
if [ -x "/usr/libexec/java_home" ]; then
export JAVA_HOME="`/usr/libexec/java_home`"
else
export JAVA_HOME="/Library/Java/Home"
fi
fi
;;
esac
if [ -z "$JAVA_HOME" ] ; then
if [ -r /etc/gentoo-release ] ; then
JAVA_HOME=`java-config --jre-home`
fi
fi
if [ -z "$M2_HOME" ] ; then
## resolve links - $0 may be a link to maven's home
PRG="$0"
# need this for relative symlinks
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG="`dirname "$PRG"`/$link"
fi
done
saveddir=`pwd`
M2_HOME=`dirname "$PRG"`/..
# make it fully qualified
M2_HOME=`cd "$M2_HOME" && pwd`
cd "$saveddir"
# echo Using m2 at $M2_HOME
fi
# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin ; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --unix "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
fi
# For Mingw, ensure paths are in UNIX format before anything is touched
if $mingw ; then
[ -n "$M2_HOME" ] &&
M2_HOME="`(cd "$M2_HOME"; pwd)`"
[ -n "$JAVA_HOME" ] &&
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
fi
if [ -z "$JAVA_HOME" ]; then
javaExecutable="`which javac`"
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
# readlink(1) is not available as standard on Solaris 10.
readLink=`which readlink`
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
if $darwin ; then
javaHome="`dirname \"$javaExecutable\"`"
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
else
javaExecutable="`readlink -f \"$javaExecutable\"`"
fi
javaHome="`dirname \"$javaExecutable\"`"
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
JAVA_HOME="$javaHome"
export JAVA_HOME
fi
fi
fi
if [ -z "$JAVACMD" ] ; then
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
else
JAVACMD="`\\unset -f command; \\command -v java`"
fi
fi
if [ ! -x "$JAVACMD" ] ; then
echo "Error: JAVA_HOME is not defined correctly." >&2
echo " We cannot execute $JAVACMD" >&2
exit 1
fi
if [ -z "$JAVA_HOME" ] ; then
echo "Warning: JAVA_HOME environment variable is not set."
fi
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
# traverses directory structure from process work directory to filesystem root
# first directory with .mvn subdirectory is considered project base directory
find_maven_basedir() {
if [ -z "$1" ]
then
echo "Path not specified to find_maven_basedir"
return 1
fi
basedir="$1"
wdir="$1"
while [ "$wdir" != '/' ] ; do
if [ -d "$wdir"/.mvn ] ; then
basedir=$wdir
break
fi
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
if [ -d "${wdir}" ]; then
wdir=`cd "$wdir/.."; pwd`
fi
# end of workaround
done
echo "${basedir}"
}
# concatenates all lines of a file
concat_lines() {
if [ -f "$1" ]; then
echo "$(tr -s '\n' ' ' < "$1")"
fi
}
BASE_DIR=`find_maven_basedir "$(pwd)"`
if [ -z "$BASE_DIR" ]; then
exit 1;
fi
##########################################################################################
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
# This allows using the maven wrapper in projects that prohibit checking in binary data.
##########################################################################################
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found .mvn/wrapper/maven-wrapper.jar"
fi
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
fi
if [ -n "$MVNW_REPOURL" ]; then
jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
else
jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
fi
while IFS="=" read key value; do
case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
esac
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
if [ "$MVNW_VERBOSE" = true ]; then
echo "Downloading from: $jarUrl"
fi
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
if $cygwin; then
wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
fi
if command -v wget > /dev/null; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found wget ... using wget"
fi
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
else
wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
fi
elif command -v curl > /dev/null; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found curl ... using curl"
fi
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
curl -o "$wrapperJarPath" "$jarUrl" -f
else
curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
fi
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Falling back to using Java to download"
fi
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
# For Cygwin, switch paths to Windows format before running javac
if $cygwin; then
javaClass=`cygpath --path --windows "$javaClass"`
fi
if [ -e "$javaClass" ]; then
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Compiling MavenWrapperDownloader.java ..."
fi
# Compiling the Java class
("$JAVA_HOME/bin/javac" "$javaClass")
fi
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
# Running the downloader
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Running MavenWrapperDownloader.java ..."
fi
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
fi
fi
fi
fi
##########################################################################################
# End of extension
##########################################################################################
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
if [ "$MVNW_VERBOSE" = true ]; then
echo $MAVEN_PROJECTBASEDIR
fi
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --path --windows "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
fi
# Provide a "standardized" way to retrieve the CLI args that will
# work with both Windows and non-Windows executions.
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
export MAVEN_CMD_LINE_ARGS
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
exec "$JAVACMD" \
$MAVEN_OPTS \
$MAVEN_DEBUG_OPTS \
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
"-Dmaven.home=${M2_HOME}" \
"-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"

188
maven/maven源码/code/mvnw.cmd vendored Normal file
View File

@@ -0,0 +1,188 @@
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership. The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License. You may obtain a copy of the License at
@REM
@REM https://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied. See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Maven Start Up Batch script
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM
@REM Optional ENV vars
@REM M2_HOME - location of maven2's installed home dir
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
@REM ----------------------------------------------------------------------------
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo off
@REM set title of command window
title %0
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
@REM set %HOME% to equivalent of $HOME
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
:skipRcPre
@setlocal
set ERROR_CODE=0
@REM To isolate internal variables from possible post scripts, we use another setlocal
@setlocal
@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome
echo.
echo Error: JAVA_HOME not found in your environment. >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto init
echo.
echo Error: JAVA_HOME is set to an invalid directory. >&2
echo JAVA_HOME = "%JAVA_HOME%" >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
@REM ==== END VALIDATION ====
:init
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
@REM Fallback to current working directory if not found.
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
set EXEC_DIR=%CD%
set WDIR=%EXEC_DIR%
:findBaseDir
IF EXIST "%WDIR%"\.mvn goto baseDirFound
cd ..
IF "%WDIR%"=="%CD%" goto baseDirNotFound
set WDIR=%CD%
goto findBaseDir
:baseDirFound
set MAVEN_PROJECTBASEDIR=%WDIR%
cd "%EXEC_DIR%"
goto endDetectBaseDir
:baseDirNotFound
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
cd "%EXEC_DIR%"
:endDetectBaseDir
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
@setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
:endReadAdditionalConfig
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
)
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
if exist %WRAPPER_JAR% (
if "%MVNW_VERBOSE%" == "true" (
echo Found %WRAPPER_JAR%
)
) else (
if not "%MVNW_REPOURL%" == "" (
SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
)
if "%MVNW_VERBOSE%" == "true" (
echo Couldn't find %WRAPPER_JAR%, downloading it ...
echo Downloading from: %DOWNLOAD_URL%
)
powershell -Command "&{"^
"$webclient = new-object System.Net.WebClient;"^
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
"}"^
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
"}"
if "%MVNW_VERBOSE%" == "true" (
echo Finished downloading %WRAPPER_JAR%
)
)
@REM End of extension
@REM Provide a "standardized" way to retrieve the CLI args that will
@REM work with both Windows and non-Windows executions.
set MAVEN_CMD_LINE_ARGS=%*
%MAVEN_JAVA_EXE% ^
%JVM_CONFIG_MAVEN_PROPS% ^
%MAVEN_OPTS% ^
%MAVEN_DEBUG_OPTS% ^
-classpath %WRAPPER_JAR% ^
"-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
%WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
if ERRORLEVEL 1 goto error
goto end
:error
set ERROR_CODE=1
:end
@endlocal & set ERROR_CODE=%ERROR_CODE%
if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
@REM check for post script, once with legacy .bat ending and once with .cmd ending
if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
:skipRcPost
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
if "%MAVEN_BATCH_PAUSE%"=="on" pause
if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
cmd /C exit /B %ERROR_CODE%

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.ykl</groupId>
<artifactId>code</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>code</name>
<description>code</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,55 @@
package com.ykl.code;
import com.ykl.code.config.MyConfig;
import com.ykl.code.entity.Pet;
import com.ykl.code.entity.User;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class CodeApplication {
public static void main(String[] args) {
//1、返回我们IOC容器
ConfigurableApplicationContext run = SpringApplication.run(CodeApplication.class, args);
/**
* Full:外部无论对配置类中的这个组件注册方法调用多少次获取的都是之前注册容器中的单实例对象
* @return
*/
//2、查看容器里面的组件
String[] names = run.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
//3、从容器中获取组件
Pet tom01 = run.getBean("tom", Pet.class);
Pet tom02 = run.getBean("tom", Pet.class);
System.out.println("组件:"+(tom01 == tom02));
//4、com.atguigu.boot.config.MyConfig$$EnhancerBySpringCGLIB$$51f1e1ca@1654a892
MyConfig bean = run.getBean(MyConfig.class);
System.out.println(bean);
//如果@Configuration(proxyBeanMethods = true)代理对象调用方法。SpringBoot总会检查这个组件是否在容器中有。
//保持组件单实例
User user = bean.user01();
User user1 = bean.user01();
System.out.println(user == user1);
User user01 = run.getBean("user01", User.class);
Pet tom = run.getBean("tom", Pet.class);
System.out.println("用户的宠物:"+(user01.getPet() == tom));
}
}

View File

@@ -1,9 +1,40 @@
/**
* Alipay.com Inc.
* Copyright (c) 2004-2022 All Rights Reserved.
*/package com.ykl.code.config;/**
*
*/
package com.ykl.code.config;
import com.ykl.code.entity.Pet;
import com.ykl.code.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;
/**
* @author faran
* @version : MyConfig, v 0.1 2022-11-12 13:33 faran Exp $
*/public class MyConfig {
}
*/
@Configuration(proxyBeanMethods = true) //告诉SpringBoot这是一个配置类 == 配置文件
public class MyConfig {
/**
* Full:外部无论对配置类中的这个组件注册方法调用多少次获取的都是之前注册容器中的单实例对象
* @return
*/
@Bean //给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值就是组件在容器中的实例
public User user01(){
User zhangsan = new User("zhangsan", 18);
//user组件依赖了Pet组件
zhangsan.setPet(tomcatPet());
return zhangsan;
}
@Bean("tom")
public Pet tomcatPet(){
return new Pet("tomcat");
}
}

View File

@@ -1,9 +1,38 @@
/**
* Alipay.com Inc.
* Copyright (c) 2004-2022 All Rights Reserved.
*/package com.ykl.code.entity;/**
*
*/
package com.ykl.code.entity;
/**
* @author faran
* @version : Pet, v 0.1 2022-11-12 13:36 faran Exp $
*/public class Pet {
*/
public class Pet {
/**
* Setter method for property <tt>counterType</tt>.
*
* @param name value to be assigned to property name
*/
public void setName(String name) {
this.name = name;
}
String name;
public Pet() {
}
public Pet(String name) {
this.name = name;
}
/**
* Getter method for property <tt>name</tt>.
*
* @return property value of name
*/
public String getName() {
return name;
}
}

View File

@@ -1,9 +1,78 @@
/**
* Alipay.com Inc.
* Copyright (c) 2004-2022 All Rights Reserved.
*/package com.ykl.code.entity;/**
*
*/
package com.ykl.code.entity;
/**
* @author faran
* @version : User, v 0.1 2022-11-12 13:34 faran Exp $
*/public class User {
*/
public class User {
String name;
int age;
/**
* Getter method for property <tt>name</tt>.
*
* @return property value of name
*/
public String getName() {
return name;
}
/**
* Setter method for property <tt>counterType</tt>.
*
* @param name value to be assigned to property name
*/
public void setName(String name) {
this.name = name;
}
/**
* Getter method for property <tt>age</tt>.
*
* @return property value of age
*/
public int getAge() {
return age;
}
/**
* Setter method for property <tt>counterType</tt>.
*
* @param age value to be assigned to property age
*/
public void setAge(int age) {
this.age = age;
}
/**
* Getter method for property <tt>pet</tt>.
*
* @return property value of pet
*/
public Pet getPet() {
return pet;
}
/**
* Setter method for property <tt>counterType</tt>.
*
* @param pet value to be assigned to property pet
*/
public void setPet(Pet pet) {
this.pet = pet;
}
Pet pet;
public User() {
}
public User(String name, int age) {
this.name = name;
this.age = age;
}
}

View File

@@ -0,0 +1,13 @@
package com.ykl.code;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class CodeApplicationTests {
@Test
void contextLoads() {
}
}