单元测试、反射、注解、动态代理

目录

一.单元测试

        1.单元测试概述

        2.单元测试快速入门

        3.单测试常用注解

二.反射

1.反射概述

2.反射获取类对象

3.反射获取构造器对象

4.反射获取成员变量对象

5.反射获取方法对象

6.反射的作用-绕过编译阶段为集合添加数据

7.反射的作用-通用框架的底层原理

三.注解

1.注解概述

2.自定义注解

3.元注解

4.注解解析

5.注解的应用场景一:junit框架

四.动态代理

1.动态代理概述,快速入门

​编辑

2.动态代理的应用案例: 做性能分析,代理的好处小结

​编辑

一.单元测试

        1.单元测试概述

        2.单元测试快速入门

package com.wjh.d1_junit;
/*
    测试类
 */

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

public class TestUserService {
    /*
    测试方法
    注意点:
        1.必须是公开的,无参数的,无返回值的方法
        2.测试方法必须使用@Test注解标记
     */
    @Test
    public void testLoginName(){
        UserService userService = new UserService();
        String rs = userService.loginName("admin", "123456");
        //System.out.println(rs);

        //进行预期结果的正确性测试:断言.
        Assert.assertEquals("你的功能业务可能出现问题", "登录成功", rs);

    }

    @Test
    public void testSelectNames(){
        UserService userService = new UserService();
        userService.selectNames();

    }



}

package com.wjh.d1_junit;

/*
业务方法
 */
public class UserService {
    public String loginName(String loginName, String passWord){
        if("admin2".equals(loginName) && "123456".equals(passWord)){
            return "登录成功";
        } else {
            return "用户名密码有问题";
        }
    }

    public void selectNames(){
        System.out.println(10/0);
        System.out.println("查询全部用户名成功!");
    }
}

[root]
TestUserService.testLoginName
TestUserService.testSelectNames


java.lang.ArithmeticException: / by zero

	at com.wjh.d1_junit.UserService.selectNames(UserService.java:16)
	at com.wjh.d1_junit.TestUserService.testSelectNames(TestUserService.java:30)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
	at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
	at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
	at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:221)
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)

        3.单测试常用注解

package com.wjh.d1_junit;
/*
    测试类
 */

import org.junit.*;

public class TestUserService {

    //只能修饰实例方法
    @Before
    public void before(){
        System.out.println("=====before方法执行一次=====");
    }

    @Before
    public void after(){
        System.out.println("=====after方法执行一次=====");
    }

    //修饰静态方法
    @BeforeClass
    public static void beforeClass(){
        System.out.println("=====beforeClass方法执行一次=====");
    }

    @AfterClass
    public static void afterClass(){
        System.out.println("=====afterClass方法执行一次=====");
    }

    /*
    测试方法
    注意点:
        1.必须是公开的,无参数的,无返回值的方法
        2.测试方法必须使用@Test注解标记
     */
    @Test
    public void testLoginName(){
        UserService userService = new UserService();
        String rs = userService.loginName("admin", "123456");
        //System.out.println(rs);

        //进行预期结果的正确性测试:断言.
        Assert.assertEquals("你的功能业务可能出现问题", "登录成功", rs);

    }

    @Test
    public void testSelectNames(){
        UserService userService = new UserService();
        userService.selectNames();

    }



}

=====beforeClass方法执行一次=====
=====after方法执行一次=====
=====before方法执行一次=====
=====after方法执行一次=====
=====before方法执行一次=====
10
查询全部用户名成功!
=====afterClass方法执行一次=====

进程已结束,退出代码为 0

 

二.反射

1.反射概述

 

2.反射获取类对象

 

package com.wjh.d2_reflect_class;
/*
    目标:
        反射第一步:获取Class对象
 */

public class Test {
    public static void main(String[] args) throws Exception {
        //1.Class类中的静态方法:forName(全限名:包名 + 类名)
        Class c = Class.forName("com.wjh.d2_reflect_class.Student");

        System.out.println(c);  //Student.Class
        //class com.wjh.d2_reflect_class.Student

        //2.类名.class
        Class c1 = Student.class;
        System.out.println(c1);
        //class com.wjh.d2_reflect_class.Student

        //3.对象.getClass() 获取对应类的Class对象
        Student s = new Student();
        Class c2 = s.getClass();
        System.out.println(c2);
        //class com.wjh.d2_reflect_class.Student



    }
}

