代理模式以及JDK动态代理
在说动态代理之前,我们要明白什么是代理模式
在这里推荐一下廖雪峰老师的Java教程
https://www.liaoxuefeng.com/wiki/1252599548343744/1281319432618017
这里有代理模式的简介
挑了一些重点:
代理模式
为其他对象提供一种代理以控制对这个对象的访问。
比如说
A接口
public interface A {
void a();
}
写一个实现
public class AImpl implements A {
@Override
public void a() {
System.out.println("a 被调用");
}
}
AProxy
public class AProxy implements A {
private A a;
@Override
public void a() {
System.out.println("a()调用前");
a.a();
System.out.println("a()调用后");
}
}
可以发现 AProxy 做了对 a()这个方法 做了一些增强
(ps:下面的这个例子,是参考网上的某一篇博客 ,但是忘记链接是哪一个了,如果原作者看到,希望在评论区指明,然后我填上去)
例子:
测试类
import java.lang.reflect.Proxy;
public class Test {
public static void main(String[] args) throws SecurityException, IllegalArgumentException {
// 被代理对象
IUserDao userDao = new UserDao();
InvocationHandlerImpl invocationHandlerImpl = new InvocationHandlerImpl(userDao);
//获取userDao的classLoader
ClassLoader loader = userDao.getClass().getClassLoader();
//获取userDao继承的接口
Class<?>[] interfaces = userDao.getClass().getInterfaces();
//参数有 加载器,接口,invocationHandler实现类
IUserDao newProxyInstance = (IUserDao) Proxy.newProxyInstance(loader, interfaces, invocationHandlerImpl);
//调用代理save()方法
newProxyInstance.save();
//调用hello()方法
newProxyInstance.hello();
}
}
IUserDao 接口
public interface IUserDao{
void save();
void hello();
}
IUserDao实现类
public class UserDao implements IUserDao{
public void save() {
System.out.println("已经保存数据...");
}
public void hello() {
System.out.println("hello");
}
}
InvocationHandlerImpl
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
// 每次生成动态代理类对象时,实现了InvocationHandler接口的调用处理器对象
public class InvocationHandlerImpl implements InvocationHandler {
private Object target;// 这其在这里插入代码片实业务实现类对象,用来调用具体的业务方法
// 通过构造函数传入目标对象
public InvocationHandlerImpl(Object target) {
this.target = target;
}
@Override
//代理对象,调用的方法,调用的参数
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result;
//这里可以指定方法 比如:"xxx".equals(method.getName()) 或者 获取注解判断
System.out.println("调用开始处理");
result = method.invoke(target, args);
System.out.println("调用结束处理");
return result;
}
}
最后的结果
可以看到,save 和 hello 在被调用的时候 都被动态代理进行了 增强。