面试题答案
一键面试静态代理模式应用场景
- 场景描述:在系统中业务逻辑相对固定,代理类和被代理类关系明确且短期内不会发生变化时适用。例如,在一个简单的电商订单处理系统中,订单处理服务
OrderService
有一个processOrder
方法,需要在执行该方法前后添加日志记录功能。 - 代码示例:
// 定义订单服务接口
interface OrderService {
void processOrder();
}
// 订单服务实现类
class OrderServiceImpl implements OrderService {
@Override
public void processOrder() {
System.out.println("处理订单");
}
}
// 订单服务静态代理类
class OrderServiceProxy implements OrderService {
private OrderService orderService;
public OrderServiceProxy(OrderService orderService) {
this.orderService = orderService;
}
@Override
public void processOrder() {
System.out.println("记录日志:开始处理订单");
orderService.processOrder();
System.out.println("记录日志:订单处理完成");
}
}
- 使用方式:
public class Main {
public static void main(String[] args) {
OrderService orderService = new OrderServiceImpl();
OrderServiceProxy proxy = new OrderServiceProxy(orderService);
proxy.processOrder();
}
}
动态代理模式应用场景
- 场景描述:当系统中有多个不同的服务接口,且都需要添加类似的通用功能(如日志记录、事务管理等),或者在运行时才能确定代理的对象时,动态代理更为合适。例如,在一个大型企业级应用中,有用户服务、商品服务等多个服务接口,都需要统一添加性能监控功能。
- 代码示例:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
// 定义服务接口
interface UserService {
void getUserInfo();
}
// 用户服务实现类
class UserServiceImpl implements UserService {
@Override
public void getUserInfo() {
System.out.println("获取用户信息");
}
}
// 动态代理处理器
class PerformanceMonitorHandler implements InvocationHandler {
private Object target;
public PerformanceMonitorHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
long startTime = System.currentTimeMillis();
Object result = method.invoke(target, args);
long endTime = System.currentTimeMillis();
System.out.println("方法 " + method.getName() + " 执行时间:" + (endTime - startTime) + " 毫秒");
return result;
}
}
// 动态代理生成代理对象
class ProxyFactory {
public static Object createProxy(Object target) {
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new PerformanceMonitorHandler(target));
}
}
- 使用方式:
public class Main {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
UserService proxy = (UserService) ProxyFactory.createProxy(userService);
proxy.getUserInfo();
}
}
总结来说,静态代理适合简单、业务逻辑固定且代理关系明确的场景;动态代理则适用于复杂、需要统一处理多个服务接口通用功能或运行时确定代理对象的场景。