• 基于Java的设计模式 - 代理模式


    代理模式是一种使用代理对象来执行目标对象的方法并在代理对象中增强目标对象方法的一种设计模式。简单来讲就是在不修改目标对象的基础上,增强主业务逻辑的设计模式。

    代理模式基本可分为三种

    • 静态代理
    • JDK动态代理
    • CGLIB动态代理

    上述简单分就是静态和动态代理,静态代理即程序运行之前已创建了代理类,动态代理是程序运行时通过反射机制动态创建代理对象

    静态代理

    DoService.java

    //主业务接口
    public interface DoService {
    	void doSomething();
    }
    
    • 1
    • 2
    • 3
    • 4

    DoServiceImpl.java

    public class DoServiceImpl implements DoService {
    
    	@Override
    	public void doSomething() {
    		// TODO Auto-generated method stub
    		System.out.println("业务操作");
    	}
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    ServiceProxy.java

    //代理类
    public class ServiceProxy implements DoService {
    	
    	private DoService target;
    	
    	public ServiceProxy(){
    		super();
    		//创建目标对象
    		target = new DoServiceImpl();
    	}
    	
    	@Override
    	public void doSomething() {
    		// TODO Auto-generated method stub
    		System.out.println("代理类--业务处理前操作");
    		target.doSomething();
    		System.out.println("代理类--业务处理后操作");
    	}
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    TestStaticProxy.java

    public class TestStaticProxy {
    	public static void main(String[] args) {
    		DoService service = new ServiceProxy();
    		service.doSomething();
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    JDK动态代理

    DoService.java

    //主业务接口
    public interface DoService {
    	void doSomething();
    }
    
    • 1
    • 2
    • 3
    • 4

    DoServiceImpl.java

    public class DoServiceImpl implements DoService {
    
    	@Override
    	public void doSomething() {
    		// TODO Auto-generated method stub
    		System.out.println("业务操作");
    	}
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    TestJdkProxy.java

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class TestJdkProxy {
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		DoService target = new DoServiceImpl();
    		// 使用JDK的Proxy动态代理,要求目标类必须实现接口
    		// 因为其底层的执行原理,与静态代理相同
    		DoService service = (DoService) Proxy.newProxyInstance(target.getClass().getClassLoader(), // 目标类的类加载器
    			target.getClass().getInterfaces(), // 目标类所实现的所有接口
    			new InvocationHandler() { // 匿名内部类
    
    				// proxy:代理对象
    				// method:目标方法
    				// args 目标方法的参数列表
    				@Override
    				public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    					// TODO Auto-generated method stub
    					System.out.println("代理类--业务处理前操作");
    					// 调用目标方法
    					Object result = method.invoke(target, args);
    					System.out.println("代理类--业务处理后操作");
    					return result;
    				}
    			});
    		service.doSomething();
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    使用jdk的proxy实现代理,要求目标类与代理类实现相同的接口,若目标类不存在接口,则无法使用该方式实现

    CGLIB动态代理

    DoService.java

    //主业务
    public class DoService {
    	public void doSomething() {
    		System.out.println("业务操作");
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    MyCglibFactory.java

    import java.lang.reflect.Method;
    
    import net.sf.cglib.proxy.Enhancer;
    import net.sf.cglib.proxy.MethodInterceptor;
    import net.sf.cglib.proxy.MethodProxy;
    
    public class MyCglibFactory implements MethodInterceptor {
    
    	private DoService target;
    	
    	public MyCglibFactory() {
    		super();
    		// TODO Auto-generated constructor stub
    		target = new DoService();
    	}
    	
    	public DoService MyCglibCreator(){
    		//创建增强器对象
    		Enhancer enhancer = new Enhancer(); 
    		//指定目标类,即父类
    		enhancer.setSuperclass(DoService.class);
    		//设置回调接口对象
    		enhancer.setCallback(this);
    		
    		return (DoService) enhancer.create();
    	}
    	
    	@Override
    	public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
    		// TODO Auto-generated method stub
    		System.out.println("代理类--业务处理前操作");
    		Object result = method.invoke(target, args);
    		System.out.println("代理类--业务处理后操作");
    		return result;
    	}
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    TestCglibProxy.java

    public class TestCglibProxy {
    	public static void main(String[] args) {
    		DoService service = new MyCglibFactory().MyCglibCreator();
    		service.doSomething();
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    对于无接口的类,要为其创建动态代理,就要使用CGLIB来实现,CGLIB代理的生成原理是生成目标类的子类,而子类是增强过,这个子类对象就是代理对象,所以使用CGLIB生成动态代理,要求目标必须能够被继承,即不能是final的类

  • 相关阅读:
    (附源码)springboot在线考试系统 毕业设计 160935
    别乱用了!文件写入的6种方法
    【阿里云】域名解析 & Tomcat绑定域名
    基于Java+vue前后端分离失物招领信息交互平台设计实现(源码+lw+部署文档+讲解等)
    golang 运算符
    【MQTT】阿里云MQTT C++ 版本 登录三元组计算获取username、password
    Flink / SQL - 6.Tumble、Slide、Session、Over Window 详解
    Redis高级
    【sfu】rtc 入口
    RSS订阅
  • 原文地址:https://blog.csdn.net/flash_love/article/details/132968943