1.java中的代理分类
- JDK静态代理
- JDK动态代理
- CGLIB动态代理
2.为什么要使用动态代理
使用动态代理是为了在不修改源代码的基础上,扩展额外原目标的功能。即扩展功能通过代理类去实现扩展功能,再由代理类去访问原目标。
首先是我们的被代理接口UserDao
public interface UserDao {
public int add(String name, int age);
public int update(String name, int age);
}
然后是接口实现类UserDaoImpl
public class UserDaoImpl implements Userdao{
@Override
public int add(String name, int age) {
System.out.println("UserdaoImpl=====add方法被调用");
return 0;
}
@Override
public int update(String name, int age) {
System.out.println("UserdaoImpl---------update方法被调用");
return 0;
}
然后是我们代理类UserDaoProxy
public class UserDaoProxy implements InvocationHandler {
private Object obj;
public UserDaoProxy(Object obj) {
this.obj = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ("add".equals(method.getName())) {
System.out.println("该方法出现在add方法执行之前.......");
Object res = method.invoke(obj, args);
System.out.println("该方法出现在add方法执行之后.......");
return res;
} else {
Object res = method.invoke(obj, args);
return res;
}
}
最后使我们的执行类JDKProxy
public static void main(String[] args) {
Class[] interfaces = {UserDao.class};
UserDaoImpl userDao = new UserDaoImpl();
UserDao proxyInstance = (UserDao)Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces, new UserDaoProxy(userDao));
proxyInstance.update("zhangsan", 19);
proxyInstance.add("lisi", 20);
}
3.部分代码讲解
- Object invoke()
实现增强逻辑的地方 - Class[] interfaces 保存的是需要被代理的接口,可以不止一个接口
- Proxy.newProxyInstance(A, B, C)
参数A:当前类的类加载器
参数B:被代理的接口对象,interfaces
参数C:代理类对象,即InvocationHandler实现类对象
4.代码执行顺序
通过类加载器,被增强接口和代理类对象获取增强后的接口对象
然后执行update方法
从上图中可以看出proxy已被赋值为UserdaoImpl,method就是Userdao中的update方法,args中保存的是"zhangsan", 19,因为if条件为false,直接执行method.invoke(obj, args),表示原目标中的update方法被执行
然后就到了add方法
这里的流程跟上面的差不多,只是这里是add方法,if条件满足,按顺序执行下来,在method方法执行前后执行增强方法
最后返回执行结果,程序执行完成
输出结果