动态代理

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

  这里就不在赘述了,看上一篇静态代理就行。

2.动态代理的代理类是动态生成的

3.分为两类-----类基于接口动态代理和基于类的动态代理

      a)基于接口动态代理---JDK动态代理

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

     现在javasist来生成动态代理

4.JDK动态代理--Proxy类和InvocaHandler接口

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

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

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

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

参数:

     proxy:在其上调用方法的处理实例

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

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

返回:

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

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

static Object newProxyInstance(ClassLoader lodaer,Class<?> interfaces,InvocationHandler h)

  返回一个指定接口的代理类实例,=该接口可以将方法调用指派到指定的调用处理程序。此方法相当于:

Proxy.getProxyClass(loader,interfaces). getConstructor(new Class[] {InvocationHandler.class}). newInstance(new Object[]{handler});

Proxy.newProxyInstance抛出IllegalArgumentException,原因与Proxy.getProxyClass相同。

参数:

    loader --定义代理类的类加载器

    interfaces --代理类要实现的接口列表

    h -指派方法调用的调用处理程序

5.实现:

  接下来感受一下动态代理

UserService.java接口类

public interface UserService {
	public void add();
	public void delete();
	public void update();
	public void search();
}

UserServiceImpl.java实现类

public class UserServiceImpl implements UserService{
	public void add() {		
		System.out.println("增加用户...................");		
	}
	public void delete() {	
		System.out.println("删除用户...................");		
	}
	public void update() {		
		System.out.println("更新用户...................");		
	}
	public void search() {	
		System.out.println("查询用户...................");		
	}
}

创建一个代理类

public class ProxyInovationHandler implements InvocationHandler{
	//target 依赖目标  要代理的事务
	private Object target;
	public void setRent(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+"方法...................");
	}
}

UserClient.java

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

仔细敲完几遍代码并体会代理的感觉,可以得出,只要有接口类和实现方法,就可以让代理类去执行

public class ListTest {	
	public static void main(String[] args) {
		ProxyInovationHandler pih=new ProxyInovationHandler();
		pih.setTarget(new ArrayList());
		List list=(List) pih.getProxy();
		list.add("你好");
		list.add("嗯嗯");	
	}

}

若还有不太懂的可以的看视频:链接:https://pan.baidu.com/s/1cK4cryW08KlRt2TriGoPIw 
提取码:xud4 
 

 

 

 

 

 

 

 

 

 

 

posted @   _SpringCloud  阅读(18)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 提示词工程——AI应用必不可少的技术
· 地球OL攻略 —— 某应届生求职总结
· 字符编码:从基础到乱码解决
· SpringCloud带你走进微服务的世界
点击右上角即可分享
微信分享提示