【java】【高级技术】单元测试&&反射&&注解&&动态代理

目录

1 单元测试

1.1 概述

1.2 Junit框架快速入门

 1.3 案例1--Junit初体验​编辑

1.3.1 准备一个被测类 StringUnit

 1.3.2 为被测试类StringUnit定义一个对应的测试类StringUnitTest

 1.3.3 引入junit框架(在StringUnitTest操作)

 1.3.4 在测试方法执行测试

 1.3.5 查看结果

1.4 案例2 -- Junit--断言机制

1.4.1 准备一个被测类 StringUnit

 1.4.2 为被测试类StringUnit定义一个对应的测试类StringUnitTest

 1.4.3 执行,查看断言的效果

1.5 执行范围

1.5.1 方法上面执行

1.5.2 类上面执行

1.5.3 模块上面执行

1.6 Junit框架的常见注解(Junit4.XXX版本)

1.6.1 准备一个被测类 StringUnit

 1.6.2 为被测试类StringUnit定义一个对应的测试类StringUnitTest

 1.6.3 执行,查看运行结果

1.7 Junit框架的常见注解(Junit5.XXX版本)

2 反射(了解)

2.1 认识反射、获取类

2.1.1 Student类

2.1.2 TestClass1主函数

2.2 获取类的构造器

2.2.1 获取类构造器

2.2.1.1Cat类

 2.2.1.2 主函数 TestConstructor

 2.2.2 获取类构造器的作用

2.2.2.1 Cat类

 2.2.2.2 主函数 TestConstructor

2.3 获取类的成员变量

2.3.1 获取类的成员变量 

2.3.1.1 Cat2类

 2.3.1.2 主函数

 2.3.2 获取类的成员变量 作用

2.3.2.2 Cat2类

 2.3.2.2 主函数

2.4 获取类的成员方法

2.4.1 获取类的成员方法

2.4.1.1 Cat3类

 2.4.1.2 主函数

2.4.2 获取类的成员方法的作用

2.4.2.1 Cat3类

 2.4.2.2 主函数

2.5 作用、变量

2.5.1 Teacher类

 2.5.2 Student2类

2.5.3 ObjectFrame类

2.5.4 主方法

3 注解

3.1 概述、自定义注解

 3.1.1 注解MyTest1

 3.1.2 注解MyTest2(不要复制 MyTest1,我复制发现有问题)

 3.1.3 创建类AnnotationTest1 使用注解

3.2 注解的原理​编辑

3.3 元注解

3.4 注解的解析

 3.4.1 MyTest4 注解

 3.4.2 Demo类

 3.4.3 AnnotationTest3测试类

3.5 应用场景  -模拟Junit框架设计 

 3.5.1 MyTest注解

 3.5.2 测试方法AnnotationTest4

4 动态代理

4.1 程序为什么需要代理?代理长什么样?

 4.1.1 Star接口

 4.1.2 BigStar类

 4.1.3 ProxyUtil代理类

 4.1.4 主函数Test

4.2 动态代理解决实际问题、掌握使用代理的好处

4.2.1 接口UserService

4.2.2 实现接口类UserServiceImpl

4.2.3 代理工具类ProxyUtil

4.2.4 主函数Test


前言:单元测试Junit框架入门、反射、注解、动态代理使用

1 单元测试

1.1 概述

1.2 Junit框架快速入门

 1.3 案例1--Junit初体验

1.3.1 准备一个被测类 StringUnit

package com.runa;

public class StringUnit {

    public static void printNumber( String name){
        if(name == null){
            System.out.println(0);
            return; //停掉方法
        }

        System.out.println("名字的长度是:" + name.length());
    }



}


 1.3.2 为被测试类StringUnit定义一个对应的测试类StringUnitTest

package com.runa;

import org.junit.Test;

public class StringUnitTest {
    @Test //测试方法
    public void testPrintNumber(){
        StringUnit.printNumber("春天的菠菜");
        StringUnit.printNumber(null);
    }

  

}

 1.3.3 引入junit框架(在StringUnitTest操作)

在@Test 注释上按住Alt+ Enter,选择JUnit4

 OK

 1.3.4 在测试方法执行测试

 1.3.5 查看结果

 

 

1.4 案例2 -- Junit--断言机制

1.4.1 准备一个被测类 StringUnit

package com.runa;

public class StringUnit {

