zoukankan      html  css  js  c++  java
  • Java代理模式

    代理模式

    23中(Gof)中代理模式中的一种,AOP本身就是基于动态代理实现的,所以掌握了代理模式对AOP的学习很有帮助,所以先讲下代理模式

    1.静态代理模式

    若代理类在程序运行前就已经存在,那么这种代理方式被成为 静态代理 ,这种情况下的代理类通常都是我们在Java代码中定义的。 通常情况下, 静态代理中的代理类和目标类会实现同一接口或是派生自相同的父类。

    1.1 创建接口

    /**
    * 定义公共接口
    * @author dpb[波波烤鸭]
    *
    */
    public interface SomeService {
       String doSome();
    }
    

    1.2 创建接口实现类

    /**
    * 静态代理模式的实现类
    * @author dpb[波波烤鸭]
    *
    */
    public class SomeServiceImpl implements SomeService{
       @Override
       public String doSome() {
       	// TODO Auto-generated method stub
       	return "hello";
       }
    }
    

    1.3 创建静态代理类

    /**
    * 代理类
    *    增强实现类
    *    和实现类实现同一个接口
    * @author dpb[波波烤鸭]
    *
    */
    public class SomeProxy implements SomeService{
       private SomeService target;
       public SomeProxy(SomeService target) {
       	super();
       	this.target = target;
       }
       /**
        * 增强方法
        *    将返回结果转换为大写
        */
       @Override
       public String doSome() {
       	return target.doSome().toUpperCase();
       }
    }
    

    1.4 测试实现

       public static void main(String[] args) {
       	SomeService some = new SomeServiceImpl();
       	// 获取静态代理对象
       	SomeProxy proxy = new SomeProxy(some);
       	System.out.println(proxy.doSome());
       }
    

    在这里插入图片描述

    2.动态代理模式

    代理类在程序运行时创建的代理方式被成为 动态代理。 也就是说,这种情况下,代理类并不是在Java代码中定义的,而是在运行时根据我们在Java代码中的“指示”动态生成的。

    代理类型 使用场景
    JDK动态代理 如果目标对象实现了接口,采用JDK的动态代理
    cglib动态代理 如果目标对象没有实现了接口,必须采用CGLIB动态代理

    2.1.JDK动态代理

    声明接口

    /**
     * 定义公共接口
     * @author dpb[波波烤鸭]
     *
     */
    public interface SomeService {
    	String doSome();
    }
    

    创建实现类

    /**
     * 静态代理模式的实现类
     * @author dpb[波波烤鸭]
     *
     */
    public class SomeServiceImpl implements SomeService{
    	@Override
    	public String doSome() {
    		// TODO Auto-generated method stub
    		return "hello";
    	}
    }
    

    JDK代理实现

    public static void main(String[] args) {
    	SomeService some = new SomeServiceImpl();
    	// 获取静态代理对象
    	SomeService proxy = (SomeService) Proxy.newProxyInstance(
    			some.getClass().getClassLoader() // 实现类的类加载器
    			, some.getClass().getInterfaces() // 实现类 实现的所有的接口
    			, new InvocationHandler()  // 处理器
    			{
    				/**
    				 * proxy 代理对象
    				 * method 目标的方法
    				 * args 目标方法的参数
    				 */
    				@Override
    				public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    					String msg = (String) method.invoke(some, args);
    					return msg.toUpperCase();
    				}
    			});
    	System.out.println(proxy.doSome());
    
    }
    

    在这里插入图片描述

    2.2CGLIB动态代理

    导入cglib的jar包

    在这里插入图片描述

    创建目标类

    /**
     * 静态代理模式的实现类
     * @author dpb[波波烤鸭]
     *
     */
    public class SomeServiceImpl {
    	
    	public String doSome() {
    		// TODO Auto-generated method stub
    		return "hello";
    	}
    }
    

    创建cglib工厂

    /**
     * cglib代理类
     * @author dpb[波波烤鸭]
     *
     */
    public class CglibProxy implements MethodInterceptor{
    	
    	private SomeServiceImpl target;
    	
    	public CglibProxy(SomeServiceImpl target) {
    		this.target = target;
    	}
    
    	/**
    	 * 创建cglib代理对象的方法
    	 * @return
    	 */
    	public SomeServiceImpl createProxy(){
    		// 创建增强器
    		Enhancer e = new Enhancer();
    		// 指定父类
    		e.setSuperclass(SomeServiceImpl.class);
    		// 指定回调接口对象
    		e.setCallback(this);
    		// 创建cglib代理对象
    		return (SomeServiceImpl) e.create();
    	}
    
    	/**
    	 * 拦截方法
    	 */
    	@Override
    	public Object intercept(Object obj, Method method, Object[] agrs, MethodProxy proxy) throws Throwable {
    		String msg = (String)method.invoke(target, agrs);
    		return msg.toUpperCase();
    	}
    
    }
    
    

    测试

    public static void main(String[] args) {
    	// 定义目标对象
    	SomeServiceImpl some = new SomeServiceImpl();
    	// 获取代理对象
    	SomeServiceImpl proxy = new CglibProxy(some).createProxy();
    	System.out.println(proxy.doSome());
    }
    

    在这里插入图片描述

  • 相关阅读:
    git 分支管理 (转自廖雪峰的git教程)
    git 命令
    java8 日期处理
    Softmax回归 softMax回归与logistic回归的关系
    决策树 学习提纲(需要解决的一些问题)
    spark UDAF
    似然函数
    spark RDD,DataFrame,DataSet 介绍
    scala LocalDateTime String 转换
    将java.util.Date类型转换成json时,使用JsonValueProcessor将date转换成希望的类型
  • 原文地址:https://www.cnblogs.com/dengpengbo/p/10308068.html
Copyright © 2011-2022 走看看