class com.wjh.d2_reflect_class.Student
class com.wjh.d2_reflect_class.Student
class com.wjh.d2_reflect_class.Student

进程已结束,退出代码为 0

3.反射获取构造器对象

 

package com.wjh.d2_reflect_constructor;

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

    public Student() {
        System.out.println("无参构造器执行!");
    }

    private Student(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;
    }

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

package com.wjh.d2_reflect_constructor;

import org.junit.Test;

import java.lang.reflect.Constructor;

public class TestStudent1 {

//    1.Constructor<?>[] getConstructors()
//    返回所有构造器对象的数组(只能拿public的)
    @Test
    public void getConstructors(){
        //a.第一步:获取类对象
        Class c = Student.class;

        //b.提取类中的全部构造器对象(只能拿public的)
        Constructor[] constructors = c.getConstructors();

        //c.遍历构造器
        for (Constructor constructor : constructors) {
            System.out.println(constructor.getName() + "===>" + constructor.getParameterCount());
        }

    }

//    2.Constructor<?>[] getDeclaredConstructors()
//    返回所有构造器对象的数组,存在就能拿到
    @Test
    public void getDeclaredConstructors(){
        //a.第一步:获取类对象
        Class c = Student.class;

        //b.提取类中的全部构造器对象(能拿全部的)
        Constructor[] constructors = c.getDeclaredConstructors();

        //c.遍历构造器
        for (Constructor constructor : constructors) {
            System.out.println(constructor.getName() + "===>" + constructor.getParameterCount());
        }

    }



//    3.Constructor<T> getConstructor(Class<?>... parameterTypes)
//    返回单个构造器对象(只能拿public的)
    @Test
    public void getConstructor() throws NoSuchMethodException {
        //a.第一步:获取类对象
        Class c = Student.class;

        //b.定位单个构造器对象(按照参数定位无参构造器, 只能那public修饰的)
        Constructor constructor = c.getConstructor();

        //c.遍历构造器
            System.out.println(constructor.getName() + "===>" + constructor.getParameterCount());


    }


//    4.Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
//    返回单个构造器对象,存在就能拿到
@Test
public void getDeclaredConstructor() throws NoSuchMethodException {
    //a.第一步:获取类对象
    Class c = Student.class;

    //b.定位单个构造器对象(按照参数定位无参构造器, 只能那public修饰的,能拿所有构造器)
    Constructor constructor = c.getDeclaredConstructor();
    System.out.println(constructor.getName() + "===>" + constructor.getParameterCount());

    //c.定位某个有参构造器
    Constructor constructor1 = c.getDeclaredConstructor(String.class, int.class);
    System.out.println(constructor1.getName() + "===>" + constructor1.getParameterCount());

}

}

package com.wjh.d2_reflect_constructor;

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

    private Student() {
        System.out.println("无参构造器执行!");
    }

    public Student(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;
    }

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

package com.wjh.d2_reflect_constructor;

import org.junit.Test;

import java.lang.reflect.Constructor;

public class TestStudent2 {
    //1.调用无参构造器得到一个类的对象返回
    @Test
    public void getDeclaredConstructor() throws Exception {
        //a.第一步:获取类对象
        Class c = Student.class;

        //b.定位单个构造器对象(按照参数定位无参构造器, 只能那public修饰的,能拿所有构造器)
        Constructor constructor = c.getDeclaredConstructor();
        System.out.println(constructor.getName() + "===>" + constructor.getParameterCount());
        //如果遇到私有的构造器,可以暴力反射
        constructor.setAccessible(true);    //权限被打开

        Student s = (Student) constructor.newInstance();
        System.out.println(s);


        //c.定位某个有参构造器
        Constructor constructor1 = c.getDeclaredConstructor(String.class, int.class);
        System.out.println(constructor1.getName() + "===>" + constructor1.getParameterCount());


        Student s1 = (Student) constructor1.newInstance("小黑子", 1000);
        System.out.println(s1);

    }