    public static void printNumber( String name){
        if(name == null){
            System.out.println(0);
            return; //停掉方法
        }

        System.out.println("名字的长度是:" + name.length());
    }

    /**
     * 求字符串的最大索引
     *
     */
    public static int getMaxIndex(String data){
        if(data == null){
            return -1;
        }
        return data.length(); // return data.length() - 1;
    }

}


 1.4.2 为被测试类StringUnit定义一个对应的测试类StringUnitTest

package com.runa;

import org.junit.Assert;
import org.junit.Test;

public class StringUnitTest {
    @Test //测试方法
    public void testPrintNumber(){
        StringUnit.printNumber("春天的菠菜");
        StringUnit.printNumber(null);
    }

    @Test //测试方法
    public void testGetMaxIndex(){
        int index1 = StringUnit.getMaxIndex(null);
        System.out.println(index1);
        int index2 =StringUnit.getMaxIndex("春天的菠菜");
        // 断言机制,程序员可以通过预测业务方法的结果
        Assert.assertEquals("不一致,方法有bug",4,index2);

    }

}

 1.4.3 执行,查看断言的效果

1.5 执行范围

1.5.1 方法上面执行

执行这个方法测试

1.5.2 类上面执行

执行这个类测试

1.5.3 模块上面执行

执行这个模块的测试

 

 

 

1.6 Junit框架的常见注解(Junit4.XXX版本)

 

1.6.1 准备一个被测类 StringUnit

package com.runa;

public class StringUnit {

    public static void printNumber( String name){
        if(name == null){
            System.out.println(0);
            return; //停掉方法
        }

        System.out.println("名字的长度是:" + name.length());
    }

    /**
     * 求字符串的最大索引
     *
     */
    public static int getMaxIndex(String data){
        if(data == null){
            return -1;
        }
        return data.length() - 1; // return data.length() - 1;
    }

}


 1.6.2 为被测试类StringUnit定义一个对应的测试类StringUnitTest

package com.runa;

import org.junit.*;

public class StringUnitTest {
    @Before
    public void test1(){
        System.out.println("每个测试方法开始的执行--------》Before");
    }

    @After
    public void test2(){
        System.out.println("每个测试方法结束的执行--------》After");
    }

    @BeforeClass
    public static void test3(){
        System.out.println("每个静态方法开始的执行--------》BeforeClass");
    }

    @AfterClass
    public static void test4(){
        System.out.println("每个静态方法结束的执行--------》AfterClass");
    }



    @Test //测试方法
    public void testPrintNumber(){
        StringUnit.printNumber("春天的菠菜");
        StringUnit.printNumber(null);
    }

    @Test //测试方法
    public void testGetMaxIndex(){
        int index1 = StringUnit.getMaxIndex(null);
        System.out.println(index1);
        int index2 =StringUnit.getMaxIndex("春天的菠菜");
        // 断言机制,程序员可以通过预测业务方法的结果
        Assert.assertEquals("不一致,方法有bug",4,index2);

    }

}

 1.6.3 执行,查看运行结果

1.7 Junit框架的常见注解(Junit5.XXX版本)

2 反射(了解)

2.1 认识反射、获取类

  

 

2.1.1 Student类

package com.reflect;

public class Student {



}

2.1.2 TestClass1主函数

package com.reflect;

public class TestClass1 {
    public static void main(String[] args) throws Exception {
        // 第一种方式
        Class c1 = Student.class;
        System.out.println(c1.getName()); // 全类名
        System.out.println(c1.getSimpleName());// 简名

        // 第二种方式
        Class  c2 = Class.forName("com.reflect.Student");
        System.out.println(c2.getName());
        System.out.println(c1 == c2);//三种方式都是同一对象

        // 第三种方式
        Student s = new Student();
        Class  c3 = s.getClass();
        System.out.println(c3.getName());
        System.out.println(c3 == c2); //三种方式都是同一对象

    }
}

 

  

2.2 获取类的构造器

2.2.1 获取类构造器

2.2.1.1Cat类
package com.reflect;

public class Cat {

    private String name;
    private int age;
   

    public Cat() {
    }

    public Cat(String name, int age) {
        this.name = name;
        this.age = age;
    }

     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;
    }

    
}
 2.2.1.2 主函数 TestConstructor
package com.reflect;

import org.junit.Test;

import java.lang.reflect.Constructor;

