Java代理模式(Proxy Pattern)是一种常用的设计模式,它为其他对象提供一种代理以控制对这个对象的访问。简单来说,我们使用代理对象来代替对真实对象的访问,这样就可以在不修改原目标对象的前提下,提供额外的功能操作,扩展目标对象的功能。
优点
缺点
// 抽象主题角色
interface Subject {
void request();
}
// 真实主题角色
class RealSubject implements Subject {
public void request() {
System.out.println("RealSubject request");
}
}
// 代理主题角色
class ProxySubject implements Subject {
private RealSubject realSubject;
public ProxySubject(RealSubject realSubject) {
this.realSubject = realSubject;
}
public void request() {
System.out.println("ProxySubject preRequest");
realSubject.request();
System.out.println("ProxySubject postRequest");
}
}
// 客户端
public class Client {
public static void main(String[] args) {
RealSubject realSubject = new RealSubject();
ProxySubject proxySubject = new ProxySubject(realSubject);
proxySubject.request();
}
}
首先,我们定义一个接口UserService,它有一个方法getUserById用于根据用户ID获取用户信息。
public interface UserService {
String getUserById(Integer id);
}
然后,我们创建一个实现了UserService接口的类UserServiceImpl,并在其中实现getUserById方法。
@Service
public class UserServiceImpl implements UserService {
@Override
public String getUserById(Integer id) {
return "User with id: " + id;
}
}
接下来,我们创建一个类UserServiceInvocationHandler,它实现了InvocationHandler接口。在这个类中,我们重写了invoke方法,在其中添加了日志记录功能。
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方法来创建一个代理对象,并使用这个代理对象来调用getUserById方法。
@SpringBootApplication
public class DemoApplication implements CommandLineRunner {
@Autowired
private UserService userService;
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
UserService proxy = (UserService) Proxy.newProxyInstance(
userService.getClass().getClassLoader(),
userService.getClass().getInterfaces(),
new UserServiceInvocationHandler(userService)
);
System.out.println(proxy.getUserById(1));
}
}
当我们运行这个程序时,会看到控制台输出以下内容:
Before method: getUserById
After method: getUserById
User with id: 1
首先,我们定义一个类UserService,它有一个方法getUserById用于根据用户ID获取用户信息。
public class UserService {
public String getUserById(Integer id) {
return "User with id: " + id;
}
}
接下来,我们创建一个类UserServiceInterceptor,它继承了MethodInterceptor接口。在这个类中,我们重写了intercept方法,在其中添加了日志记录功能。
public class UserServiceInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("Before method: " + method.getName());
Object result = methodProxy.invokeSuper(o, objects);
System.out.println("After method: " + method.getName());
return result;
}
}
最后,在我们的主类中,我们使用Enhancer类来创建一个代理对象,并使用这个代理对象来调用getUserById方法。
@SpringBootApplication
public class DemoApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(UserService.class);
enhancer.setCallback(new UserServiceInterceptor());
UserService proxy = (UserService) enhancer.create();
System.out.println(proxy.getUserById(1));
}
}
当我们运行这个程序时,会看到控制台输出以下内容:
Before method: getUserById
After method: getUserById
User with id: 1