天天看点

Spring - JDK的动态代理

JDK的动态代理

  • 运行过程:

    JVM -> 动态代理类 -> 代理对象

  • Proxy.newProxyInstance方法参数详解
Spring - JDK的动态代理
  • 三个参数:
  1. loader: 用哪个类加载器去加载代理对象
  2. interfaces: 动态代理类需要实现的接口
  3. h: 动态代理方法在执行时,会调用h里面的invoke方法去执行
1. ClassLoader loader
	(1)类加载器的作用:
    	1. 通过类加载器把对应类的字节码文件加载JVM
    	2. 通过类加载器创建类的Class对象, 进而创建这个类的对象
    	
   	(2)类加载器的运行过程:
   		.java -> .class(字节码文件) -> (通过类加载器)加载到JVM -> (通过类加载器创建).class对象 -> new 类的对象	
   
   	(3)如何获得类加载器
   		JVM会为每一个类的.class文件自动分配与之对应的类加载器
   		
   	(4)备注:
    	Class对象记录了这个类最完整的信息
           
2. @NotNull Class<?>[] interfaces

	通过 原始类对象.getClass().getInterfaces() 获得接口
           
3. @NotNull InvocationHandler h
	
	简介: InvocationHandler接口是proxy代理实例的调用处理程序实现的一个接口,每一个proxy代理实例都有一个关联的调用处理程序;在代理实例调用方法时,方法调用被编码分派到调用处理程序的invoke方法。
	
	当我们通过动态代理对象调用一个方法时候,这个方法的调用就会被转发到实InvocationHandler接口类的invoke方法来调用
	
	/**
	* Object: 返回原始方法的返回值
    * proxy: 代理对象
    * method: 我们所要调用某个对象真实的方法的Method对象, 即核心功能
    * args: 原始方法的参数
    */
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
           
  • 代码演示

    TextJDKProxy.java

package com.wyt.jdk;

import com.hello.wyt.User;
import com.hello.wyt.UserService;
import com.hello.wyt.UserServiceImpl;

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

public class TextJDKProxy {
    public static void main(String[] args) {
        //1.创建原始对象
        UserService userService = new UserServiceImpl();

        InvocationHandler handler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("---proxy log before---");
                //原始方法运行
                Object ret = method.invoke(userService, args);

                System.out.println("---proxy log after---\n");

                return ret;
            }
        };

        //获得代理对象
        UserService userServiceProxy = (UserService) Proxy.newProxyInstance(TextJDKProxy.class.getClassLoader(), userService.getClass().getInterfaces(), handler);

        userServiceProxy.login("wyt", "123456");
        userServiceProxy.register(new User());
    }
}
           

UserService.java(接口)

package com.wyt.proxy;

public interface UserService{
    public void register(User user);

    public boolean login(String name, String password);
}

           

UserServiceImpl.java

package com.wyt.proxy;

public class UserServiceImpl implements UserService{
    @Override
    public void register(User user) {
        System.out.println("UserServiceImpl.register 业务运算 + DAO");
    }

    @Override
    public boolean login(String name, String password) {
        System.out.println("UserServiceImpl.login");
        return true;
    }
}

           

User.class

package com.wyt.proxy;

import java.io.Serializable;

public class User implements Serializable {
    private String name;
    private String password;

    public User() {

    }

    public User(String name, String password) {
        this.name = name;
        this.password = password;
    }

    public String getName() {
        return name;
    }

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

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

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