public class TestConstructor {
    // 查询全部构造器
    @Test
    public void  testGetConstructors(){
        //1   反射第一步:必须先得到这个类的Class对象
        Class c = Cat.class;
        // 获取类的全部构造器
        Constructor[] constructors = c.getDeclaredConstructors(); // c.getConstructors();  只能获取public修饰的的构造器
        // 遍历数组中的每个构造器对象
        for (Constructor constructor : constructors) {
            System.out.println(constructor.getName() + "--->" + constructor.getParameterCount()); //查询构造器名和 有几个查询
        }
    }


    // 查询单个构造器,有参和无参的两种类型
    @Test
    public void testGetConstructor() throws Exception {
        //1   反射第一步:必须先得到这个类的Class对象
        Class c = Cat.class;
        // 获取某个构造器,:无参的构造器
        Constructor constructor = c.getDeclaredConstructor(); // c.getConstructor(); 只能获取public修饰的
        System.out.println(constructor.getName() + "--->" + constructor.getParameterCount()); //查询构造器名和 有几个查询

        // 获取某个构造器,:有参的构造器
        Constructor constructor2 = c.getDeclaredConstructor(String.class, int.class); // c.getConstructor(); 只能获取public修饰的
        System.out.println(constructor2.getName() + "--->" + constructor2.getParameterCount()); //查询构造器名和 有几个查询
    }
}

 

 2.2.2 获取类构造器的作用

2.2.2.1 Cat类
package com.reflect;

public class Cat {
    private String name;
    private int age;
    

    @Override
    public String toString() {
        return "Cat{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public Cat() {
        System.out.println("无参数构造器执行了");
    }

    public Cat(String name, int age) {
        System.out.println("有参数构造器执行了");
        this.name = name;
        this.age = age;
    }
    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;
    }

  
}
 2.2.2.2 主函数 TestConstructor
package com.reflect;

import org.junit.Test;

import java.lang.reflect.Constructor;

public class TestConstructor {
    // 查询全部构造器
    @Test
    public void  testGetConstructors(){
        //1   反射第一步:必须先得到这个类的Class对象
        Class c = Cat.class;
        // 获取类的全部构造器
        Constructor[] constructors = c.getDeclaredConstructors(); // c.getConstructors();  只能获取public修饰的的构造器
        // 遍历数组中的每个构造器对象
        for (Constructor constructor : constructors) {
            System.out.println(constructor.getName() + "--->" + constructor.getParameterCount()); //查询构造器名和 有几个查询
        }
    }


    // 查询单个构造器,有参和无参的两种类型
    @Test
    public void testGetConstructor() throws Exception {
        //1   反射第一步:必须先得到这个类的Class对象
        Class c = Cat.class;
        // 获取某个构造器,:无参的构造器
        Constructor constructor = c.getDeclaredConstructor(); // c.getConstructor(); 只能获取public修饰的
        System.out.println(constructor.getName() + "--->" + constructor.getParameterCount()); //查询构造器名和 有几个查询
        constructor.setAccessible(true); // 禁止检查访问权限
        Cat cat = (Cat) constructor.newInstance();
        System.out.println(cat);

        // 获取某个构造器,:有参的构造器
        Constructor constructor2 = c.getDeclaredConstructor(String.class, int.class); // c.getConstructor(); 只能获取public修饰的
        System.out.println(constructor2.getName() + "--->" + constructor2.getParameterCount()); //查询构造器名和 有几个查询
        constructor2.setAccessible(true); // 禁止检查访问权限
        Cat cat2 = (Cat) constructor2.newInstance("TOM", 3);
        System.out.println(cat2);
    }
}

 

2.3 获取类的成员变量

2.3.1 获取类的成员变量 

2.3.1.1 Cat2类
package com.reflect;

public class Cat2 {
    public static int a;
    public static final String COUNTY = "中国";
    private String name;
    private int age;

    public Cat2() {
        System.out.println("无参数构造器执行了");
    }

    public Cat2(String name, int age) {
        System.out.println("有参数构造器执行了");
        this.name = name;
        this.age = age;
    }
    public static int getA() {
        return a;
    }

    public static void setA(int a) {
        Cat2.a = a;
    }

    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;
    }
}
 2.3.1.2 主函数
package com.reflect;

import org.junit.Test;

import java.lang.reflect.Field;

