代理(Proxy)

本文介绍了Java代理(Proxy)的概念,它允许我们对指定接口的方法进行功能扩展。通过Java.lang.reflect.Proxy类提供的newProxyInstance方法,我们可以创建目标对象的代理实例。代理对象在执行接口方法时会触发InvocationHandler事件处理器,将当前执行的方法作为参数传入。文章举例说明了在HTTP请求参数编码处理的过滤器中为HttpServletRequest创建代理对象,以及为Connection对象创建代理对象的应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代理(Proxy)

      对指定接口的某一个方法进行功能扩展,可以使用代理

代理API

|--java.lang.reflect.Proxy

         static Object newProxyInstance(

  ClassLoader loader,    当前使用的类加载器

  Class<?>[] interfaces,   目标对象实现的接口类型

  InvocationHandler h    事件处理器:当执行上面接口中的方法的时候,就会自动触发事件处理器代码,把当前执行的方法(method)作为参数传入。

       )

案例:

①在处理http请求参数时,编码处理时过滤器的编写,为HttpServletRequest对象创建代理对象

package com.cn.filter;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * 编码处理过滤器
 * @author liuzhiyong
 *
 */
public class EncodingFilter implements Filter{
	
	/**
	 * 过滤器业务处理方法:处理公用的业务逻辑操作
	 */
	@Override
	public void doFilter(ServletRequest req, ServletResponse res,
			FilterChain chain) throws IOException, ServletException {
		
		//转型
        //目标对象
		final HttpServletRequest request = (HttpServletRequest)req;
		HttpServletResponse response = (HttpServletResponse)res;
		/**
		 * 1.处理公用的逻辑业务
		 */
		//设置post方式提交的请求的编码
		request.setCharacterEncoding("utf-8");//只对POST提交有效
		//设置页面打开时的编码格式,设置响应体的编码格式
		response.setContentType("text/html;charset=utf-8");
		
		/**
		 * 出现get中文乱码,是因为在request.getParameter("参数名")方法内部没有进行提交方式判断并处理
		 * 
		 * 解决:对指定接口的某一个方法进行功能扩展,可以使用代理:
		 * 		对request对象(目标对象),创建代理对象
		 */
		HttpServletRequest requestProxy =(HttpServletRequest)Proxy.newProxyInstance(
				request.getClass().getClassLoader(),// 定义代理对象类的类加载器。负责加载类的对象
				new Class[]{HttpServletRequest.class}, //代理类要实现的接口列表
				new InvocationHandler(){//// 当调用目标对象对象方法的时候, 自动触发事务处理器
			@Override
			public Object invoke(Object proxy, Method method, Object[] args)//这里的args是调用方法传入的参数
					throws Throwable {
				//定义方法返回值
				Object returnValue = null;
				
				//当前执行方法的方法名
				String methodName = method.getName();
				//判断:对getParameter方法进行GET方式提交中文处理
				if("getParameter".equals(methodName)){
					
					//获取请求数据的值
					String parameterValue = request.getParameter(args[0].toString());//调用目标对象的方法
					
					//获取提交请求的提交方式
					String submitMethod = request.getMethod();
					
					//判断,如果是GET提交,需要对数据进行处理(POST提交已经处理过了)
					if("GET".equals(submitMethod)){//注意在Servlet中这里是大写的GET
						if(parameterValue!=null && !"".equals(parameterValue.trim())){
							//处理GET方式提交的中文
							parameterValue = new String(parameterValue.getBytes("ISO-8859-1"), "UTF-8");
						}
					}
					return parameterValue;//返回getParameter方法的返回值
				}else{
					returnValue = method.invoke(request, args);//调用目标对象request的其它方法
					return returnValue;//返回返回值
				}
			}
		});
		
		
		//2.放行(进入下一个过滤器或者进入Servlet)
		chain.doFilter(requestProxy, response);//传入request代理对象requestProxy
	}
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		// TODO Auto-generated method stub
		
	}
	
	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		
	}
}
②为Connection对象创


②为Connection对象创建代理对象

//原始的目标对象
final Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root", "root");
/*****************对Connection对象代理***********************/
//对conn创建其代理对象。返回一个指定接口的代理类实例
Connection proxy = (Connection)Proxy.newProxyInstance(
	conn.getClass().getClassLoader(),// 定义代理类的类加载器。负责加载类的对象。
	new Class[]{Connection.class},//代理类要实现的接口列表
	new InvocationHandler(){// 当调用con对象方法的时候, 自动触发事务处理器
		@Override
		public Object invoke(Object proxy, Method method,
				Object[] args) throws Throwable {
			//方法返回
			Object result = null;
			// 当前执行的方法的方法名
			String methodName = method.getName();
			if("close".equals(methodName)){
				//连接放入连接池
				pool.add(conn);
			}else{
				result = method.invoke(conn, args);//// 调用目标对象的其它方法
			}
			return result;
		}
		
	}//指派方法调用的调用处理程序 
);


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值