zoukankan      html  css  js  c++  java
  • java代理与动态代理的学习

    静态代理比较简单,就是代理对象与被代理对象继承相同的接口,代理类负责调用被代理类(委托类)的对象的相关方法去提供具体的服务,一个代理类只能为一个接口服务,要是有很多服务的话需要开很多代理类。而动态代理则是由反射实现,可以用一个代理类实现所有的代理功能,这点是比较方便的。

    先看看静态代理:

    一个接口类,若干个接口实现类和一个代理类即可

    接口

    package proxy;
    
    public interface Women {
        public void eat();
        public void play();
     
    }
    

    接口实现类一

    package proxy;
    
    public class Lily implements Women{
     
        @Override
        public void eat() {
            System.out.println("i'm Lily,i love eat banana");
        }
     
        @Override
        public void play() {
            System.out.println("i'm Lily,i love swimming");
        }
     
    }
    

    接口实现类二

    package proxy;
    
    public class Juli implements Women{
     
        @Override
        public void eat() {
            System.out.println("i'm Juli,i love eat banana");
        }
     
        @Override
        public void play() {
            System.out.println("i'm Juli,i love swimming");
        }
     
    }
    

    代理类

    package proxy;
    
    public class Proxy implements Women{
    	private Women women;
    	public Proxy(){
    		this.women=new Lily();//设一个代理的默认值
    	}
    	public  Proxy(Women women){
    		this.women=women;
    	}
    	@Override
    	public void eat() {
    		this.women.eat();
    	}
    	@Override
    	public void play() {
    		this.women.play();
    	}
    
    }
    

    测试

    package proxy;
    
    public class StaticProxyTest {
    	public static void main(String[] args) {
    		Proxy p;
    		p=new Proxy();
    		p.eat();
    		p.play();
    		p=new Proxy(new Juli());
    		p.eat();
    		p.play();
    	}
    
    }
    

    测试结果 

    i'm Lily,i love eat banana
    i'm Lily,i love swimming
    i'm Juli,i love eat banana
    i'm Juli,i love swimming
    

    动态代理的话主要有两种实现方式,一种是jdk动态代理实现,一种是cglib代理。JDK动态代理只能针对实现了接口的类生成代理,CGLIB(CODE GENERLIZE LIBRARY)代理是针对类实现代理,

    主要是对指定的类生成一个子类,覆盖其中的所有方法,所以该类或方法不能声明称final的。

    先看看jdk代理

    代理类

    package proxy;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class JdkProxy implements InvocationHandler{
    	private Women women;
    	public JdkProxy(Women women){
    		this.women=women;
    	}
    	public static Women newProxyInstance(Women women){
    		return (Women) Proxy.newProxyInstance(JdkProxy.class.getClassLoader(), new Class<?>[] { Women.class }, new JdkProxy(women));
    		
    	}
    
    	@Override
    	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    		return method.invoke(women, args);
    	}
    
    }
    

    改成通用点的

    package proxy;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class JdkProxy implements InvocationHandler{
    	
    	private  Object obj;
    	public JdkProxy(Object obj){
    		this.obj=obj;
    	}
    	public static Object newProxyInstance(Object targetObject){//传入的是类的实现接口
    		return Proxy.newProxyInstance(JdkProxy.class.getClassLoader(), targetObject.getClass().getInterfaces(),new JdkProxy(targetObject));
    		
    	}
    
    	@Override
    	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    		return method.invoke(this.obj, args);
    	}
    
    }
    

      

    测试类 

    package proxy;
    
    public class JdkProxyTest {
    	public static void main(String[] args) {
    		Women women= JdkProxy.newProxyInstance(new Lily());
    		women.eat();
    		women.play();
    	}
    
    } 

     

    测试结果

    i'm Lily,i love eat banana
    i'm Lily,i love swimming
    

      

    Cglib代理类

    package proxy;
    
    import java.lang.reflect.Method;
    
    import org.springframework.cglib.proxy.Enhancer;
    import org.springframework.cglib.proxy.MethodInterceptor;
    import org.springframework.cglib.proxy.MethodProxy;
    
    public class CglibProxy implements MethodInterceptor {
    	private CglibProxy() {
    	}
    	public static <T extends Women> Women newProxyInstance(Class<T> targetInstanceClazz){
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(targetInstanceClazz);
            enhancer.setCallback(new CglibProxy());
            return (Women) enhancer.create();//返回的对象是一个封装了"实现类"的代理类,是实现类的实例
            
        }
    	
    	@Override
    	public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
    		return proxy.invokeSuper(obj, args);
    	}
    
    }
    

    改成通用点的

    package proxy;
    
    import java.lang.reflect.Method;
    
    import org.springframework.cglib.proxy.Enhancer;
    import org.springframework.cglib.proxy.MethodInterceptor;
    import org.springframework.cglib.proxy.MethodProxy;
    
    public class CglibProxy implements MethodInterceptor {
    	private CglibProxy() {
    	}
    	public static <T extends Object> Object newProxyInstance(Class<T> targetInstanceClazz){
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(targetInstanceClazz);
            enhancer.setCallback(new CglibProxy());
            return (Object) enhancer.create();//返回的对象是一个封装了"实现类"的代理类,是实现类的实例
            
        }
    	
    	@Override
    	public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
    		return proxy.invokeSuper(obj, args);
    	}
    
    }
    

     

    测试 

    package proxy;
    
    public class CglibTest {
    	public static void main(String[] args) {
    		Women women = (Women) CglibProxy.newProxyInstance(Lily.class);
    		women.eat();
    		women.play();
    	}
    
    }
    

    测试结果 

    i'm Lily,i love eat banana
    i'm Lily,i love swimming
    

      

     

  • 相关阅读:
    hello world
    first demo
    Mac出现Operation not permitted
    java 获取一个数字中,各个数字出现的次数
    java 判断回文数字
    202001031
    20200103
    华为手机的系列
    java 反向打印一个数字
    java 生成两个数之间的素数
  • 原文地址:https://www.cnblogs.com/JAYIT/p/6386759.html
Copyright © 2011-2022 走看看