[Java学习日记]日志、类加载器、XML、DTD与schema、XML解析、XPath、单元测试、Assert、BeforeAfter、注解、自定义注解、注解案例

下面的案例中只是做一个简单的了解,不做深入理解啦

目录

一.使用Logback写日志

二.类加载器

三.XML

四.XML编写规定:DTD与schema

五.XML解析

六.XPath

七.单元测试

七.Assert(断言):检验方法结果

八.使用before与after注解备份与还原数据

九.注解

十.自定义注解

十一.注解案例:用注解模拟JUnit


使用到的部分jar包版本如下:

[Java学习日记]日志、类加载器、XML、DTD与schema、XML解析、XPath、单元测试、Assert、BeforeAfter、注解、自定义注解、注解案例_第1张图片

 

 

一.使用Logback写日志

使用Logback写日志
把输出语句保存到文件当中
接口规范:Commons Logging(JCL)与Simple Logging Facade for java(slf4j)
日志实现框架:JUL(Java自带)、log4j、Logback(现在学习的,基于slf4j)
在使用Logger前应该做的准备工作有哪些?
1.需要导入的jar包:slf4j(规范)logback-core(核心)logback-classic(实现了完整的slf4j)logback-access(与汤猫服务器继承,提供了日志访问功能)
2.将配置文件logback.xml拷贝到src目录下

在测试类中如何使用logback产生日志文件?
1.通过LoggerFactory类的静态方法getLogger,传入本类对象创建Logger对象
2.通过Logger的info(或者其他方法记录信息)写入日志信息

配置文件:

 

    
    
    
        
        System.out
        
            
            %d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] [%c] [%thread] : %msg%n
        
    

    
    
        
            %d{yyyy-MM-dd HH:mm:ss} : %msg%n
        
        
            
            D:/IDEACode/demo1/JAVA基础/src/Day36/MyLog/data%d{yyyy-MMdd}.log
        
    

    
    
        
        
    
public class Demo361Logback {
    final static Logger LOGGER = LoggerFactory.getLogger("Demo361Logback.class");
    public static void main(String[] args) {
        LOGGER.info("SunCoya学习日志");
    }
}

 

[Java学习日记]日志、类加载器、XML、DTD与schema、XML解析、XPath、单元测试、Assert、BeforeAfter、注解、自定义注解、注解案例_第2张图片 

 


 

二.类加载器

类加载器:把字节码class文件搬运到虚拟机里面

类加载时机-用到才加载
1.创建对象 2.调用静态方法 3.访问静态变量 4.使用反射创建class对象 5.初始化子类 6.java.exe

类加载过程
加载:
    通过全限定名获取定义此类的二进制流
    把静态存储结构转化为运行时数据结构
    加载完毕则创建一个class对象
连接:
    验证:检查信息有没有安全隐患
    准备:为静态变量初始化值—默认
    解析:加载把引用型变量需要用到的类,把符号引用变为直接引用
初始化:
    初始化静态变量:变为被复制的值

加载器分类
所有加载请求都会被送到最顶层的启动类加载器,然后往下送,看那个加载器能加载
启动类加载器:虚拟机内置类加载器
平台类加载器:加载JDK特殊模块
系统类加载器:加载用户类路径上所指定的类库
自定义加载器
public class Demo362ClassLoader {
    final static String FILE_STR = "Day35_Reflect_DynamicAgent\\message.properties";
    public static void main(String[] args) throws IOException {
        //获得系统类加载器
        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
        ClassLoader platformClassLoader = systemClassLoader.getParent();
        ClassLoader bootStrapClassLoader = platformClassLoader.getParent();
        System.out.println(systemClassLoader);
        System.out.println(platformClassLoader);
        System.out.println(bootStrapClassLoader);

        //加载某一个资源文件:只能设置本模块中的路径
        InputStream stream = systemClassLoader.getResourceAsStream(FILE_STR);
        Properties properties = new Properties();
        properties.load(stream);
        System.out.println(properties);
        stream.close();
    }
}

 [Java学习日记]日志、类加载器、XML、DTD与schema、XML解析、XPath、单元测试、Assert、BeforeAfter、注解、自定义注解、注解案例_第3张图片

 


 

三.XML

XML(EXtensible markup language,可扩展(标签名字随便写)的标记性语言)
一般用来保存配置文件,缺点就是解析起来比较复杂
使用properties配置文件时遇到同键多值的情况会出现问题

xml声明规则:
1.文档声明必须是第一行,声明版本号码,编码:
2.标签必须要有一对或者是不成对的标签:
3.必须要有根标签(最外面的标签),且只能有一个
4.在标签里面可以设置属性,要与标签名隔开,属性值要用引号引起来:


    
        zhangsan
        23
        
        小于< 大于> 且& 单引' 双引"
        
        ]]>
    

 


 

四.XML编写规定:DTD与schema