public class TestField {
    @Test
    public void testGetField() throws Exception {
        //1   反射第一步:必须先得到这个类的Class对象
        Class c = Cat2.class;

        // 2 获取类的全部成员变量
        Field[] fields = c.getDeclaredFields(); //c.getFields(); 只能拿public修饰的
        // 遍历
        for (Field field : fields) {
            System.out.println(field.getName() + "类型: " + field.getType());
        }

        // 3 获取单个成员变量
        Field field = c.getDeclaredField("name"); //c.getField(); 只能拿public修饰的
        System.out.println(field.getName() + "类型: " + field.getType());


    }

}

 

 2.3.2 获取类的成员变量 作用

2.3.2.2 Cat2类
package com.reflect;

public class Cat2 {
    public static int a;
    public static final String COUNTY = "中国";
    private String name;
    private int age;

    public Cat2() {
        System.out.println("无参数构造器执行了");
    }

    public Cat2(String name, int age) {
        System.out.println("有参数构造器执行了");
        this.name = name;
        this.age = age;
    }
    public static int getA() {
        return a;
    }

    public static void setA(int a) {
        Cat2.a = a;
    }

    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;
    }

    @Override
    public String toString() {
        return "Cat2{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
 2.3.2.2 主函数
package com.reflect;

import org.junit.Test;

import java.lang.reflect.Field;

public class TestField {
    @Test
    public void testGetField() throws Exception {
        //1   反射第一步:必须先得到这个类的Class对象
        Class c = Cat2.class;

        // 2 获取类的全部成员变量
        Field[] fields = c.getDeclaredFields(); //c.getFields(); 只能拿public修饰的
        // 遍历
        for (Field field : fields) {
            System.out.println(field.getName() + "类型: " + field.getType());
        }

        // 3 获取单个成员变量
        Field field = c.getDeclaredField("name"); //c.getField(); 只能拿public修饰的
        System.out.println(field.getName() + "类型: " + field.getType());

        // 赋值
        Cat2 cat = new Cat2();
        field.setAccessible(true); // 暴力反射,禁止访问控制权限
        field.set(cat, "咖啡猫");
        System.out.println(cat);

        // 取值
        String  name = (String) field.get(cat);
        System.out.println(name);


    }

}

 

2.4 获取类的成员方法

 

2.4.1 获取类的成员方法

2.4.1.1 Cat3类
package com.reflect;

public class Cat3 {
    public static int a;
    public static final String COUNTY = "中国";
    private String name;
    private int age;

    public Cat3() {
        System.out.println("无参数构造器执行了");
    }

    public Cat3(String name, int age) {
        System.out.println("有参数构造器执行了");
        this.name = name;
        this.age = age;
    }
    private void run(){
        System.out.println("跑得很快~~~~");
    }
    public void eat(){
        System.out.println("爱吃鱼~~~~");
    }

    private String eat(String name){
       return "最爱吃:" + name;

    }

    public static int getA() {
        return a;
    }

    public static void setA(int a) {
        Cat3.a = a;
    }

    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;
    }

    @Override
    public String toString() {
        return "Cat2{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
 2.4.1.2 主函数
package com.reflect;

import org.junit.Test;

import java.lang.reflect.Method;

public class TestMethod {
    @Test
    public void testGetMethods() throws Exception {
            //1   反射第一步:必须先得到这个类的Class对象
        Class c = Cat3.class;
        
        // 2 获取全部类的全部成员方法
        Method[] declaredMethods = c.getDeclaredMethods();
        // 3 遍历
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod.getName() + "-->"
                    + declaredMethod.getParameterCount()
                    + "-->" + declaredMethod.getReturnType());

        }
        System.out.println("=================");
        // 4 获取某个方法对象
        Method run = c.getDeclaredMethod("run"); //拿run方法 无参数
        System.out.println(run.getName() + "-->"
                + run.getParameterCount()
                + "-->" + run.getReturnType());

        Method eat = c.getDeclaredMethod("eat",String.class); //拿eat方法 有参数
        System.out.println(eat.getName() + "-->"
                + eat.getParameterCount()
                + "-->" + eat.getReturnType());

    }
}

 

2.4.2 获取类的成员方法的作用

2.4.2.1 Cat3类
package com.reflect;

public class Cat3 {
    public static int a;
    public static final String COUNTY = "中国";
    private String name;
    private int age;

