Java: dynamic proxy and reflection

One, class loading

1.1 class loading process

[External link image transfer failed. The source site may have an anti-hotlinking mechanism. It is recommended to save the image and upload it directly (img-KsU0EnAU-1610806508512)(C:\Users\24582\AppData\Roaming\Typora\typora-user-images\ image-20210106213109276.png)]
[External link image transfer failed. The source site may have an anti-hotlinking mechanism. It is recommended to save the image and upload it directly (img-re5OL81p-1610806508514)(C:\Users\24582\AppData\Roaming\Typora\typora-user-images\ image-20210106213248173.png)]

1.2 class loader

Insert picture description here

Second, reflection

2.1 Definition of reflection

The java reflection mechanism is in the running state, for any class, you can know the attributes and methods of this class. For any object, any one of its methods and properties can be called. This kind of dynamic acquisition of information and dynamic call object method function is called the reflection mechanism of java language

2.2 Get the Class object

/**
 * 反射:通过.class文件对象,去使用该文件中的成员变量、成员属性、成员方法
 */

public class demo1 {
    
    
    public static void main(String[] args) throws ClassNotFoundException {
    
    
        //获取Class对象
        //方式1:Object类中的getclass
        Student student = new Student("张三",18);
        Class c1 = student.getClass();
        //方式2:任意数据类型的静态class-----练习中使用
        Class c2 = Student.class;

        Student student2 = new Student("张三",18);
        Class c3 = student2.getClass();

//        System.out.println(c1==c2);//true
//        System.out.println(student==student2);//false
//        System.out.println(c1==c3);//true

        //方式3:通过Class类中的静态方法,必须指定路径----------开发中常使用
        Class c4 = Class.forName("org.wdit.Reflect.Student");
        System.out.println(c1==c4);//true
    }
}

2.3 Get the construction method

/**
 * 构造方法获取
 */

public class demo2 {
    
    
    public static void main(String[] args) throws Exception {
    
    
        Class c1 = Student.class;
        //获取所有公共修饰的方法
        Constructor[] constructors = c1.getConstructors();
        for (Constructor con : constructors) {
    
    
            System.out.println(con);
        }
        System.out.println("-------------------------------------------");
        //获取所有的构造方法
        Constructor[] declaredConstructors = c1.getDeclaredConstructors();
        for (Constructor con : declaredConstructors) {
    
    
            System.out.println(con);
        }
        System.out.println("---------------------------------------------");
        //获取一个公共的构造方法
        Constructor constructor = c1.getConstructor();
        System.out.println("------------------------------------------");
        //创建一个类对象的实例
        Object object = constructor.newInstance();
        System.out.println(object);

        System.out.println("-------------------------------------------");

        Constructor constructor1 = c1.getConstructor(String.class, int.class, String.class);
        Object o = constructor1.newInstance("李四",18,"男");
        System.out.println(o);
    }
}

2.4 Get the structure of private methods

/**
 * 通过私有方法创建对象
 */
public class demo3 {
    
    
    public static void main(String[] args) throws Exception {
    
    
        Class c = Class.forName("org.wdit.Reflect.Student");
        //获取构造方法
        Constructor constructor = c.getDeclaredConstructor(String.class);
        constructor.setAccessible(true);
        Object o = constructor.newInstance("lily");
        System.out.println(o);
    }
}

2.5 Get member variables

/**
 * 获取成员变量:
 */
public class demo4 {
    
    
    public static void main(String[] args) throws Exception{
    
    
        Class c = Student.class;
        //获取所有公共的成员变量
        Field[] fields = c.getFields();
        for (Field f:fields){
    
    
            System.out.println(f);
        }
        System.out.println("-----------------------------");
        //获取所有成员变量
        Field[] declaredFields = c.getDeclaredFields();
        for (Field f:declaredFields) {
    
    
            System.out.println(f);
        }
        System.out.println("------------------------------");

        Constructor constructor = c.getConstructor();
        Object obj = constructor.newInstance();
        System.out.println(obj);
        //获取单个成员变量
        Field sex = c.getField("sex");
        Field name = c.getDeclaredField("name");
        Field age = c.getDeclaredField("age");
        sex.set(obj,"男");
        name.setAccessible(true);
        name.set(obj,"张三");
        age.set(obj,18);
        System.out.println(obj);
    }
}

//建议日后使用中,无论什么修饰权限的,我们都使用带Declared,以及设置Accessible

2.6 Member method

/**
 * 成员方法:
 */
