💥 该系列属于【Java基础编程500题】专栏,如您需查看Java基础的其他相关题目,请您点击左边的连接
目录
✨✨ 返回题目目录 ✨ ✨
1. 使用Java动态代理实现一个简单的日志功能。
- 创建一个接口Operation,包含一个方法execute(String msg)。
- 实现Operation接口的OperationImpl类。
- 使用动态代理为OperationImpl类添加日志功能。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
// 定义一个操作接口
interface Operation {
void execute(String msg);
}
// 实现操作接口的类
class OperationImpl implements Operation {
@Override
public void execute(String msg) {
// 执行操作
System.out.println("执行操作:" + msg);
}
}
// 日志处理器,实现InvocationHandler接口
class LoggingHandler implements InvocationHandler {
private Object target; // 被代理的对象
public LoggingHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 在方法执行前打印日志
System.out.println("日志:方法 " + method.getName() + " 开始执行");
// 执行实际的方法
Object result = method.invoke(target, args);
// 在方法执行后打印日志
System.out.println("日志:方法 " + method.getName() + " 执行结束");
return result;
}
}
public class Main {
public static void main(String[] args) {
// 创建目标对象
Operation operation = new OperationImpl();
// 创建代理对象
Operation proxy = (Operation) Proxy.newProxyInstance(
Operation.class.getClassLoader(),
new Class[]{Operation.class},
new LoggingHandler(operation)
);
// 通过代理对象调用方法
proxy.execute("操作1");
}
}
2. 使用Java动态代理实现方法调用的权限校验。
- 创建一个接口UserService,包含一个方法login(String username, String password)。
- 实现UserService接口的UserServiceImpl类。
- 使用动态代理为UserServiceImpl类添加权限校验功能。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
// 定义用户服务接口
interface UserService {
void login(String username, String password);
}
// 实现用户服务接口的类
class UserServiceImpl implements UserService {
@Override
public void login(String username, String password) {
// 执行登录操作
System.out.println(username + " 登录成功");
}
}
// 权限校验处理器,实现InvocationHandler接口
class AccessHandler implements InvocationHandler {
private Object target; // 被代理的对象
public AccessHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 进行权限校验
if (args != null && args.length > 1 && "admin".equals(args[0])) {
System.out.println("管理员登录,权限校验通过");
return method.invoke(target, args); // 权限校验通过,执行方法
} else {
System.out.println("非管理员登录,权限校验不通过");
return null; // 权限校验不通过,不执行方法
}
}
}
public class Main {
public static void main(String[] args) {
// 创建目标对象
UserService userService = new UserServiceImpl();
// 创建代理对象
UserService proxy = (UserService) Proxy.newProxyInstance(
UserService.class.getClassLoader(),
new Class[]{UserService.class},
new AccessHandler(userService)
);
// 通过代理对象调用方法
proxy.login("admin", "123456");
proxy.login("user", "123456");
}
}
3. 使用Java动态代理实现方法的耗时统计。
- 创建一个接口TimeConsuming,包含一个方法calculate()。
- 实现TimeConsuming接口的TimeConsumingImpl类。
- 使用动态代理为TimeConsumingImpl类添加方法耗时统计功能。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
// 定义耗时操作接口
interface TimeConsuming {
void calculate();
}
// 实现耗时操作接口的类
class TimeConsumingImpl implements TimeConsuming {
@Override
public void calculate() {
try {
// 模拟耗时操作
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 执行计算
System.out.println("计算完成");
}
}
// 耗时处理器,实现InvocationHandler接口
class TimeHandler implements InvocationHandler {
private Object target; // 被代理的对象
public TimeHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
long start = System.currentTimeMillis(); // 开始时间
Object result = method.invoke(target, args); // 执行方法
long end = System.currentTimeMillis(); // 结束时间
// 打印方法耗时
System.out.println("方法耗时:" + (end - start) + " 毫秒");
return result;
}
}
public class Main {
public static void main(String[] args) {
// 创建目标对象
TimeConsuming timeConsuming = new TimeConsumingImpl();
TimeConsuming proxy = (TimeConsuming) Proxy.newProxyInstance(
TimeConsuming.class.getClassLoader(),
new Class[]{TimeConsuming.class},
new TimeHandler(timeConsuming)
);
proxy.calculate();
}
}
4. 使用Java动态代理实现一个简单的缓存机制。
- 定义一个
Calculator
接口,包含一个calculate
方法,该方法接收两个整数参数并返回它们的和。- 实现该接口的
CalculatorImpl
类。- 使用动态代理为
CalculatorImpl
类添加缓存功能,以避免重复计算相同的参数。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;
// 定义计算器接口
interface Calculator {
int calculate(int a, int b);
}
// 实现计算器接口
class CalculatorImpl implements Calculator {
@Override
public int calculate(int a, int b) {
// 模拟计算过程
return a + b;
}
}
// 缓存处理器
class CacheHandler implements InvocationHandler {
private Calculator target;
private Map<String, Integer> cache = new HashMap<>();
public CacheHandler(Calculator target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 构建缓存键
String key = method.getName() + "_" + args[0] + "_" + args[1];
// 检查缓存
if (cache.containsKey(key)) {
System.out.println("从缓存中获取结果");
return cache.get(key);
}
// 执行计算
Object result = method.invoke(target, args);
// 存储结果到缓存
cache.put(key, (Integer) result);
return result;
}
}
public class Main {
public static void main(String[] args) {
Calculator calculator = new CalculatorImpl();
Calculator proxy = (Calculator) Proxy.newProxyInstance(
Calculator.class.getClassLoader(),
new Class[]{Calculator.class},
new CacheHandler(calculator)
);
// 调用代理方法
System.out.println("计算结果:" + proxy.calculate(10, 20));
System.out.println("计算结果:" + proxy.calculate(10, 20)); // 第二次调用会从缓存中获取结果
}
}
5. 使用Java动态代理实现方法调用次数限制。
- 定义一个LimitedMethod接口,包含一个call方法。
- 实现该接口的LimitedMethodImpl类。
- 使用动态代理为LimitedMethodImpl类添加调用次数限制功能,当调用次数超过限制时,抛出异常。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
// 定义有限制的方法接口
interface LimitedMethod {
void call();
}
// 实现有限制的方法接口
class LimitedMethodImpl implements LimitedMethod {
@Override
public void call() {
System.out.println("方法被调用");
}
}
// 调用次数限制处理器
class LimitHandler implements InvocationHandler {
private LimitedMethod target;
private int callCount = 0;
private final int LIMIT = 3;
public LimitHandler(LimitedMethod target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (callCount >= LIMIT) {
throw new RuntimeException("调用次数超过限制");
}
callCount++;
return method.invoke(target, args);
}
}
public class Main {
public static void main(String[] args) {
LimitedMethod limitedMethod = new LimitedMethodImpl();
LimitedMethod proxy = (LimitedMethod) Proxy.newProxyInstance(
LimitedMethod.class.getClassLoader(),
new Class[]{LimitedMethod.class},
new LimitHandler(limitedMethod)
);
// 调用代理方法
for (int i = 0; i < 5; i++) {
try {
proxy.call();
} catch (RuntimeException e) {
System.out.println(e.getMessage());
}
}
}
}