• JavaSE进阶21天---第二十天---JavaSE(​​日志、logback日志、添加模板、类加载器、ressources文件夹)


     ✨✨个人主页:沫洺的主页

    📚📚系列专栏: 📖 JavaWeb专栏📖 JavaSE专栏 📖 Java基础专栏📖vue3专栏 

                               📖MyBatis专栏📖Spring专栏📖SpringMVC专栏📖SpringBoot专栏

                               📖Docker专栏📖Reids专栏📖MQ专栏📖SpringCloud专栏     

    💖💖如果文章对你有所帮助请留下三连✨✨

    🥝日志

    概述

    • 程序中的日志可以用来记录程序在运行的时候点点滴滴。并可以进行永久存储。

    日志与输出语句的区别

    输出语句 日志技术
    取消日志需要修改代码,灵活性比较差不需要修改代码,灵活性比较好
    输出位置只能是控制台可以将日志信息写入到文件或者数据库中
    多线程和业务代码处于一个线程中多线程方式记录日志,不影响业务代码的性能

    🥥日志体系结构

    🍈logback

    Logback介绍

    • Logback是基于slf4j的日志规范实现的框架,性能比之前使用的log4j要好
    • 官方网址:https://logback.qos.ch/index.html

    Logback主要分三个技术模块

    • logback-core: 该模块为其他两个模块提供基础代码,必须有
    • logback-ckassic: 完整实现了slf4j APS的模块
    • logback-access 模块与Tomcat 和 Jetty 等 Servlet 容器集成,以提供 HTTP 访问日志功能

    Logback的作用

    • 通过使用logback,可以控制日志信息输送的目的地是控制台、文件等位置。
    • 可以控制每一条日志的输出格式。
    • 通过定义每一条日志信息的级别,能够更加细致地控制日志的生成过程。
    • 可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。

     Logback入门使用

    1. 导入logback的相关jar包

    2. 编写logback配置文件

    3. 在代码中获取日志的对象

    4. 按照级别设置记录日志信息

    添加jar包

    可以去网盘下载下来,然后复制到项目模块下

    链接:https://pan.baidu.com/s/1NgM50O0X71Qm6LncPyReiw?pwd=wznb 
    提取码:wznb 

     复制到模块src下

     添加配置文件(注意日志保存的路径)

     注意jar包和配置文件都是放在src文件夹下

    代码演示

    1. package cn.moming1;
    2. import org.slf4j.Logger;
    3. import org.slf4j.LoggerFactory;
    4. import java.util.Scanner;
    5. public class LogDemo {
    6. //获取日志对象
    7. private static final Logger LOGGER = LoggerFactory.getLogger(LogDemo.class);
    8. public static void main(String[] args) {
    9. //打日志
    10. Scanner sc = new Scanner(System.in);
    11. System.out.println("输入姓名");
    12. String name = sc.nextLine();
    13. //面向日志对象,调用方法,记录日志
    14. //通过核心配置文件可以指定日志记录的位置
    15. LOGGER.info("用户输入的姓名为:"+name);
    16. System.out.println("输入年龄");
    17. String age = sc.nextLine();
    18. try {
    19. int ageInt = Integer.parseInt(age);
    20. LOGGER.info("用户输入的年龄为:"+age);
    21. } catch (NumberFormatException e) {
    22. LOGGER.info("用户输入的年龄格式错误->"+age);
    23. }
    24. }
    25. }
    1. 输入姓名
    2. moming
    3. 2022-08-20 10:31:23.482 [INFO ] cn.moming1.LogDemo [main] : 用户输入的姓名为:moming
    4. 输入年龄
    5. 18
    6. 2022-08-20 10:31:29.142 [INFO ] cn.moming1.LogDemo [main] : 用户输入的年龄为:18
    1. 输入姓名
    2. moming
    3. 2022-08-20 10:31:52.357 [INFO ] cn.moming1.LogDemo [main] : 用户输入的姓名为:moming
    4. 输入年龄
    5. abc
    6. 2022-08-20 10:31:55.999 [INFO ] cn.moming1.LogDemo [main] : 用户输入的年龄格式错误->abc

    然后找到日志文件

    🍉配置文件

    如果系统上线后只想记录一些错误的日志信息或者不想记录日志,怎么办?

    • 可以通过设置日志的输出级别来控制哪些日志信息输出或者不输出
    • 级别程度依次是:TRACE
    • 默认级别是debug(忽略大小写)
    • 作用:将开发中不同的日志信息进行分类,只输出大于等于该日志级别的日志信息
    • ALL和OFF分别是打开全部日志信息,及关闭全部日志信息

    🍋配置文件添加模板

    🍊类加载器

    什么是类加载器

    • 类加载器负责将.class文件(存储的物理文件)加载到内存中

    类加载的时机

    类在什么时候会被加载到内存中呢?

    • 创建类的实例(对象)

    • 调用类的类方法

    • 访问类或者接口的类变量,或者为该类变量赋值

    • 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象

    • 初始化某个类的子类

    • 直接使用java.exe命令来运行某个主类

    总结就是,用到就加载

    类加载的过程

    加载(把.class文件读到内存里边)

    • 通过包名 + 类名,获取这个类,准备用流进行传输

    • 在这个类加载到内存中

    • 加载完毕创建一个class对象

    链接

    • 验证

      确保Class文件字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身安全

      (文件中的信息是否符合虚拟机规范有没有安全隐患)

    • 准备

      负责为类的类变量(被static修饰的变量)分配内存,并设置默认初始化值

      (初始化静态变量)

    • 解析

      将类的二进制数据流中的符号引用替换为直接引用

      (本类中如果用到了其他类,此时就需要找到对应的类)

    初始化

    根据程序员通过程序制定的主观计划去初始化类变量和其他资源

    (静态变量赋值以及初始化其他资源)

    小结

    • 当一个类被使用的时候,才会加载到内存

    • 类加载的过程: 加载、验证、准备、解析、初始化

    类加载器分类

    • Bootstrap class loader:启动类加载器,虚拟机的内置类加载器,通常表示为null ,并且没有父null

    • Platform class loader:平台类加载器,负责加载JDK中一些特殊的模块

    • System class loader:系统类加载器,负责加载用户类路径上所指定的类库

    • UserClassloader:自定义类加载器

    类加载器的继承关系

    • System的父加载器为Platform

    • Platform的父加载器为Bootstrap

    双亲委派模型

    介绍

    • 如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这个请求委托给父类的加载器去执行,如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归,请求最终将到达顶层的启动类加载器,如果父类加载器可以完成类加载任务,就成功返回,倘若父类加载器无法完成此加载任务,子加载器才会尝试自己去加载,这就是双亲委派模式

    目的:为了保证一个类最多只能加载1次

    代码示例(只是演示一下双亲委派机制的过程)

    1. package cn.moming4;
    2. public class ClassLoaderDemo1 {
    3. public static void main(String[] args) {
    4. //获得系统类加载器
    5. ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
    6. //获取系统类加载器的父加载器--平台类加载器
    7. ClassLoader classLoader1 = systemClassLoader.getParent();
    8. //获取平台类加载器的父加载器--启动类加载器
    9. ClassLoader classLoader2 = classLoader1.getParent();
    10. System.out.println("系统类加载器:"+systemClassLoader);
    11. System.out.println("平台类加载器:"+classLoader1);
    12. System.out.println("启动类加载器:"+classLoader2);
    13. }
    14. }
    1. 系统类加载器:jdk.internal.loader.ClassLoaders$AppClassLoader@63947c6b
    2. 平台类加载器:jdk.internal.loader.ClassLoaders$PlatformClassLoader@41629346
    3. 启动类加载器:null

    获取类加载器的两种方法

    推荐使用第二种

    1. package cn.moming4;
    2. public class MyLoader {
    3. public static void main(String[] args) {
    4. //1.直接使用ClassLoader的静态方法
    5. ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
    6. System.out.println(systemClassLoader);
    7. //2.可以利用当前类的字节码文件对象,调用getClassLoader()
    8. ClassLoader classLoader = MyLoader.class.getClassLoader();
    9. System.out.println(classLoader);
    10. System.out.println(classLoader==systemClassLoader);
    11. }
    12. }
    1. jdk.internal.loader.ClassLoaders$AppClassLoader@63947c6b
    2. jdk.internal.loader.ClassLoaders$AppClassLoader@63947c6b
    3. true

    类加载器的常用方法

    方法名说明
    public static ClassLoader getSystemClassLoader()获取系统类加载器
    public InputStream getResourceAsStream(String name)加载某一个资源文件

    练习使用类加载器读配置文件

    先创建一个资源文件(在src路径下因为类加载器是从src路径下开始的

     加载资源文件

    1. package cn.moming4;
    2. import java.io.IOException;
    3. import java.io.InputStream;
    4. import java.util.Properties;
    5. public class ClassLoaderDemo2 {
    6. public static void main(String[] args) throws IOException {
    7. //获取系统类加载器
    8. ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
    9. //加载某一个资源文件
    10. //利用加载器去加载一个指定的文件
    11. //参数:文件的路径
    12. //返回值:字节流
    13. InputStream is = systemClassLoader.getResourceAsStream("prop.properties");
    14. Properties prop = new Properties();
    15. prop.load(is);
    16. System.out.println(prop);
    17. is.close();
    18. }
    19. }
    {name=moming, age=18}

    补充

    🍓resources文件夹

    在实际开发中,配置文件一般是放在resources文件夹中,效果和src一样

     

  • 相关阅读:
    NR SRS(二)
    Java学习笔记(二)
    从0到1,手把手带你开发截图工具ScreenCap------001实现基本的截图功能
    大数据在电力行业的应用案例100讲(二十六)-分布式ID微服务实现及应用
    模拟堆的实现
    第七章 总结及作业【编译原理】
    我们为什么做NDH
    【AI设计模式】01-数据表示-特征哈希(Feature Hashed)模式
    工作流-重要概念
    python的opencv操作记录(五) - 空间域与频域转换
  • 原文地址:https://blog.csdn.net/HeyVIrBbox/article/details/126435932