1
动态代理对象介绍
Proxy
提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类。
核心方法:
参数介绍:
三个参数全都
是固定写法!
参数一:通过被增强对象获取类加载器
参数二:通过被增强对象获取所有实现类的接口
参数三:动态代理的处理类,
用于对方法的增强
代理图示:
2
动态代理操作步骤
固定步骤:
1
、创建
被增强对象【被代理对象】
2
、创建
增强对象
【代理对象】
2.1
、通过被代理对象获取类加载器
被代理对象
.getClass().getClassLoader()
2.2
、通过被代理对象获取其所有的接口
被代理对象
.getClass().getInterfaces()
2.3
、创建一个处理类
【专门用来增强方法】
动态代理执行简单过程:
动态代理只对接口里面的方法进行增强,实现类的不曾强!
(
我们实现动态代理压根儿不知道它的实现类
)
3 解决request请求乱码问题:
案例代码:
//1.解决POST中文乱码
request.setCharacterEncoding("utf-8")
/*//2.使用装饰者设计模式解决GET请求中文乱码
MyRequest req = new MyRequest((HttpServletRequest) request);
//3.放行,如果后面没有其它的过滤器,那么访问目标资源文件,需要传递包装过后的request对象
chain.doFilter(req, response);*/
//4.使用动态代理设计模式解决GET请求中文乱码
//5.创建一个被代理对象(直接强转得到)
final HttpServletRequest req = (HttpServletRequest) request;
//6.创建代理对象实例
HttpServletRequest requestProxy = (HttpServletRequest) Proxy.newProxyInstance(req.getClass().getClassLoader(), req.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//只对getParameter方法增强
if("getParameter".equals(method.getName())){
//只处理GET请求中文乱码
if("GET".equalsIgnoreCase(req.getMethod())){
//执行invoke方法,得到乱码的请求参数
//代理对象(requestProxy)调用被代理对象(req)里面的方法才执行
//执行它method.invoke(req, args)等价于执行getParameter();
String value = (String) method.invoke(req, args);
//解决乱码问题
value = new String(value.getBytes("iso8859-1"),"utf-8");
//如果是get请求,返回处理后的对象
return value;
}
//如果不是get请求,调用原来的方法
return method.invoke(req, args);
}
//如果是其它方法,也调用原来的方法
return method.invoke(req, args);
}
});
//7.放行,如果没哟其它过滤器,直接到目标资源文件
chain.doFilter(requestProxy, response);
4
动态代理与静态代理区别
1
、静态代理
代理的是类
创建一个增强类【代理类】
2
、动态代理
代理的是对象
创建一个增强对象【代理对象】
- 静态代理(工作量极大)
要实现所有接口中的所有方法全部实现。
工作量极大
需要知道具体的接口名字。通过
class
找所有接口。工作量极大
2
、动态代理(灵活,工作量极小)
只需要被代理对象
5.
总结
(
类加载器
)
l
类加载器:类加载器是负责加载类的对象。将
class
文件(硬盘)加载到内存生成
Class
对象。
所有的类加载器
都是
java.lang.ClassLoader
的子类
l
使用
类
.class.getClassLoader()
获得加载自己的类加载器
l
类加载器加载机制:全盘负责委托机制
全盘负责:
A
类如果要使用
B
类(不存在),
A
类加载器
C
必须负责加载
B
类。
委托机制:
A
类加载器如果要加载资源
B
,必须询问父类加载是否加载。
如果加载,将直接使用。
如果没有机制,自己再加载。
l
采用
全盘负责委托机制
保证
一个
class
文件
只会被加载一次,形成一个
Class
对象。
l
注意:
如果一个
class
文件,被两个类加载器加载,将是两个对象。
提示
com.andday.Hello
不能强制成
com.andday.Hello
h.getClass() -->A h.getClass() -->B
自定义类加载,可以将一个
class
文件加载多次。