public class demo5 {
    
    
    public static void main(String[] args) throws Exception {
    
    
        Class c = Class.forName("org.wdit.Reflect.Student");
        //获取全部成员方法 自己以及父类
        Method[] methods = c.getMethods();
        for (Method m:methods) {
    
    
            System.out.println(m);
        }
        System.out.println("---------------------------------------------");
        //获取自己的成员方法
        Method[] declaredMethods = c.getDeclaredMethods();
        for (Method m:declaredMethods) {
    
    
            System.out.println(m);
        }
        System.out.println("-------------------------------------------");
        //获取单个成员方法并使用
        Constructor constructor = c.getConstructor();
        Object o = constructor.newInstance();
        Method method = c.getMethod("show1");
        //o.show1(); 写法错误
        method.invoke(o);
        System.out.println("---------------------------------------------");
        Method method2 = c.getMethod("show2", String.class);
        method2.invoke(o,"李四");
        System.out.println("--------------------------------------------");
        Method method3 = c.getMethod("show3", String.class);
        Object o1 = method3.invoke(o, "哈哈");
        System.out.println(o1);
        System.out.println("---------------------------------------------");
        Method method4 = c.getDeclaredMethod("show4");
        method4.setAccessible(true);
        method4.invoke(o);
    }
}

2.7 Practice questions

1:
/**
 * 使用配置文件运行类中的方法
 */
public class Testdemo {
    
    
    public static void main(String[] args) throws Exception {
    
    
        //加载配置文件
        Properties properties = new Properties();
        FileReader fr = new FileReader("D:\\桌面\\java\\src\\Properties.txt");
        properties.load(fr);
        fr.close();
        //获取数据
        String ClassName = properties.getProperty("ClassName");
        String MethodName = properties.getProperty("MethodName");

        // 反射加载对应的类并调用方法
        Class c = Class.forName(ClassName);
        //创建对象
        Constructor constructor = c.getConstructor();
        Object o = constructor.newInstance();
        //调用方法
        Method method = c.getMethod(MethodName);
        method.invoke(o);
    }
}
2:
/**
 * 给定一个指定的泛型Integer类型的ArrayList的集合,在这个集合中添加一个字符串
 */

public class Testdemo2 {
    
    
    public static void main(String[] args) throws Exception {
    
    
        ArrayList<Integer> arrayList = new ArrayList<>();
        //获取对应的字节码文件
        Class c = arrayList.getClass();
        //获取方法
        Method method = c.getMethod("add", Object.class);
        //使用方法
        method.setAccessible(true);
        method.invoke(arrayList,"hello");
        System.out.println(arrayList);
    }
}
3:

Write a method, this method can assign values ​​to the properties of the specified object

public class Testdemo3 {
    
    
    public static void main(String[] args) throws Exception {
    
    
        Dog dog =new Dog();
        System.out.println(dog);
        Tool tool = new Tool();
        tool.setProperty(dog,"name","博美");
        tool.setProperty(dog,"age",10);
        System.out.println(dog);
    }
}
------------------------------------------------------
class Dog{
    
    
    private String name;
    int age;

    @Override
    public String toString() {
    
    
        return "Dog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
------------------------------------------------------
class Tool{
    
    
    public void setProperty(Object obj,String filedName,Object value) throws Exception {
    
    
        //先拿到指定对象的字节码文件
        Class c= obj.getClass();
        //获取属性名
        Field field = c.getDeclaredField(filedName);
        //抑制访问权限
        field.setAccessible(true);
        field.set(obj,value);
    }
}

Three, dynamic agency

3.1 Overview:

Agency is what you originally did, but if you ask someone to do it for you, the person you ask is the agent

It is the object produced during the running of the program-----generation of proxy through reflection

3.2 Dynamic proxy application

/*
 * Proxy:提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类。
 * public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
 *                      返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。
 *
 * InvocationHandler:由代理实例的调用处理程序实现的接口。
 * invoke(Object proxy, 方法 method, Object[] args) 处理代理实例上的方法调用并返回结果。
 */
public class ProxyDemo {
    
    
    public static void main(String[] args) {
    
    
        UserDao userDao = new UserDaoImpl();
        MyInvocationHandler myInvocationHandler = new MyInvocationHandler(userDao);
        //创建代理对象
        UserDao proxy = (UserDao)Proxy.newProxyInstance(userDao.getClass().getClassLoader(),userDao.getClass().getInterfaces(),
                myInvocationHandler);
        proxy.add();
        proxy.del();
    }
}

public class MyInvocationHandler implements InvocationHandler {
    
    
    private Object object;

    public MyInvocationHandler(Object object){
    
    
        this.object = object;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
    
        System.out.println("权限校验");
        Object result =  method.invoke(object,args);//代理对象
        System.out.println("日志记录");
        return result;
    }
}

public interface UserDao {
    
    
    public abstract void add();
    public abstract void del();
}

public class UserDaoImpl implements UserDao {
    
    

    @Override
    public void add() {
    
    
        System.out.println("添加");
    }

    @Override
    public void del() {
    
    
        System.out.println("删除");
    }
}
ic abstract void del();
}

public class UserDaoImpl implements UserDao {
    
    

    @Override
    public void add() {
    
    
        System.out.println("添加");
    }

    @Override
    public void del() {
    
    
        System.out.println("删除");
    }
}

Guess you like

Origin blog.csdn.net/zjdzka/article/details/112725955
Recommended