动态代理

引入:

什么是动态代理?

为什么要用动态代理?

在什么时候要用到动态代理?

 

代理是java的一种设计模式,他们的特征是,有俩个类,一个是委托类,一个是代理类,他们都实现了同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。 

根据代理的时间可以分为两类:静态代理和动态代理

静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。它比较死板,一个代理类只可以给一个接口类提供服务。如果有很多的委托类,就要写很多的代理类,这样就回导致代码的重复。所以有了动态代理来解决这个问题。

 
动态代理:在程序运行时,运用反射机制动态创建而成。

举个生活中的例子来说下这个问题:

范冰冰在成名之前,一些业务总是要自己去处理,比如说拍电影要对方那多少钱来等等,成名后她就找了个经济人,她就是我们所说的委托类,而经济人就是代理类,所以我们是无法直接找范冰冰本人了,我们要去找经济人,就是去找代理类处理一些问题,比如说要对方给100000块钱,经济人才会起表演,其实最终还是有范爷本人去表演,只是经济人把我们拦了下来,加上了条件,我们满足了条件,经济人才会去通知范爷给我们表演。所以动态代理也适合做权限的拦截。

下面具体来了解下:

和动态代理有关的有两个类 
1.interface InvocationHandler 
Object invoke(Object proxy, Method method, Object[] args) 
只这一个方法,后面再说 

2.class Proxy 
真正表示动态代理的类,提供两个静态方法: 

Class<?> getProxyClass(ClassLoader loader, Class<?>[] interface) 
用来产生代理类,参数要提供interface数组,它会生成这些interface的“虚拟实现”, 
用来冒充真实的对象。 

Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 
产生代理对象,多了InvocationHandler参数(只是InvocationHandler接口的实现类), 
它与代理对象关联,当请求分发到代理对象后,会自动执行h.invoke(...)方法, 
invoke方法就是我们用来做N多事情的地方 -_-。参数说明:

ClassLoader loader:类加载器 (下面有介绍)
Class<?>[] interfaces:得到全部的接口 
InvocationHandler h:得到InvocationHandler接口的子类实例 

类加载器 
在Proxy类中的newProxyInstance()方法中需要一个ClassLoader类的实例,ClassLoader实际上对应的是类加载器,在Java中主要有一下三种类加载器; 
Booststrap ClassLoader:此加载器采用C++编写,一般开发中是看不到的; 
Extendsion ClassLoader:用来进行扩展类的加载,一般对应的是jre\lib\ext目录中的类; 
AppClassLoader:(默认)加载classpath指定的类,是最常使用的是一种加载器。

不多说了,来个例子看看

动态代理可以实现拦截,我就用个过滤器类来体现下吧!

这个过滤器是用来解决javaweb中的乱码问题的:

这里我们要增强request的功能,而要增强一个对象的功能有以下几种方法:

1,写一个子类;

2,写一这个对象的包装类;

3,用动态代理

而在这里我们可以用动态代理和包装类比较合适,我就写段动态代理的吧;

public class CharacterEncodingFilter2 implements Filter {

	public void doFilter(ServletRequest req, ServletResponse res,
			FilterChain chain) throws IOException, ServletException {
		final HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) res;

		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		response.setCharacterEncoding("utf-8");

		chain.doFilter((ServletRequest)Proxy
				.newProxyInstance(CharacterEncodingFilter2.class
						.getClassLoader(), request.getClass()
						.getInterfaces(), new InvocationHandler() {

					public Object invoke(Object proxy, Method method,
							Object[] args) throws Throwable {
						if (!method.getName().equals("getParameter")) {
							return method.invoke(request, args);
						}
						if (!request.getMethod().equalsIgnoreCase("get")) {
							return method.invoke(request, args);
						}
						String  value = (String) method.invoke(request, args);

						if (value == null) {
							return null;
						}
						value = new String(value.getBytes(
								"iso8859-1"), "utf-8");
						return value;
					}
				}), response);

	}

	public void init(FilterConfig filterConfig) throws ServletException {
	}

	public void destroy() {
	}

}

新手一枚,如果有什么不对的地方,往高手多多指点!!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值