DTD(Document Type Definition):约束文档,后缀必须是.dtd


元素根标签必须叫书架,书架里面的元素必须是书,书能写多个

书里面有三个子标签

代表里面的元素只能是文本数据, 缺点就是不能限定数据类型

而schema可以约束具体数类型,约束能力更加强大,其本身也是一个xml文件,也受到其他xml文件的约束
编写schema约束文档,后缀名必须是xsd

dtd文件:





 chema文件:




    
        
            
                
                    
                        
                            
                            
                            
                        
                    
                
            
        
    
引入DTD:
1.引入本地:
2.内部引入:
3.引入网络: 
  

 XML导入DTD:




<书架>
    <书>
        <书名>Java从入门到起飞
        <作者>阿玮
        <售价>100w
    
    <书>
        <书名>Java算法真经
        <作者>????
        <售价>100w
    

 


 

五.XML解析

使用dom4j.jar去解析xml文档
SAX解析(Simple API for XML):逐行读取,只能查不能改,但是查询效率高
DOM解析:整体加载到内存,形成树型结构,可查可改,我们学习的也是DOM解析工具
在dom思想中:attribute是属性
public class Demo363XMLoad {
    final static String FILE_STR = "JAVA基础\\src\\Day36\\MyXML\\students2.xml";
    public static void main(String[] args) throws DocumentException {
        System.out.println("1.创建SAXReader对象");
        SAXReader saxReader = new SAXReader();
        System.out.println("2.调用saxReader的read方法,传入需要读取的文件,获取dom对象");
        Document document = saxReader.read(new File(FILE_STR));
        System.out.println(document);
        System.out.println("3.通过dom获取根标签对象");
        Element rootElement = document.getRootElement();
        System.out.println(rootElement.getName());
        System.out.println("4.通过根标签获取子标签,传入参数代表限制标签名");
        List elements = rootElement.elements();
        for (Element element : elements)System.out.println(element.getName());
        System.out.println("5.通过标签获取属性,内容,把数据放到集合中");
        ArrayList arrayList = new ArrayList<>();
        for (Element element : elements) {
            //获取标签属性
            Attribute attribute = element.attribute("id");
            String id = attribute.getText();
            //获取标签
            String name = element.element("name").getText();
            String age = element.element("age").getText();
            arrayList.add(new Student(Integer.parseInt(id),name,Integer.parseInt(age)));
        }
        System.out.println(arrayList);
    }
}
public class Student {
    private int id;
    private String name;
    private int age;
    public Student() {
    }
    public Student(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String toString() {
        return "Student{id = " + id + ", name = " + name + ", age = " + age + "}";
    }
}

 



    
        zhangsan
        23
    
    
        lisi
        24
    
    
        wangwu
        25
    

[Java学习日记]日志、类加载器、XML、DTD与schema、XML解析、XPath、单元测试、Assert、BeforeAfter、注解、自定义注解、注解案例_第4张图片 


 

六.XPath

Xpath技术:获取xml文档中的单个元素,依赖于dom4j
其提供了比较独特的路径思想:使用路径来定位元素节点或者是属性节点
导入jaxen.jar包(暂时未用到)
public class Demo364XPath {
    public static void main(String[] args) throws DocumentException {
        SAXReader saxReader = new SAXReader();
        Document document = saxReader.read(new File(Demo363XMLoad.FILE_STR));
        System.out.println("1.获取到DOM对象之后使用selectNodes方法获取节点元素");
        System.out.println("2.绝对路径:从头开始一级一级往下,可以检索多个符合这一条路径的元素,用多个/表示");
        List nodes = document.selectNodes("/students/student/name");
        for (Node node : nodes) {System.out.println(node.getText());}

        System.out.println("如果是获取单个标签,则得到第一个");
        Node node = document.selectSingleNode("students/student/name");
        System.out.println(node.getText());

        System.out.println("3.相对路径:需要找到一个当前节点,用.表示");
        Element rootElement = document.getRootElement();
        nodes = rootElement.selectNodes("./student/name");
        for (Node node1 : nodes) {System.out.println(node1.getText()); }

        System.out.println("""
                4.全文检索:直接搜索元素名,使用//,比如我的案例中可以直接使用//name
                下面的写法则是搜索所有students路径下的name,不必严格一级一级往下
                也可以写//student/name:表示搜索到的name一定要在student下一级
                也就是说有两条杠就可以随意玩,只有一条杠就需要遵守层级规则                   
                """);
        nodes = document.selectNodes("//students//name");
        for (Node node1 : nodes) {System.out.println(node1.getText()); }

        System.out.println("5.属性检索,使用//@属性名检索所有的属性");
        nodes = document.selectNodes("//@id");
        for (Node node1 : nodes) { System.out.println(node1.getText()); }

        System.out.println("6.通过特定属性检索标签:在标签后添加[@属性名]");
        nodes=document.selectNodes("//student[@id]");
        for (Node node1 : nodes) { System.out.println(node1.getName()); }

        System.out.println("7.通过固定属性检索标签,在上面的案例基础上给属性赋值即可,下面字符串中只能用单引");
        nodes = document.selectNodes("//student[@id='1']");
        for (Node node1 : nodes) { System.out.println(node1.getName()); }
    }
}

[Java学习日记]日志、类加载器、XML、DTD与schema、XML解析、XPath、单元测试、Assert、BeforeAfter、注解、自定义注解、注解案例_第5张图片 

 


 

七.单元测试

单元测试:针对Java中的方法的测试
编写测试方法:public void method(),一定要是非静态方法,在测试方法上使用@Test注解
左边的External Libraries中出现JUnit4
点击类名左边的绿色箭头可测试多个方法
public class Demo365JUnitTest {
    @Test
    public void method1(){
        System.out.println("测试方法一");
    }
    @Test
    public void method2(){
        System.out.println("测试方法二");
    }
    @Test
    public void method3(){
        System.out.println("测试方法三");
    }
}

[Java学习日记]日志、类加载器、XML、DTD与schema、XML解析、XPath、单元测试、Assert、BeforeAfter、注解、自定义注解、注解案例_第6张图片 


 

七.Assert(断言):检验方法结果

public class Demo366JUnitAssert {
    @Test
    public void method1(){
        Demo366JUnitAssert jt = new Demo366JUnitAssert();
        int res = jt.add(1, 1);
        //参数一:两个结果不一样的提示消息
        Assert.assertEquals("这个方法出错了",2,res);
    }
    public int add(int a,int b){
        return a*b;
    }
}

[Java学习日记]日志、类加载器、XML、DTD与schema、XML解析、XPath、单元测试、Assert、BeforeAfter、注解、自定义注解、注解案例_第7张图片 

 


 

八.使用before与after注解备份与还原数据

public class Demo367BeforeAfter {
    //在测试单元中,相对路径是在当前模块中,和类加载器一样
    final static String FILE_STR = "src\\Day36\\MyLog\\a.txt";
    final static String FILE_COPY ="src\\Day36\\MyLog\\aCopy.txt";
    @Test
    public void test(){
        boolean b = new File(FILE_STR).delete();
        Assert.assertTrue(b);
        b=new File(FILE_STR).exists();
        Assert.assertFalse(b);
        System.out.println("Test,在这个方法里面做测试");
    }
    @Before
    public void before(){
        FileUtil.copy(new File(FILE_STR),new File(FILE_COPY),false);
        System.out.println("before,使用这个方法初始化数据,比如数据的删除");

    }
    @After
    public void after(){
        FileUtil.copy(new File(FILE_COPY),new File(FILE_STR),false);
        new File(FILE_COPY).delete();
        System.out.println("after,使用这个方法还原数据,删除备份数据");
    }
}

[Java学习日记]日志、类加载器、XML、DTD与schema、XML解析、XPath、单元测试、Assert、BeforeAfter、注解、自定义注解、注解案例_第8张图片 

 


 

九.注解

注解主要是给编译器看的,用来检测
@Deprecated:表示方法已经过时:也会给你提示替代方案
@SuppressWarnings("all"):压制(去除)警告
@SuppressWarnings("all")
public class Demo368Annotation {
    public static void main(String[] args) {
        int a;
    }
    @Deprecated
    public static void method(){
        System.out.println("haihai");
    }
}

 


 

十.自定义注解

自定义注解:结合反射使用
能在变量上使用,也能在方法中使用
public @interface MyAnno {
    //可以不写默认值
    public String name()default "???";
    public int age();
}
public class Demo369MyAnno {
    //如果注解中只有一个属性,就可以只写值,如压制警告
    @MyAnno(name = "啊?",age=20)
    String aaa;
    String bbb;
    @MyAnno(name = "啊?",age=20)
    public void method(){
        System.out.println("方法一");
    }
    public void method2(){
        System.out.println("方法二");
    }
}

 


 

十一.注解案例:用注解模拟JUnit

元注解:注解的注解
@Target:约束注解使用的地方
@Retention:申明注解的生命周期
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTest {}
public class Main {
    public static void main(String[] args) throws ClassNotFoundException, InvocationTargetException, IllegalAccessException {
        Class aClass = Class.forName("Day36.Demo3610.Main");
        //补个对象
        Main main = new Main();
        Method[] methods = aClass.getMethods();
        for (Method method : methods) {
            method.setAccessible(true);
            if (method.isAnnotationPresent(MyTest.class)){
                method.invoke(main);
            }
        }
    }

    @MyTest
    public void method1(){
        System.out.println("方法一");
    }
    @MyTest
    public void method2(){
        System.out.println("方法二");
    }
    public void method3(){
        System.out.println("方法三");
    }
}

你可能感兴趣的:(JAVA黑马程序员笔记分享,java,学习,xml)