diff --git a/Java三方库/logback.md b/Java三方库/logback.md index 5db64e68..f1d00dc9 100644 --- a/Java三方库/logback.md +++ b/Java三方库/logback.md @@ -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 ``` -### maven依赖 +### maven 依赖 ```xml @@ -47,35 +46,31 @@ logback是一个开源的日志组件,是log4j的作者开发的用来替代lo ``` - - ## 2 配置内容 ### configuration + 日志配置的根节点 ``` ``` - ### contextName -的子节点。各个logger都被关联到一个loggerContext中,loggerContext负责制造logger,也负责以树结构排列个logger。 - - +的子节点。各个 logger 都被关联到一个 loggerContext 中,loggerContext 负责制造 logger,也负责以树结构排列个 logger。 ``` atguiguSrb ``` + ### property 的子节点,用来定义变量。 - 有两个属性,name和value:name的值是变量的名称,value是变量的值。 - -通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。 + 有两个属性,name 和 value:name 的值是变量的名称,value 是变量的值。 +通过定义的值会被插入到 logger 上下文中。定义变量后,可以使“${}”来使用变量。 ```xml @@ -100,16 +95,17 @@ logback是一个开源的日志组件,是log4j的作者开发的用来替代lo ``` ### appender -``是``的子节点,是负责写日志的组件.主要用于指定日志输出的目的地,目的地可以是控制台、文件、远程套接字服务器、MySQL、PostreSQL、Oracle和其他数据库、JMS和远程UNIX Syslog守护进程等。 -不同的appender有不同的属性可以配置 +``是``的子节点,是负责写日志的组件.主要用于指定日志输出的目的地,目的地可以是控制台、文件、远程套接字服务器、MySQL、PostreSQL、Oracle 和其他数据库、JMS 和远程 UNIX Syslog 守护进程等。 +不同的 appender 有不同的属性可以配置 ### ConsoleAppender -* ``有两个必要属性name和class:name指定appender名称,class指定appender的全限定名 -* ``对日志进行格式化 - * ``定义日志的具体输出格式 - * ``编码方式 + +- ``有两个必要属性 name 和 class:name 指定 appender 名称,class 指定 appender 的全限定名 +- ``对日志进行格式化 + - ``定义日志的具体输出格式 + - ``编码方式 ```xml @@ -120,12 +116,20 @@ logback是一个开源的日志组件,是log4j的作者开发的用来替代lo ${CONSOLE_LOG_PATTERN} ${ENCODING} + + ${logging.level} + + + ERROR + DENY + ``` 输出模式说明 -* 输出模式:%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 -* ``表示日志文件的位置,如果上级目录不存在会自动创建,没有默认值。\ -* ``默认 true,日志被追加到文件结尾,如果是 false,服务重启后清空现存文件。 +- ``表示日志文件的位置,如果上级目录不存在会自动创建,没有默认值。\ +- ``默认 true,日志被追加到文件结尾,如果是 false,服务重启后清空现存文件。 + ```xml @@ -153,14 +161,15 @@ logback是一个开源的日志组件,是log4j的作者开发的用来替代lo ``` ### RollingFileAppender + 表示滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将旧日志备份到其他文件 -* ``是``的子节点,用来定义滚动策略。 +- ``是``的子节点,用来定义滚动策略。 -* TimeBasedRollingPolicy:最常用的滚动策略,根据时间来制定滚动策略。 +- TimeBasedRollingPolicy:最常用的滚动策略,根据时间来制定滚动策略。 -* ``:包含文件名及转换符, “%d”可以包含指定的时间格式,如:%d{yyyy-MM-dd}。如果直接使用 %d,默认格式是 yyyy-MM-dd。 -* ``:可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件。假设设置每个月滚动,且``是6,则只保存最近6个月的文件,删除之前的旧文件。注意,删除旧文件是,那些为了归档而创建的目录也会被删除。 +- ``:包含文件名及转换符, “%d”可以包含指定的时间格式,如:%d{yyyy-MM-dd}。如果直接使用 %d,默认格式是 yyyy-MM-dd。 +- ``:可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件。假设设置每个月滚动,且``是 6,则只保存最近 6 个月的文件,删除之前的旧文件。注意,删除旧文件是,那些为了归档而创建的目录也会被删除。 ```xml @@ -178,21 +187,92 @@ logback是一个开源的日志组件,是log4j的作者开发的用来替代lo 15 + + ${log_path}/userlog-%d{yyyyMMddHHmm}-%i.log + 300KB + 60 + ``` -* 放在``的子节点的位置,基于实践策略的触发滚动策略``设置触发滚动条件:单个文件大于100M时生成新的文件 +- 放在``的子节点的位置,基于实践策略的触发滚动策略``设置触发滚动条件:单个文件大于 100M 时生成新的文件 + +### AsyncAppender + +``` + + + + +``` + +### SiftingAppender +之前在介绍常用appender时已经记录过了,SiftingAppender可用于根据给定的运行时属性来分离(或筛选)日志记录。 + +比如:可以按照业务功能生成独立的日志文件、按照用户会话id为每个用户生成独立的日志文件等。 + +按照业务功能生成独立的日志文件 +上面我们通过为每个业务类配置的方式,实现了按照业务功能生成独立的日志文件,下面我们使用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 + + + + + logKey + general + + + + + ${log_path}/db/${logKey}.log + + ${log_path}/db/${logKey}.%d{yyyyMMddHHmm}.log + 60 + + + %msg%n + + + + + + + + +``` ### logger ``可以是``的子节点,用来设置日志打印级别、指定`` +- name:用来指定受此 logger 约束的某一个包或者具体的某一个. +- level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF。默认继承上级的级别。logger 日志级别。级别包括:TRACE < DEBUG < INFO < WARN < ERROR,定义于 ch.qos.logback.classic.Level 类中。 +- ``可以包含零个或多个``元素,标识这个 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。 -* ``可以包含零个或多个``元素,标识这个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的取得:通过org.slf4j.LoggerFactory的getLogger()方法取得。getLogger(Class obj)方式是通过传入一个类的形式来进行logger对象和类的绑定;getLogger(String name)方式是通过传入一个contextName的形式来指定一个logger,用同一个名字调用该方法获取的永远都是同一个logger对象的引用。 +- logger 的取得:通过 org.slf4j.LoggerFactory 的 getLogger()方法取得。getLogger(Class obj)方式是通过传入一个类的形式来进行 logger 对象和类的绑定;getLogger(String name)方式是通过传入一个 contextName 的形式来指定一个 logger,用同一个名字调用该方法获取的永远都是同一个 logger 对象的引用。 + +### root + +配置默认的日志打印 + +也是元素,但是它是根loger。只有一个level属性,应为已经被命名为"root". +level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,不能设置为INHERITED或者同义词NULL。默认是DEBUG。 + +* 没有设置addtivity,默认为true,将此loger的打印信息向上级传递; + +```xml + + + +``` + ## 3 配置文件 ### 配置文件实例 @@ -424,4 +520,4 @@ logback是一个开源的日志组件,是log4j的作者开发的用来替代lo -``` \ No newline at end of file +``` diff --git a/Java基础教程/Java语言基础/12 Java注解.md b/Java基础教程/Java语言基础/12 Java注解.md index 31a58058..0b838460 100644 --- a/Java基础教程/Java语言基础/12 Java注解.md +++ b/Java基础教程/Java语言基础/12 Java注解.md @@ -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元注解修饰那么根据Value(ElementType枚举常量)的指定的目标进行规定。 -* @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元注解修饰那么根据Value(ElementType枚举常量)的指定的目标进行规定。 + +* @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中定义服务、使用服务、实现服务。具有相同的含义。 diff --git a/Java基础教程/Java语言基础/13 lambda表达式.md b/Java基础教程/Java语言基础/13 lambda表达式.md index e69de29b..e6e50dfe 100644 --- a/Java基础教程/Java语言基础/13 lambda表达式.md +++ b/Java基础教程/Java语言基础/13 lambda表达式.md @@ -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) { + ArrayListlist=new ArrayList<>(); + list.add("a"); + list.add("bc"); + list.add("def"); + list.add("hello"); + + //写法1:(不用Lambda表达式) + list.forEach(new Consumer() { + @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) { + ArrayListlist=new ArrayList<>(); + list.add("hh"); + list.add("hi"); + list.add("def"); + list.add("abc"); + + //写法1:(不用Lambda表达式) + list.sort(new Comparator() { + @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) { + HashMapmap=new HashMap<>(); + map.put(1,"hello"); + map.put(2,"I"); + map.put(3,"love"); + map.put(4,"china"); + + //法一:(不用Lambda) + map.forEach(new BiConsumer() { + @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)); + } +``` \ No newline at end of file diff --git a/Spring/Springboot/01 内容简介.md b/Spring/Springboot/01 内容简介.md index ceabb35c..51f94bde 100644 --- a/Spring/Springboot/01 内容简介.md +++ b/Spring/Springboot/01 内容简介.md @@ -246,7 +246,7 @@ public class Bootstrap { ## 5 自动配置原理 ### maven继承关系 - +* 在parent中管理版本信息 ```xml 依赖管理 diff --git a/Spring/Springboot/02 配置文件.md b/Spring/Springboot/02 创建项目.md similarity index 100% rename from Spring/Springboot/02 配置文件.md rename to Spring/Springboot/02 创建项目.md diff --git a/Spring/Springboot/2配置.md b/Spring/Springboot/03 配置文件.md similarity index 59% rename from Spring/Springboot/2配置.md rename to Spring/Springboot/03 配置文件.md index 6e822bb0..e70f4cc4 100644 --- a/Spring/Springboot/2配置.md +++ b/Spring/Springboot/03 配置文件.md @@ -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: value;kv之间有空格 +* 大小写敏感 +* 使用缩进表示层级关系 +* 缩进不允许使用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 animal; + private Map score; + private Set salarys; + private Map> 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 + + org.springframework.boot + spring-boot-configuration-processor + true + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.springframework.boot + spring-boot-configuration-processor + + + + + + +``` + +### @Value +* 通过占位符的方式加载自定义的参数 + +``` +@Component +public class Book { + + @Value("${book.name}") + private String name; + @Value("${book.author}") + private String author; + + // 省略getter和setter +} +``` +* @Value支持的表达式格式 +``` +#{...} +${...} +``` + + +### @ConfigurationProperties 假设在propertes配置中有这样一个配置: ``` diff --git a/Spring/Springboot/03 基本注解.md b/Spring/Springboot/04 基本注解.md similarity index 76% rename from Spring/Springboot/03 基本注解.md rename to Spring/Springboot/04 基本注解.md index 84245706..b926eb38 100644 --- a/Spring/Springboot/03 基本注解.md +++ b/Spring/Springboot/04 基本注解.md @@ -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 diff --git a/Spring/Springboot/image/2022-11-12-15-49-46.png b/Spring/Springboot/image/2022-11-12-15-49-46.png new file mode 100644 index 00000000..cb015643 Binary files /dev/null and b/Spring/Springboot/image/2022-11-12-15-49-46.png differ diff --git a/maven/maven源码/code/.gitignore b/maven/maven源码/code/.gitignore new file mode 100644 index 00000000..549e00a2 --- /dev/null +++ b/maven/maven源码/code/.gitignore @@ -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/ diff --git a/maven/maven源码/code/.mvn/wrapper/maven-wrapper.jar b/maven/maven源码/code/.mvn/wrapper/maven-wrapper.jar new file mode 100644 index 00000000..c1dd12f1 Binary files /dev/null and b/maven/maven源码/code/.mvn/wrapper/maven-wrapper.jar differ diff --git a/maven/maven源码/code/.mvn/wrapper/maven-wrapper.properties b/maven/maven源码/code/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 00000000..b74bf7fc --- /dev/null +++ b/maven/maven源码/code/.mvn/wrapper/maven-wrapper.properties @@ -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 diff --git a/maven/maven源码/code/mvnw b/maven/maven源码/code/mvnw new file mode 100755 index 00000000..8a8fb228 --- /dev/null +++ b/maven/maven源码/code/mvnw @@ -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 "$@" diff --git a/maven/maven源码/code/mvnw.cmd b/maven/maven源码/code/mvnw.cmd new file mode 100644 index 00000000..1d8ab018 --- /dev/null +++ b/maven/maven源码/code/mvnw.cmd @@ -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% diff --git a/maven/maven源码/code/pom.xml b/maven/maven源码/code/pom.xml new file mode 100644 index 00000000..e10553af --- /dev/null +++ b/maven/maven源码/code/pom.xml @@ -0,0 +1,47 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.7.5 + + + com.ykl + code + 0.0.1-SNAPSHOT + code + code + + 1.8 + + + + org.springframework.boot + spring-boot-starter + + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.springframework.boot + spring-boot-starter-tomcat + compile + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/maven/maven源码/code/src/main/java/com/ykl/code/CodeApplication.java b/maven/maven源码/code/src/main/java/com/ykl/code/CodeApplication.java new file mode 100644 index 00000000..9178c046 --- /dev/null +++ b/maven/maven源码/code/src/main/java/com/ykl/code/CodeApplication.java @@ -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)); + + } + +} diff --git a/maven/maven源码/code/src/main/java/com/ykl/code/config/MyConfig.java b/maven/maven源码/code/src/main/java/com/ykl/code/config/MyConfig.java index 10742383..a4e92ba5 100644 --- a/maven/maven源码/code/src/main/java/com/ykl/code/config/MyConfig.java +++ b/maven/maven源码/code/src/main/java/com/ykl/code/config/MyConfig.java @@ -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"); + } +} \ No newline at end of file diff --git a/maven/maven源码/code/src/main/java/com/ykl/code/entity/Pet.java b/maven/maven源码/code/src/main/java/com/ykl/code/entity/Pet.java index 48be0283..a698b1c5 100644 --- a/maven/maven源码/code/src/main/java/com/ykl/code/entity/Pet.java +++ b/maven/maven源码/code/src/main/java/com/ykl/code/entity/Pet.java @@ -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 counterType. + * + * @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 name. + * + * @return property value of name + */ + public String getName() { + return name; + } } diff --git a/maven/maven源码/code/src/main/java/com/ykl/code/entity/User.java b/maven/maven源码/code/src/main/java/com/ykl/code/entity/User.java index 8660d856..197501c8 100644 --- a/maven/maven源码/code/src/main/java/com/ykl/code/entity/User.java +++ b/maven/maven源码/code/src/main/java/com/ykl/code/entity/User.java @@ -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 name. + * + * @return property value of name + */ + public String getName() { + return name; + } + + /** + * Setter method for property counterType. + * + * @param name value to be assigned to property name + */ + public void setName(String name) { + this.name = name; + } + + /** + * Getter method for property age. + * + * @return property value of age + */ + public int getAge() { + return age; + } + + /** + * Setter method for property counterType. + * + * @param age value to be assigned to property age + */ + public void setAge(int age) { + this.age = age; + } + + /** + * Getter method for property pet. + * + * @return property value of pet + */ + public Pet getPet() { + return pet; + } + + /** + * Setter method for property counterType. + * + * @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; + } } diff --git a/maven/maven源码/code/src/main/resources/application.properties b/maven/maven源码/code/src/main/resources/application.properties new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/maven/maven源码/code/src/main/resources/application.properties @@ -0,0 +1 @@ + diff --git a/maven/maven源码/code/src/test/java/com/ykl/code/CodeApplicationTests.java b/maven/maven源码/code/src/test/java/com/ykl/code/CodeApplicationTests.java new file mode 100644 index 00000000..63efeebe --- /dev/null +++ b/maven/maven源码/code/src/test/java/com/ykl/code/CodeApplicationTests.java @@ -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() { + } + +}