阿里云大学JavaWeb开发系列课程:Spring框架入门第十讲动态代理

动态代理

1、动态代理和静态代理的角色是一样的。

2、动态代理的代理类是动态生成的。

3、分为两类,一类基于接口动态代理和基于类的动态代理。

a)基于接口动态代理——jdk动态代理

b)基于类的动态代理——cglib

现在javassist来生成动态代理

4、jdk动态代理——Proxy类和InvocationHander接口

5、InvocationHandler是代理实例的调用处理程序实现的接口。

6、每个代理实例都具有一个关联的调用处理程序。对代理实例调用方法时,将对方法调用进行编码并将其指派到它的调用处理程序的invoke方法。

Object invoke(Object proxy,Method method,Object[] args)在代理实例上处理方法调用并返回结果。

在代理实例上处理方法调用并返回结果。在与方法关联的代理实例上调用方法时,将在调用处理程序上调用此方法。

参数:

proxy——在其上调用方法的代理实例

method——对应于在代理实例上调用的接口方法的Method实例。Method对象的声明类将是在其中声明方法的接口,该接口可以是代理类赖以继承方法的代理接口的超接口。

args——包含传入代理实例上方法调用的参数值的对象数组,如果接口方法不使用参数,则为null。基本类型的参数被包装在适当基本包装器类(如java.lang.Integer或java.lang.Boolean)的实例中。

返回:

从代理实例的方法调用返回的值。如果接口方法的声明返回类型是基本类型,则此方法返回的值一定是相应基本包装对象类的实例;否则,它一定是可分配到声明返回类型的类型。如果此方法返回的值为null并且接口方法的返回类型是基本类型,则代理实例上的方法调用将抛出NullPointerException。否则,如果此方法返回的值与上述接口方法的声明返回类型不兼容,则代理实例上的方法调用将抛出ClassCastException。

Proxy提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类。

Client.java

package cn.sxt.dynamicproxy;


public class Client {
	public static void main(String[] args) {
		Host host=new Host();
		ProxyInovationHandler pih =new ProxyInovationHandler();
		pih.setRent(host);
		Rent proxy =(Rent)pih.getProxy();
		proxy.rent();
	}
}

Host.java

package cn.sxt.dynamicproxy;

public class Host implements Rent {
	public void rent() {
		System.out.println("房屋出租");
	}
}

ProxyInovationHandler.java

package cn.sxt.dynamicproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyInovationHandler implements InvocationHandler{
	private Rent rent;
	
	
	public void setRent(Rent rent) {
		this.rent = rent;
	}
	/*
	 * 生成代理类
	 */
	public Object getProxy() {
		return Proxy.newProxyInstance(this.getClass().getClassLoader(), 
				rent.getClass().getInterfaces(), this);
	}
	/*
	 * proxy是代理类
	 * method 代理类的调用处理程序的方法对象
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) 
			throws Throwable {
		seeHouse();
		Object result =method.invoke(rent, args);
		fare();
		return result;
	}
	private void seeHouse() {
		System.out.println("带房客看房");
	}
	//收中介费
	private void fare() {
		System.out.println("收取中介费");
	}

}

Rent.java

package cn.sxt.dynamicproxy;

public interface Rent {
	public void rent() ;
}

ProxyInovationHandler.java

package cn.sxt.dynamicproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyInovationHandler implements InvocationHandler{
	private Object target;//目标对象——真实对象
	public void setTarget(Object target) {
		this.target = target;
	}
	/*
	 * 生成代理类
	 */
	public Object getProxy() {
		return Proxy.newProxyInstance(this.getClass().getClassLoader(), 
				target.getClass().getInterfaces(), this);
	}
	/*
	 * proxy是代理类
	 * method 代理类的调用处理程序的方法对象
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) 
			throws Throwable {
		seeHouse();
		Object result =method.invoke(target, args);
		fare();
		return result;
	}
	//看房
	private void seeHouse() {
		System.out.println("带房客看房");
	}
	//收中介费
	private void fare() {
		System.out.println("收取中介费");
	}

}

Client.java

package cn.sxt.dynamicproxy;

import cn.sxt.service.UserService;
import cn.sxt.service.UserServiceImpl;

public class Client {
	public static void main(String[] args) {
		UserService userService=new UserServiceImpl();
		ProxyInovationHandler pih =new ProxyInovationHandler();
		pih.setTarget(userService);
		UserService proxy =(UserService)pih.getProxy();
		proxy.search();
	}
}


ProxyInovationHandler.java

package cn.sxt.dynamicproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyInovationHandler implements InvocationHandler{
	private Object target;//目标对象——真实对象
	public void setTarget(Object target) {
		this.target = target;
	}
	/*
	 * 生成代理类
	 */
	public Object getProxy() {
		return Proxy.newProxyInstance(this.getClass().getClassLoader(), 
				target.getClass().getInterfaces(), this);
	}
	/*
	 * proxy是代理类
	 * method 代理类的调用处理程序的方法对象
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) 
			throws Throwable {
		log(method.getName());
		Object result =method.invoke(target, args);
		return result;
	}
	public void log(String methodName) {
		System.out.println("执行"+methodName+"方法");
	}
}

到这里动态代理就完成了.

一个动态代理一般代理某一类业务,一个动态代理可以代理多个类。


Client.java

package cn.sxt.dynamicproxy;

import java.util.ArrayList;
import java.util.List;

import cn.sxt.service.UserService;
import cn.sxt.service.UserServiceImpl;

public class Client {
	public static void main(String[] args) {
//		UserService userService=new UserServiceImpl();
//		ProxyInovationHandler pih =new ProxyInovationHandler();
//		pih.setTarget(userService);
//		UserService proxy =(UserService)pih.getProxy();
//		proxy.search();
		ProxyInovationHandler ph =new ProxyInovationHandler();
		ph.setTarget(new ArrayList());
		List list =(List)ph.getProxy();
		list.add("hello");
		}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值