    //2.调用有参构造器得到一个类的对象返回


}

4.反射获取成员变量对象

 

package com.wjh.d4_reflect_field;

public class Student {
        private String name;
        private int age;
        public static String schoolName;
        public static final String COUNT = "中国";


        public Student() {
            System.out.println("无参构造器执行!");
        }

        public Student(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;
        }

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

package com.wjh.d4_reflect_field;


import org.junit.Test;

import java.lang.reflect.Field;

//    Field[] getFields()	返回所有成员变量对象的数组(只能拿public的)
//    Field[] getDeclaredFields()	返回所有成员变量对象的数组,存在就能拿到
//    Field getField(String name)	返回单个成员变量对象(只能拿public的)
//    Field getDeclaredField(String name)	返回单个成员变量对象,存在就能拿到Field[] getFields()	返回所有成员变量对象的数组(只能拿public的)
//    Field[] getDeclaredFields()	返回所有成员变量对象的数组,存在就能拿到
//    Field getField(String name)	返回单个成员变量对象(只能拿public的)
//    Field getDeclaredField(String name)	返回单个成员变量对象,存在就能拿到
public class FieldDemo1 {
    /*
        1.获取全部的成员变量
        Field[] getDeclareFields();
        获取所有的成员变量对应的Field对象,只要申明了就可以得到
     */
    @Test
    public void getDeclareFields(){
        //a.定位class对象
        Class c = Student.class;
        //b.定位全部成员变量
        Field[] fields = c.getDeclaredFields();
        //c.遍历一下
        for (Field field : fields) {
            System.out.println(field.getName() + "===>" + field.getType());
        }
    }



    /*
        2.获取某个成员变量对象
     */
    @Test
    public void getDeclaredField() throws NoSuchFieldException {
        //a.定位class对象
        Class c = Student.class;
        //b.根据名称定位某个成员变量
        Field f = c.getDeclaredField("age");
        //c.遍历一下
        System.out.println(f.getName() + "===>" + f.getType());
    }



}

package com.wjh.d4_reflect_field;

import java.lang.reflect.Field;
import org.junit.Test;

public class FieldDemo2 {

    @Test
    public void getDeclareFields() throws Exception {
        //a.定位class对象
        Class c = Student.class;
        //b.提取某个成员变量
        Field ageF = c.getDeclaredField("age");

        ageF.setAccessible(true);

        //c.赋值
        Student s = new Student();
        ageF.set(s, 18);
        System.out.println(s);

        //d.取值
        int age = (int) ageF.get(s);
        System.out.println(age);

    }

}

 

5.反射获取方法对象

package com.wjh.d5_reflect_method;

public class Dog {
    private String name;

    public Dog() {
    }

    public Dog(String name) {
        this.name = name;
    }

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

    public void run(){
        System.out.println("狗跑得很快!");
    }

    public void eat(){
        System.out.println("狗吃骨头");
    }

    private String eat(String name){
        System.out.println("狗吃" + name);
        return "吃得很开心";
    }

    public static void inAddress(){
        System.out.println("在南工很多人学习Java");
    }

    public String getName(){
        return name;
    }

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


}
package com.wjh.d5_reflect_method;

import org.junit.Test;

import java.lang.reflect.Method;

public class MethodDemo01 {
    /*
    1.获得类中所有成员方法对象
     */
    @Test
    public void getDeclaredMethods(){
        //a.获取类对象
        Class c = Dog.class;
        //b.提取全部方法,包括私有的
        Method[] methods = c.getDeclaredMethods();
        //c.遍历全部方法
        for (Method method : methods) {
            System.out.println("方法名:" + method.getName() + " 返回值类型:" + method.getReturnType() + " 参数个数:" + method.getParameterCount());
        }
    }


