前言:
为什么需要动态代理?
当你需要对一个接口的方法进行扩展内容或者修改内容的时候,你有什么方法?
方法1:创建一个接口重写该方法。
缺点:全部方法都得实现,那多麻烦啊,明明我们只修改扩展一个方法。
动态代理:
对指定接口的某一个方法进行功能扩展,可以使用代理
注意:是指定的接口。
创建代理类:
目标对象接口类型 proxy = (目标对象接口类型)Proxy.
newProxyInstance(loader,interfaces,InvocationHandler);
loader:目标对象的加载类
参数:getClass().getClassLoader()
interfaces:一个Interface对象的数组 目标对象实现的接口集合,
被代理类实现的接口,创建的代理类会实现这些接口
参数:getClass().getInterfaces()
InvocationHandler:
当调用代理类方法的时候就会触发该类执行其中的invoke方法
参数:new InvocationHandler()创建的匿名对象
触发方法进入invoke的方法 所以要重写该invoke
public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable {}
proxy: 指代我们所代理的那个真实对象
method: 指代的是我们所要调用真实对象的某个方法的Method对象
args: 指代的是调用真实对象某个方法时接受的参数
一般来说 、 自己写一个方法继承InvocationHandler接口 创建一个带参的构造函数,传入目标对象。
注意:
method是目标执行的方法
request是目标对象
args是目标方法的参数
Object returnValue = method.invoke(request, args);
动态代理我这目前有2个自己写的栗子:
栗子1:
C3P0线程池的时候调用Close方法的时候 扩展判断方法(线程池是否满
如果不满不Close,加入线程池,
如果是线程池已满,则Close
代码:
https://blog.csdn.net/qq_38409944/article/details/81211812
栗子2:
刚学了拦截器结合拦截器写的。
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) arg0;
HttpServletResponse response = (HttpServletResponse) arg1;
HttpServletRequest proxy = (HttpServletRequest) Proxy.newProxyInstance(request.getClass().getClassLoader(),
request.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object returnValue = null;
String methodName = method.getName();
if ("getParameter".equals(methodName)) {
String value = (String) method.invoke(request, args[0]);
String methodSubmit = request.getMethod();
if ("POST".equals(methodSubmit)) {
if (value != null && !"".equals(value)) {
String newValue = new String(value.getBytes("iso-8859-1"), "utf-8");
return newValue;
}
}
} else {
returnValue = method.invoke(request, args);
}
return returnValue;
}
});
arg2.doFilter(proxy, response);
}