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