    /*
    2.获得某个方法对象
     */
    @Test
    public void getDeclaredMethod() throws Exception {
        //a.获取类对象
        Class c = Dog.class;
        //b.提取单个方法对象
        Method method = c.getDeclaredMethod("eat");
        Method method2 = c.getDeclaredMethod("eat", String.class);
        //c.
        System.out.println("方法名:" + method.getName() + " 返回值类型:" + method.getReturnType() + " 参数个数:" + method.getParameterCount());

    }
}

方法名:eat 返回值类型:void 参数个数:0
方法名:getName 返回值类型:class java.lang.String 参数个数:0
方法名:run 返回值类型:void 参数个数:0
方法名:toString 返回值类型:class java.lang.String 参数个数:0
方法名:setName 返回值类型:void 参数个数:1
方法名:eat 返回值类型:void 参数个数:0
方法名:eat 返回值类型:class java.lang.String 参数个数:1
方法名:inAddress 返回值类型:void 参数个数:0

进程已结束,退出代码为 0

 

@Test
    public void getDeclaredMethod() throws Exception {
        //a.获取类对象
        Class c = Dog.class;
        //b.提取单个方法对象
        Method method = c.getDeclaredMethod("eat");
        Method method2 = c.getDeclaredMethod("eat", String.class);
        System.out.println("方法名:" + method.getName() + " 返回值类型:" + method.getReturnType() + " 参数个数:" + method.getParameterCount());

        method.setAccessible(true);
        method2.setAccessible(true);

        //c.触发方法的执行
        Dog d = new Dog();
        //注意:方法如果是没有结果回来的,那么返回的是null
        Object result =  method.invoke(d);
        System.out.println(result); //null

        method2.invoke(d, "骨头头");
        Object result2 =  method.invoke(d);
        System.out.println(result2); 
    }


狗吃骨头头
狗吃骨头
null

进程已结束,退出代码为 0

6.反射的作用-绕过编译阶段为集合添加数据

package com.wjh.d6_reflect_genericity;

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

public class ReflectDemo {
    public static void main(String[] args) throws Exception {
        //需求:反射实现泛型擦除后,加入其他类型的元素
        ArrayList<String> list1 = new ArrayList<>();
        ArrayList<Integer> list2 = new ArrayList<>();
        System.out.println(list1.getClass());   //class java.util.ArrayList
        System.out.println(list2.getClass());   //class java.util.ArrayList

        System.out.println(list1.getClass() == list2.getClass());   //Class文件是否一样 -> true

        System.out.println("==================================");
        ArrayList<Integer> list3 = new ArrayList<>();

        list3.add(23);
        list3.add(24);
        //list3.add("南工");

        Class c = list3.getClass(); //ArrayList.class ==> public boolean add(E e){}
        //定位c类中的add方法
        Method add = c.getDeclaredMethod("add", Object.class);
        boolean rs = (boolean) add.invoke(list3, "南工");
        System.out.println(rs);

        System.out.println(list3);



    }
}

 class java.util.ArrayList
class java.util.ArrayList
true
==================================
true
[23, 24, 南工]

进程已结束,退出代码为 0

ArrayList list4 = list3;
        list4.add("牛马");
        list4.add(23);
        list4.add(false);
        System.out.println(list4);  //[23, 24, 南工, 牛马, 23, false]

7.反射的作用-通用框架的底层原理

 

package com.wjh.d7_reflect_framework;

public class Student {
    private String name;
    private char sex;
    private int age;
    private String className;
    private String hobby;

    public Student() {
    }

    public Student(String name, char sex, int age, String className, String hobby) {
        this.name = name;
        this.sex = sex;
        this.age = age;
        this.className = className;
        this.hobby = hobby;
    }

    public String getName() {
        return name;
    }

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

    public char getSex() {
        return sex;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getClassName() {
        return className;
    }

    public void setClassName(String className) {
        this.className = className;
    }

    public String getHobby() {
        return hobby;
    }

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

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", sex=" + sex +
                ", age=" + age +
                ", className='" + className + '\'' +
                ", hobby='" + hobby + '\'' +
                '}';
    }
}
package com.wjh.d7_reflect_framework;

public class Teacher {
    private String name;
    private char sex;
    private double salary;

    public Teacher() {
    }

    public Teacher(String name, char sex, double salary) {
        this.name = name;
        this.sex = sex;
        this.salary = salary;
    }

    public String getName() {
        return name;
    }

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

