JDK动态代理

JDK动态代理

用户类

/**
 * @Author frh
 * @Date 2021/6/26 10:35
 */
public class User {

    private String username;
    private String password;

    public User() {
    }

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

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

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

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

用户服务接口类:

/**
 * @Author frh
 * @Date 2021/6/26 10:34
 */
public interface UserService {

    public void save(User user);

    public User findUser(String username);

}

用户服务接口实现类:

/**
 * @Author frh
 * @Date 2021/6/26 10:36
 */
public class UserServiceImpl implements UserService {
    Map<String, User> map;

    public UserServiceImpl() {
        map = new HashMap<>();
        map.put("zhangsan", new User("zhangsan", "123456"));
        map.put("lisi", new User("lisi", "666666"));
    }

    @Override
    public void save(User user) {
        if(null == user)
            return;
        map.put(user.getUsername(), user);
    }

    @Override
    public User findUser(String username) {
        return map.get(username);
    }
}

用户处理器实现类

/**
 * @Author frh
 * @Date 2021/6/26 10:40
 */
public class UserInvocationHandler implements InvocationHandler {

    private Object target;

    public UserInvocationHandler(Object target) {
        this.target = target;
    }

    public void before() {
        System.out.println("检查用户信息...");
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		
        before();	// 在执行目标方法前进行操作
        /**
        	获取执行方法后的返回值,并最后返回结果
        	第一个参数不能直接使用proxy,否则会出现:
        	Caused by: java.lang.reflect.InvocationTargetException
        	而需要通过构造函数,传递要代理的对象。
        */
        Object ret = method.invoke(target, args);
        System.out.println(ret);
        after();	// 在执行目标方法后进行操作
        return ret;
    }

    public void after() {
        System.out.println("后续对用户信息进行处理...");
    }
}

测试类

/**
 * @Author frh
 * @Date 2021/6/26 10:42
 */
public class JDKProxy {

    public static void main(String[] args) {
		// 在这里设置sun.misc.ProxyGenerator.saveGeneratedFiles这个系统属性为true
		// 把生成的class保存到本地文件来查看。
        System.setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");

        UserService target = new UserServiceImpl();

        UserService userService = (UserService) Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(), new UserInvocationHandler(target));

        User user = userService.findUser("zhangsan");
        System.out.println("查询到的用户信息: " + user);
    }
    
}

执行结果:
检查用户信息...
User{username='zhangsan', password='123456'}
后续对用户信息进行处理...
查询到的用户信息: User{username='zhangsan', password='123456'}

生成的代理类

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.sun.proxy;

import com.shell.fph.code.bean.User;
import com.shell.fph.code.service.UserService;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;

public final class $Proxy0 extends Proxy implements UserService {
    private static Method m1;
    private static Method m3;
    private static Method m4;
    private static Method m2;
    private static Method m0;

    public $Proxy0(InvocationHandler var1) throws  {
        super(var1);
    }

    public final boolean equals(Object var1) throws  {
        try {
            return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final void save(User var1) throws  {
        try {
            super.h.invoke(this, m3, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final User findUser(String var1) throws  {
        try {
            return (User)super.h.invoke(this, m4, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final String toString() throws  {
        try {
            return (String)super.h.invoke(this, m2, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final int hashCode() throws  {
        try {
            return (Integer)super.h.invoke(this, m0, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
            m3 = Class.forName("com.shell.fph.code.service.UserService").getMethod("save", Class.forName("com.shell.fph.code.bean.User"));
            m4 = Class.forName("com.shell.fph.code.service.UserService").getMethod("findUser", Class.forName("java.lang.String"));
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}

可以看出生成的代理类,继承了Proxy,所以JDK动态代理不支持实现类的动态代理,只支持对接口的动态代理。

参考

细说JDK动态代理的实现原理 – MikanMu

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值