    public Cat3() {
        System.out.println("无参数构造器执行了");
    }

    public Cat3(String name, int age) {
        System.out.println("有参数构造器执行了");
        this.name = name;
        this.age = age;
    }
    private void run(){
        System.out.println("跑得很快~~~~");
    }
    public void eat(){
        System.out.println("爱吃鱼~~~~");
    }

    private String eat(String name){
       return "最爱吃:" + name;

    }

    public static int getA() {
        return a;
    }

    public static void setA(int a) {
        Cat3.a = a;
    }

    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;
    }

    @Override
    public String toString() {
        return "Cat2{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
 2.4.2.2 主函数
package com.reflect;

import org.junit.Test;

import java.lang.reflect.Method;

public class TestMethod {
    @Test
    public void testGetMethods() throws Exception {
            //1   反射第一步:必须先得到这个类的Class对象
        Class c = Cat3.class;
        
        // 2 获取全部类的全部成员方法
        Method[] declaredMethods = c.getDeclaredMethods();
        // 3 遍历
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod.getName() + "-->"
                    + declaredMethod.getParameterCount()
                    + "-->" + declaredMethod.getReturnType());

        }
        System.out.println("=================");
        // 4 获取某个方法对象
        Method run = c.getDeclaredMethod("run"); //拿run方法 无参数
        System.out.println(run.getName() + "-->"
                + run.getParameterCount()
                + "-->" + run.getReturnType());

        Method eat = c.getDeclaredMethod("eat",String.class); //拿eat方法 有参数
        System.out.println(eat.getName() + "-->"
                + eat.getParameterCount()
                + "-->" + eat.getReturnType());

        Cat3 cat = new Cat3();
        run.setAccessible(true); // 禁止检查访问权限
        Object rs = run.invoke(cat); //调用无参数的run方法。用cat对象歘调用的
        System.out.println(rs);


        Cat3 cat2 = new Cat3();
        eat.setAccessible(true); // 禁止检查访问权限
        Object rs2 = eat.invoke(cat2,"鱼儿"); //调用有参数的eat方法。用cat对象歘调用的
        System.out.println(rs2);

    }
}

 

 

2.5 作用、变量

  

2.5.1 Teacher类

 

package com.reflect;

public class Teacher {
    private String name;
    private Double salary;

    public Teacher() {
    }

    public Teacher(String name, Double salary) {
        this.name = name;
        this.salary = salary;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Double getSalary() {
        return salary;
    }

    public void setSalary(Double salary) {
        this.salary = salary;
    }
}

 2.5.2 Student2类

package com.reflect;

public class Student2 {
    private String name;
    private int age;
    private char sex;
    private double height;
    private String hobby;

    public Student2() {
    }

    public Student2(String name, int age, char sex, double height, String hobby) {
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.height = height;
        this.hobby = hobby;
    }

    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 char getSex() {
        return sex;
    }

    public void setSex(char sex) {
        this.sex = sex;
    }

    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }

    public String getHobby() {
        return hobby;
    }

    public void setHobby(String hobby) {
        this.hobby = hobby;
    }
}

2.5.3 ObjectFrame类

package com.reflect;

import java.io.FileOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;

public class ObjectFrame {
    // 目标:保存任务对象的字段和其数据到文件中去
    public static void saveObject(Object obj) throws Exception {
        PrintStream ps = new PrintStream(new FileOutputStream("C:\\Users\\cheng\\IdeaProjects\\FirstJava\\opp-junit\\src\\data.txt", true));  // 这个地方没有使用相对路径成功,未找到原因
        // obj   是任意对象,到底有多少个字段要保存
        Class c = obj.getClass();
        String cName = c.getSimpleName();
        ps.println("-------------------" + cName + "--------------------");
        // 2 从这个类中提取它的全部成员变量
        Field[] fields = c.getDeclaredFields();
        // 3 遍历
        for (Field field : fields) {
            // 4 拿到成员变量的命中
            String name = field.getName();
            // 5 拿到这个成员遍历在对象中的数据
            field.setAccessible(true); // 禁止检查访问控制
            String value = field.get(obj) + "";
            ps.println(name + "=" + value);
        }
        ps.close();

    }
}

2.5.4 主方法

package com.reflect;

import org.junit.Test;

