• JDK动态代理


             

            那时候还小,仅仅记得代理模式就是 daili 给 SchoolGirl 送了洋娃娃,送了花,还送了巧克力

     

             代理模式是在訪问对象时引入一定程度的间接性,这样的间接性让我们能够趁机完毕很多想要的功能.代理模式的特征是代理类和托付类有相同的接口,代理类主要负责为托付类预处理消息,过滤消息,把消息转发给托付类,以及事后处理消息等.代理类对象和托付类对象关联,代理类对象是通过调用托付类的对象的相关方法提供特定的服务.

     

             代理类怎样被创建,怎样被调用,怎样默默调用了托付类一系列问题都须要我们弄明确,以下我们来看看代理到底是怎样实现的.

     

    代理分为静态代理和动态代理.

     

    1. 静态代理:

           为其他对象提供一种代理以控制对这个对象的訪问.之所以称之为静态,是由于程序猿或特定工具在编程时已经创建了代理类,之后编译成字节码文件.在程序执行前,代理类的.class文件已经存在了.


    业务接口类:


    package com.tgb.staticproxy;
    
    public interface UserManager {
    
    	public void addUser(String userId,String userName);
    
    	public String queryUser(String userId);
    }
    


    实现类:


    package com.tgb.staticproxy;
    
    public class UserManagerImpl implements UserManager {
    
    	@Override
    	public void addUser(String userId, String userName) {
    		try {
    			
    			System.out.println("UserManagerImpl.addUser() userId---" + userId);	
    			
    		} catch (Exception e) {
    			e.printStackTrace();
    			throw new RuntimeException();
    		}
    	}
    
    	@Override
    	public String queryUser(String userId) {
    		System.out.println("UserManagerImpl.queryUser() userId---" + userId);
    		return "转折";
    	}
    }
    


    代理类:


    package com.tgb.staticproxy;
    
    public class UserManagerImplProxy implements UserManager {
    
    	private UserManager userManager;
    	
    	public UserManagerImplProxy(UserManager userManager){
    		this.userManager=userManager;
    	}
    	
        public void addUser(String userId,String userName){
        	try {
    			System.out.println("start--addUser()--userId--" + userId);
    			userManager.addUser(userId, userName);
    			System.out.println("success");
    		} catch (Exception e) {
    			e.printStackTrace();
    			System.out.println("error");
    		}
        }
        public String queryUser(String userId){
        	return null;
        }    
    }
    


    client:


    package com.tgb.staticproxy;
    
    public class Client {
    
    	public static void main(String[] args){
    		UserManager userManager=new UserManagerImplProxy(new UserManagerImpl());
    		userManager.addUser("1001","转折");
    	}
    }
    


    执行结果:


          


    1. 动态代理:

            在程序执行时,运用反射机制动态创建代理类,不须要程序猿编写源码.动态代理简化了编程工作,提高了系统的可扩展性,由于Java反射机制能够生成随意类型的动态代理类.说究竟,java.lang.reflect包中的Proxy类和InvocationHandler接口提供了生成动态代理类的能力.

     

            详细说来,JDK动态代理中包括一个Proxy类和一个InvocationHandler接口.

            通过Proxy类为一个或多个接口动态地生成实现类,其方法是

    public static Object newProxyInstance(ClassLoader loader, Class<?

    >[] interfaces,

    InvocationHandler h) throws IllegalArgumentException{}

            通过InvocationHandler接口,调用实现类的方法,从而完毕终于操作.其方法是

    public interface InvocationHandler {

    public Object invoke(Object proxy,Method method,Object[] args) throws Throwable;

    }

      

    业务接口类:


    package com.tgb.Dynamicproxy;
    
    public interface UserManager {
    
    	public String Query(String userId);
    }
    


    实现类:


    package com.tgb.Dynamicproxy;
    
    public class UserManagerImpl implements UserManager{
    
    	@Override
    	public String Query(String userId) {
    		System.out.println("UserManagerImpl.Query()---userId--" + userId);
    		return "转折";
    	}	
    }
    


            在静态代理中,一个代理类仅仅能为一个接口提供代理,这种话,我们开发过程中须要写N多个代理类,并且它们间仅仅有调用的方法不一样而已.于是,我们希望仅仅用一个代理类就完毕所有的代理功能.在动态代理中,我们没有写好确定的代理类,而是有一个以下的类.

     

    产生代理的类:


    package com.tgb.Dynamicproxy;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class UserManagerImplProxy implements InvocationHandler {
    
    	private Object targetObject;
    	
    	public Object newProxyInstance(Object targetObject){
    		
    		this.targetObject=targetObject;
    		return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
    				targetObject.getClass().getInterfaces(),this);		
    	}
    	
    	public Object invoke(Object proxy,Method method,Object[] args)
    			throws Throwable{
    		System.out.println("start--" + method.getName());
    		for(int i=0;i<args.length;i++){
    			System.out.println(args[i]);
    		}
    		
    		Object ret=null;
    		
    		try {
    			ret=method.invoke(targetObject, args);
    			System.out.println("success--" + method.getName());
    		} catch (Exception e) {
    			e.printStackTrace();
    			System.out.println("error--" + method.getName());			
    		}
    		return ret;
    	}
    }
    


    client:


    package com.tgb.Dynamicproxy;
    
    public class Client {
    
    	public static void main(String[] args){
    		UserManagerImplProxy userManagerImplProxy=new UserManagerImplProxy();
    		UserManager userManager=(UserManager)userManagerImplProxy.newProxyInstance(new UserManagerImpl());
    		
    		String userName=userManager.Query("1001");
    		System.out.println("userName--" + userName);
    	}
    }
    


    执行结果:


               

              JDK动态代理的最大缺点是,它依靠接口实现,假设有的类没有实现接口,那么,它是不能使用JDK代理的.这个就是还有一种动态代理----cglib动态代理了.

     

           总结:    学习不是一条直线,温故而知新,是收获的时候了.



  • 相关阅读:
    Google Go语言推出第一个正式版本:Go 1
    前端开发工作感悟:具体的量化指标
    AIR SDK 更新方法
    HTML5 MediaStream的运用
    理解css中的长度单位
    快速提高 Vi/Vim 使用效率的原则与途径
    Saving the Day with Scoped CSS
    事件的发生顺序HTML5移动开发
    BigPipe学习研究
    构建合规的Web应用程序
  • 原文地址:https://www.cnblogs.com/wzzkaifa/p/6780230.html
Copyright © 2020-2023  润新知