    public char getSex() {
        return sex;
    }

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

    public double getSalary() {
        return salary;
    }

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

    @Override
    public String toString() {
        return "Teacher{" +
                "name='" + name + '\'' +
                ", sex=" + sex +
                ", salary=" + salary +
                '}';
    }
}
package com.wjh.d7_reflect_framework;

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

public class MyBatisUtil {
    /**
     * 保存任意类型的对象
     * @param obj
     */
    public static void save(Object obj){
        try(
            PrintStream ps = new PrintStream(new FileOutputStream("D:\\JavaDemo\\JavaSEPro\\JavaSEProMax\\junit-reflect-annotation-app\\src\\date.txt",true));
            ) {
            //1.提取这个对象的全部成员变量.只有反射可以解决
            Class c = obj.getClass();   // (c.getSimpleName() 获取当前类名 c.getName获取全限名: 包名 + 类名)
            ps.println("\n==========" + c.getSimpleName() + "=========");
            //2.提取他的全部成员变量
            Field[] fields = c.getDeclaredFields();
                //3.获取成员变量的信息
                for (Field field : fields) {
                    String name = field.getName();
                    //提取本成员变量在obj对象中的值(取值)
                    field.setAccessible(true);
                    String value = field.get(obj) + "";
                    ps.println(name + " = " + value);
                }
                //ps.close();
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }



==========Student=========
name = 猪八戒
sex = 男
age = 1000
className = 幼儿园大班
hobby = 吃饭,睡觉

==========Teacher=========
name = 波妞
sex = 女
salary = 30000.0

三.注解

1.注解概述

2.自定义注解

package com.wjh.d8_annotation;
/*
    目标:学会自定义注解+,掌握其定义格式和语法
 */
@MyBook(name = "<<精通JavaSE>>", authors = {"iKun", "小黑子"}, price = 50.5)
public class AnnotationDemo1 {

    @MyBook(name = "<<精通JavaSE>>", authors = {"iKun", "小黑子"}, price = 50.5)
    private AnnotationDemo1(){
        
    }
    
    @MyBook(name = "<<精通JavaSE>>", authors = {"iKun", "小黑子"}, price = 50.5)
    public static void main(String[] args) {
        int age = 21;
    }
    
}

package com.wjh.d8_annotation;

public @interface MyBook {
    //public String name();
    String name();
    String[] authors();
    double price();
    
}

package com.wjh.d8_annotation;

public @interface Book {
    String value(); //特殊属性
    double price() default 9.9;
}
 //@Book(value = "/delete")
    @Book(value = "/delete", price = 23.5)
    //@Book("/delete")
    private AnnotationDemo1(){

    }

3.元注解

package com.wjh.d8_annotation;

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

@Target({ElementType.METHOD, ElementType.FIELD})   //元注解
@Retention(RetentionPolicy.RUNTIME) //一直活着,在运行阶段这个注解也不会消失
public @interface MyTest {

}
package com.wjh.d8_annotation;
/*
    目标:认识元注解
 */
//@MyTest //只能注解申明过方法和成员变量
public class AnnotationDemo2 {

    @MyTest
    private String name;

    @MyTest
    public void test(){
        
    }

    public static void main(String[] args) {


    }

}

4.注解解析

package com.wjh.d8_annotation;
/*
    目标:完成注解的解析
 */
import org.junit.Test;
import java.lang.reflect.Method;
import java.util.Arrays;

public class AnnotationDemo3 {

    @Test
    public void parseMethod() throws Exception {
        //a.先得到类对象
        Class c = BookStore.class;

        Method m = c.getDeclaredMethod("test");

        //b.判断这个类上面是否存在这个注解
        if(c.isAnnotationPresent(Bokk.class)){
            //c.直接获取该注解对象
            Bokk book =(Bokk)c.getDeclaredAnnotation(Bokk.class);
            System.out.println(book.value());
            System.out.println(book.price());
            System.out.println(Arrays.toString(book.authors()));
        }
    }
}

@Bokk(value = "<<琅琊榜>>", price = 99.9, authors = {"苏哲", "蒙挚"})
class BookStore{

    @Bokk(value = "<<jjj>>", price = 19.9, authors = {"www", "hhh"})
    public void test(){

    }

}
package com.wjh.d8_annotation;

public @interface Bokk {
    //String name();
    double price();
    String[] authors();
    String value();
}

5.注解的应用场景一:junit框架

package com.wjh.d8_annotation;
/*
    目标:认识元注解
 */


import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

public class AnnotationDemo4 {

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

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

    /**
     * 启动菜单:有注解的才调用
     * @param args
     */
    public static void main(String[] args) throws Exception{
        AnnotationDemo4 t = new AnnotationDemo4();
        //a.获取类对象
        Class c = AnnotationDemo4.class;
        //b.提取全部方法
        Method[] methods = c.getDeclaredMethods();
        //c.遍历方法看是否有注解
        for (Method method : methods) {
            if(method.isAnnotationPresent(MyTest.class)){
                //跑他
                method.invoke(t);
            }
        }
    }

}

===test1===
===test3===

进程已结束,退出代码为 0

四.动态代理

1.动态代理概述,快速入门

 

 

package com.wjh.d9_proxy;

public class Star implements Skill{
    private String name;

    public Star() {
    }

    public Star(String name) {
        this.name = name;
    }

    @Override
    public void jump() {
        System.out.println(name + "开始跳舞!!");
    }

    @Override
    public void sing() {
        System.out.println(name + "开始唱歌!!");

    }
}
package com.wjh.d9_proxy;
/*
代理接口类
 */
public interface Skill {
    void jump();    //跳舞
    void sing();    //唱歌
}
package com.wjh.d9_proxy;

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

public class StarAgentProxy {
    /**
     * 设计一个方法来返回一个明星对象的代理对象
     *
     */
    public static Skill getProxy(Star obj){
        //为ycy这个对象,生成一个代理对象
        /*
        public static Object newProxyInstance(ClassLoader loader,
                    Class<?>[] interfaces,对象的实现接口列表
                    InvocationHandler h)
         */
        return (Skill) Proxy.newProxyInstance(obj.getClass().getClassLoader(),
                obj.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("收首付款");
                        //真正的让ycy去唱歌和跳舞...
                        //method 正在调用的方法和对象     args 代表这个方法的参数
                        Object rs = method.invoke(obj, args);
                        System.out.println("收首付款,把ycy接回来!");
                        return rs;
                    }
                });

    }
}
package com.wjh.d9_proxy;

public class Test {
    public static void main(String[] args) {
        //目标:学习开发出一个代理对象出来,理解动态代理执行流程
        //1.创建一个对象(ycy),对象的类必须实现接口

        Star s = new Star("杨程宇");

        //为ycy对象,生成一个代理对象(经纪人)
        Skill s2 = StarAgentProxy.getProxy(s);
        s2.jump();  //走代理的
        s2.sing();



    }
}

收首付款
杨程宇开始跳舞!!
收首付款,把ycy接回来!
收首付款
杨程宇开始唱歌!!
收首付款,把ycy接回来!

进程已结束,退出代码为 0
 

 

2.动态代理的应用案例: 做性能分析,代理的好处小结

package com.wjh.d10_proxy2;

public interface UserService {
    String login(String loginName, String passWord);