public class TestFrame {
    @Test
    public void save() throws  Exception{
        Student2 s1 = new Student2("菠菜", 30, '男' , 175, "实战");
        Teacher t1 = new Teacher("黑泽",999.88);

        // 需求:把任意对象的字段名和其对应的值等信息,保存到文件当中去
        ObjectFrame.saveObject(s1);
        ObjectFrame.saveObject(t1);
    }
}

 

3 注解

3.1 概述、自定义注解

 

 3.1.1 注解MyTest1

package com.annotation;

public @interface MyTest1 {
    String aaa();
    boolean bbb() default true;
    String[] ccc();
}

 3.1.2 注解MyTest2(不要复制 MyTest1,我复制发现有问题)

package com.annotation;

public @interface MyTest2 {
    String value();
}

 3.1.3 创建类AnnotationTest1 使用注解

package com.annotation;

@MyTest1(aaa="牛魔王",ccc={"HTML", "JAVA"})
//@MyTest2(value = "孙悟空")
@MyTest2("孙悟空")
public class AnnotationTest1 {
    @MyTest1(aaa="牛魔王",bbb = false, ccc={"python", "HTML", "JAVA"})
    public void test1(){

    }
}

3.2 注解的原理

   

3.3 元注解

 

 

  

3.4 注解的解析

 3.4.1 MyTest4 注解

package com.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTest4 {
    String value();
    double aaa() default 100;
    String[] bbb();
}

 3.4.2 Demo类

package com.annotation;
@MyTest4(value = "孙悟空", aaa = 100.01, bbb = {"紫霞仙子", "春天的菠菜"})
public class Demo {

    @MyTest4(value = "白骨精", aaa = 120.01, bbb = {"猪八戒", "春天的菠菜"})
    public void test1(){

    }
}

 3.4.3 AnnotationTest3测试类

package com.annotation;

import org.junit.Test;

import java.lang.reflect.Method;
import java.util.Arrays;

public class AnnotationTest3 {
    @Test
    public void parseClass(){
        // 1   先获得class对象
        Class c = Demo.class;
        // 2 解析类上的注解
        // 判断类上是否包含某个注解
        if(c.isAnnotationPresent(MyTest4.class)){
            MyTest4 myTest4 = (MyTest4) c.getDeclaredAnnotation(MyTest4.class);
            System.out.println(myTest4.value());
            System.out.println(myTest4.aaa());
            System.out.println(Arrays.toString(myTest4.bbb()));
        }
    }

    @Test
    public void parseMethod() throws Exception{
        // 1   先获得class对象
        Class c = Demo.class;
        // 2 再获得方法对象
        Method method = c.getDeclaredMethod("test1");
        // 2 解析方法上的注解
        // 判断方法上是否包含某个注解
        if(method.isAnnotationPresent(MyTest4.class)){
            MyTest4 myTest4 = (MyTest4) method.getDeclaredAnnotation(MyTest4.class);
            System.out.println(myTest4.value());
            System.out.println(myTest4.aaa());
            System.out.println(Arrays.toString(myTest4.bbb()));
        }
    }

}

 

 

3.5 应用场景  -模拟Junit框架设计 

 3.5.1 MyTest注解

package com.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD) //只能注解方法
@Retention(RetentionPolicy.RUNTIME) // 让当前注解可以一直存活
public @interface MyTest {
    
}

 3.5.2 测试方法AnnotationTest4

package com.annotation;

import java.lang.reflect.Method;

public class AnnotationTest4 {
//    @MyTest
    public void test1(){
        System.out.println("==============test1============");
    }

    @MyTest
    public void test2(){
        System.out.println("==============test2============");
    }

    @MyTest
    public void test3(){
        System.out.println("==============test3============");
    }

//    @MyTest
    public void test4(){
        System.out.println("==============test4============");
    }

    public static void main(String[] args) throws Exception{
        AnnotationTest4 a = new AnnotationTest4();
        // 启动程序
        // 1 得到class对象
        Class c = AnnotationTest4.class;
        // 2 提取全部成员方法
        Method[] methods = c.getDeclaredMethods();
        // 3 遍历数组的每个方法,看方法是否存在MyTest注解,存在触发执行
        for (Method method : methods) {
            if(method.isAnnotationPresent(MyTest.class)){
                //  说明当前方法上存在MyTest注解,触发执行
                method.invoke(a);

            }
        }


    }
}

 

 

4 动态代理

