作用:为其他对象提供一种代理以控制对这个对象的访问.在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用
一.静态代理
定义:在编译时就将接口、实现类、代理类全部创建
涉及到的角色
抽象角色:声明真实对象和代理对象的共同接口
代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能够代替真实对象。代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装
真实角色:代理角色所代表的真实对象,是我们最终要引用的对象
示例代码
//1.真实对象和代理对象的共同接口
public interface Singer {
void sing();
}
//2. 真实角色
public class Zhoujielun implements Singer {
@Override
public void sing() {
System.out.println("周杰伦在唱歌...");
}
}
//3. 代理角色
public class Jingjiren implements Singer {
// 代理角色持有对真实角色的引用
private Zhoujielun zhoujielun;
public Jingjiren() {
zhoujielun = new Zhoujielun();
}
@Override
public void sing() {
// 真实角色完成的功能
zhoujielun.sing();
}
}
//4. 测试类
public class Test {
public static void main(String[] args) {
Singer singer = new Jingjiren();
singer.sing();
}
}
二、动态代理
定义:客户通过代理类来调用其他对象的方法
创建的步骤
创建一个实现接口InvocationHandler的类,它必须实现invoke()方法
创建被代理的类以及接口
通过Proxy的静态方法newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)创建一个代理
通过代理调用方法
案例的实现,encodingFilter
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
// 1.强制类型转换
final HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
// 2.实现业务逻辑,对象方法的增强 继承、装饰者模式、动态代理
//创建代理对象
HttpServletRequest proxy = (HttpServletRequest) Proxy.newProxyInstance(request.getClass().getClassLoader(),
request.getClass().getInterfaces(), new InvocationHandler() {
//method:原方法
//args:原方法的参数
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//需要增强的方法
if(method.getName().equals("getParameter")){
//获取请求方式
String reqMethod = request.getMethod();
if("get".equalsIgnoreCase(reqMethod)){
String oldValue = request.getParameter((String) args[0]);
//下面这个代码就等价于request.getParameter(name);
//String oldValue = (String)method.invoke(request,args);
String newValue = new String(oldValue.getBytes("iso-8859-1"),"utf-8");
return newValue;
}else if ("post".equalsIgnoreCase(reqMethod)) {
request.setCharacterEncoding("utf-8");
}
}
return method.invoke(request, args);
}
});
//3.放行
chain.doFilter(proxy, response);
}
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
// 1.强制类型转换
final HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
// 2.实现业务逻辑,对象方法的增强 继承、装饰者模式、动态代理
//创建代理对象
HttpServletRequest proxy = (HttpServletRequest) Proxy.newProxyInstance(request.getClass().getClassLoader(),
request.getClass().getInterfaces(), new InvocationHandler() {
//method:原方法
//args:原方法的参数
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//需要增强的方法
if(method.getName().equals("getParameter")){
//获取请求方式
String reqMethod = request.getMethod();
if("get".equalsIgnoreCase(reqMethod)){
String oldValue = request.getParameter((String) args[0]);
//下面这个代码就等价于request.getParameter(name);
//String oldValue = (String)method.invoke(request,args);
String newValue = new String(oldValue.getBytes("iso-8859-1"),"utf-8");
return newValue;
}else if ("post".equalsIgnoreCase(reqMethod)) {
request.setCharacterEncoding("utf-8");
}
}
return method.invoke(request, args);
}
});
//3.放行
chain.doFilter(proxy, response);
}