JDK动态代理(JDK Proxy)是Java中一种常用的代理模式实现方式,它可以在运行时动态地创建代理类和代理对象,而无需先定义代理类。以下是JDK动态代理的完整攻略:
步骤一:接口
首先,需要定义一个接口该接口是代理类和被代理类的公共接口。以下是一个示例接口:
public interface UserService {
void addUser(String name, String password);
void deleteUser(String name);
}
步骤二:实现被代理类
接下来,需要实现一个被代理类,该类实现了上一步定义的接口。以下是一个示例被代理类:
public class UserServiceImpl implements UserService {
@Override
public void addUser(String name, String password) {
System.out.println("Add user: " + name);
}
@Override
public void deleteUser(String name) {
System.out.println("Delete user: " + name);
}
}
步骤三:实现InvocationHandler接口
接下来,需要实现一个InvocationHandler接口,该接口中有一个invoke方法,该方法是代理类的核心方法。以下是一个示例InvocationHandler实现类:
public class UserServiceInvocationHandler implements InvocationHandler {
private Object target;
public UserServiceInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Before method " + method.getName());
Object result = method.invoke(target, args);
System.out.println("After method " + method.getName());
return result;
}
}
步骤四:创建代理对象
最后,需要创建一个代理对象,该对象是通过Proxy类的静态方法newProxyInstance创建的。以下是一个示例创建代理对象的代码:
public class Main {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
UserServiceInvocationHandler invocationHandler = new UserServiceInvocationHandler(userService);
UserService proxy = (UserService) Proxy.newProxyInstance(
userService.getClass().getClassLoader(),
userService.getClass().getInterfaces(),
invocationHandler);
proxy.addUser("Alice", "123456");
proxy.deleteUser("Bob");
}
}
以上代码中,创建了一个UserServiceInvocationHandler对象,并将其传递给Proxy.newProxyInstance方法,该方法返回一个代理对象。通过代理对象调用方法时,会先执行InvocationHandler中的invoke方法,然后再执行被代理类中的方法。
示例一:使用JDK动态代理实现日志记录
以下是一个示例,使用JDK动态代理实现日志记录:
public interface UserService {
void(String name, String password);
void deleteUser(String name);
}
public class UserServiceImpl implements UserService {
@Override
public void addUser(String name, String password) {
System.out.println("Add user: " + name);
}
@Override
public void deleteUser(String name) {
System.out.println("Delete user: " + name);
}
}
public class UserServiceInvocationHandler implements InvocationHandler {
private Object target;
public UserServiceInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Before method " + method.getName());
Object result = method.invoke(target, args);
System.out.println("After method " + method.getName());
return result;
}
}
public class Main {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
UserServiceInvocationHandler invocationHandler = new UserServiceInvocationHandler(userService);
UserService proxy = (UserService) Proxy.newProxyInstance(
userService.getClass().getClassLoader(),
userService.getClass().getInterfaces(),
invocationHandler);
proxy.addUser("Alice", "123456");
proxy.deleteUser("Bob");
}
}
以上代码中,UserServiceInvocationHandler实现了InvocationHandler接口,用于记录方法调用前后的日志。在Main类中,创建了一个代理对象,并通过代理对象调用了UserService中的方法。
示例二:使用JDK动态代理实现权限控制
以下是一个示例,使用JDK动态代理实现权限控制:
public interface UserService {
void addUser(String name, String password);
void deleteUser(String name);
}
public class UserServiceImpl implements UserService {
@Override
public void addUser(String name, String password) {
System.out.println("Add user: " + name);
}
@Override
public void deleteUser(String name) {
System.out.println("Delete user: " + name);
}
}
public class UserServiceInvocationHandler implements InvocationHandler {
private Object target;
public UserServiceInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().equals("addUser")) {
System.out.println("Permission denied");
return null;
}
Object result = method.invoke(target, args);
return result;
}
}
public class Main {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
UserServiceInvocationHandler invocationHandler = new UserServiceInvocationHandler(userService);
UserService proxy = (UserService) Proxy.newProxyInstance(
userService.getClass().getClassLoader(),
userService.getClass().getInterfaces(),
invocationHandler);
proxy.addUser("Alice", "123456");
proxy.deleteUser("Bob");
}
}
以上代码中,UserServiceInvocationHandler实现了InvocationHandler接口,用于实现权限控制。在Main类中,创建了一个代理对象,并通过代理对象调用了UserService中的方法。在UserServiceInvocationHandler中,对addUser方法进行了权限控制,如果调用该方法,则会输出“Permission denied”。
以上就是JDK动态代理的完整攻略,通过这种方式可以实现很多有用的功能,如日志记录、权限控制等。