4.1 程序为什么需要代理?代理长什么样?

 

 

 4.1.1 Star接口

package com.proxy;

public interface Star {
    String sing(String name);
    void dance();
}

 4.1.2 BigStar类

package com.proxy;

public class BigStar implements Star{
    private String name;

    public BigStar(String name) {
        this.name = name;
    }
    public String sing(String name){
        System.out.println(this.name + "正在唱" + name);
        return "谢谢!谢谢";
    }

    public void dance(){
        System.out.println(this.name + "正在优雅的跳舞");
    }
}

 4.1.3 ProxyUtil代理类

package com.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyUtil {
    public static Star creatProxy(BigStar bigStar){
        // 参数1  用于指定一个类加载器
        // 参数2  指定生成的代理长生么样子,也就是有哪些方法
        // 参数3  用来指定生成的代理对象要干什么事情
        Star starProxy = (Star) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(),
                new Class[]{Star.class}, new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        // 代理对象要做的事情,会在这里写代码
                        if(method.getName().equals("sing")){
                            System.out.println("准备话筒,收钱100万");
                        }else if(method.getName().equals("dance")){
                            System.out.println("准备场地,收钱200万");
                        }
                        return method.invoke(bigStar, args);
                    }
                });
        return starProxy;
    }
}

 4.1.4 主函数Test

package com.proxy;

public class Test {
    public static void main(String[] args) {
        BigStar s = new BigStar("春天的菠菜");
        Star starProxy = ProxyUtil.creatProxy(s);
        String rs = starProxy.sing("柠檬树");
        System.out.println(rs);
        System.out.println("-------------------");
        starProxy.dance();
    }
}

 

 

4.2 动态代理解决实际问题、掌握使用代理的好处

4.2.1 接口UserService

 

package com.proxy2;

public interface UserService {
    // 登录功能
    void login(String loginName, String password) throws Exception;

    // 删除用户
    void deleteUsers() throws Exception;
    // 查询用户,返回数组形式
    String[] selectUsers() throws Exception;
}

4.2.2 实现接口类UserServiceImpl

package com.proxy2;

public class UserServiceImpl implements UserService {

    @Override
    public void login(String loginName, String password) throws Exception {
        if("admin".equals(loginName) && "123456".equals(password)){
            System.out.println("您登录成功!,欢迎您~~~");
        }else{
            System.out.println("你登录失败,用户名或密码错误~");
        }

    }

    @Override
    public void deleteUsers() throws Exception {
        System.out.println("成功删除了10万个用户~");
        Thread.sleep(1500);


    }

    @Override
    public String[] selectUsers() throws Exception {
        System.out.println("查询出了3个用户");
        String[] names = {"邱淑贞", "小玛丽", "黑泽"};
        Thread.sleep(500);
        return names;
    }
}

4.2.3 代理工具类ProxyUtil

package com.proxy2;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyUtil {
    public static UserService createProxy(UserService userService){
        UserService userServiceProxy = (UserService) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(),
                new Class[]{UserService.class}, new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        if(method.getName().equals("login") || method.getName().equals("deleteUsers")
                                || method.getName().equals("selectUsers")){
                            long startTime = System.currentTimeMillis();
                            Object rs = method.invoke(userService, args);

                            long endTime = System.currentTimeMillis();
                            System.out.println(method.getName() + "方法执行耗时:" + (endTime - startTime) / 1000.0 + "s");
                            return rs;
                        }else{
                            Object rs = method.invoke(userService, args);
                            return rs;
                        }
                    }
                });
        return userServiceProxy;
    }
}

4.2.4 主函数Test

package com.proxy2;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyUtil {
    public static UserService createProxy(UserService userService){
        UserService userServiceProxy = (UserService) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(),
                new Class[]{UserService.class}, new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        if(method.getName().equals("login") || method.getName().equals("deleteUsers")
                                || method.getName().equals("selectUsers")){
                            long startTime = System.currentTimeMillis();
                            Object rs = method.invoke(userService, args);

                            long endTime = System.currentTimeMillis();
                            System.out.println(method.getName() + "方法执行耗时:" + (endTime - startTime) / 1000.0 + "s");
                            return rs;
                        }else{
                            Object rs = method.invoke(userService, args);
                            return rs;
                        }
                    }
                });
        return userServiceProxy;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

春天的菠菜

一毛两毛也是动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值