    void deleteUser();

    String selectUsers();

}

package com.wjh.d10_proxy2;
//实现类

public class UserServiceImpl implements UserService {
    @Override
    public String login(String loginName, String passWord) {
        long startTime = System.currentTimeMillis();
        String rs = "用户名或密码有误!";
        if ("admin".equals(loginName) && "123456".equals(passWord)) {
            rs = "登录成功!";
        }
        try {
            Thread.sleep(1000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        long endTime = System.currentTimeMillis();
        System.out.println("login方法耗时:" + (endTime - startTime) / 1000.0 + "s");
        return rs;
    }

    @Override
    public void deleteUser() {
        long startTime = System.currentTimeMillis();
        try {
            System.out.println("正在删除数据...");
            Thread.sleep(2000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        long endTime = System.currentTimeMillis();
        System.out.println("delete方法耗时:" + (endTime - startTime) / 1000.0 + "s");

    }

    @Override
    public String selectUsers() {
        long startTime = System.currentTimeMillis();
        String rs = "查询了10000个用户";
        try {
            Thread.sleep(3000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        long endTime = System.currentTimeMillis();
        System.out.println("select法耗时:" + (endTime - startTime) / 1000.0 + "s");
        return rs;
    }
}
package com.wjh.d10_proxy2;

public class Test {
    public static void main(String[] args) {
        //目标:掌握使用动态代理解决问题,理解使用动态代理的优势
        UserService userService = new UserServiceImpl();
        System.out.println(userService.login("admin", "123456"));
        System.out.println(userService.selectUsers());
        userService.deleteUser();
    }
}

login方法法耗时:1.008s
登录成功!
selectUsers方法法耗时:3.015s
查询了10000个用户
正在删除数据...
deleteUser方法法耗时:2.002s

进程已结束,退出代码为 0
 

 问题:

package com.wjh.d10_proxy2;

public interface UserService {
    String login(String loginName, String passWord);

    void deleteUser();

    String selectUsers();

    void deleteById(int id);

}

package com.wjh.d10_proxy2;
//实现类

public class UserServiceImpl implements UserService {
    @Override
    public String login(String loginName, String passWord) {

        String rs = "用户名或密码有误!";
        if ("admin".equals(loginName) && "123456".equals(passWord)) {
            rs = "登录成功!";
        }
        try {
            Thread.sleep(1000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return rs;
    }

    @Override
    public void deleteUser() {

        try {
            System.out.println("正在删除数据...");
            Thread.sleep(2000);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    @Override
    public String selectUsers() {

        String rs = "查询了10000个用户";
        try {
            Thread.sleep(3000);
        } catch (Exception e) {
            e.printStackTrace();
        }


        return rs;
    }

    @Override
    public void deleteById(int id) {
        try {
            System.out.println("根据用户的身份证号:" + id + "删除了该账户");
            Thread.sleep(1500);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
package com.wjh.d10_proxy2;


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

public class proxyUtil {
    /**
     * 通过一个静态方法:为用户业务对象返回一个代理对象
     */
    public static UserService getProxy(UserService obj){
        return (UserService) Proxy.newProxyInstance(obj.getClass().getClassLoader(),
                obj.getClass().getInterfaces(), new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        long startTime = System.currentTimeMillis();

                        //真正触发对象行为执行的
                        Object rs = method.invoke(obj, args);
                        //System.out.println(rs);

                        long endTime = System.currentTimeMillis();
                        System.out.println(method.getName() + "方法法耗时:" + (endTime - startTime) / 1000.0 + "s");
                        return rs;
                    }
                });
    }
}
package com.wjh.d10_proxy2;




public class Test {
    public static void main(String[] args) {
        //目标:掌握使用动态代理解决问题,理解使用动态代理的优势
        UserService userService = proxyUtil.getProxy(new UserServiceImpl());
        System.out.println(userService.login("admin", "123456"));
        System.out.println(userService.selectUsers());
        userService.deleteUser();
        userService.deleteById(162152);
    }
}

login方法法耗时:1.003s
登录成功!
selectUsers方法法耗时:3.003s
查询了10000个用户
正在删除数据...
deleteUser方法法耗时:2.004s
根据用户的身份证号:162152删除了该账户
deleteById方法法耗时:1.509s

进程已结束,退出代码为 0

package com.wjh.d10_proxy2;


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

public class proxyUtil {
    /**
     * 通过一个静态方法:为用户业务对象返回一个代理对象
     */
    public static <T> T getProxy(T obj){
        return (T) Proxy.newProxyInstance(obj.getClass().getClassLoader(),
                obj.getClass().getInterfaces(), new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        long startTime = System.currentTimeMillis();

                        //真正触发对象行为执行的
                        Object rs = method.invoke(obj, args);
                        //System.out.println(rs);

                        long endTime = System.currentTimeMillis();
                        System.out.println(method.getName() + "方法法耗时:" + (endTime - startTime) / 1000.0 + "s");
                        return rs;
                    }
                });
    }
}

为任意接口的实现类对象做代理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

程序员希西子

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值