Java设计模式--代理模式

代理模式的概念:

代理模式是对象的结构模式。代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用,以控制对这个对象的访问。 代理类和委托类有共同的父类或父接口,这样在任何使用委托类对象的地方都可以用代理对象替代。代理类负责请求的预处理、过滤、将请求分派给委托类处理、以及委托类执行完请求后的后续处理。 

1.静态代理:

由程序员创建或工具生成代理类的源码,再编译代理类。所谓静态也就是代理类和委托类的关系在运行前就确定了,在程序运行前就已经存在代理类的字节码文件(class文件)。

2.

1)JDK动态代理:

动态代理类是在程序运行期间由JVM根据反射等机制动态的生成。代理类和委托类的关系是在程序运行时确定的,所以其字节码文件是动态生成的。

注:JDK动态代理只能代理实现了接口的类,而没有实现接口的类就不能用JDK的动态代理

2)cgllib动态代理:

针对类来实现代理的,他的原理是采用的是继承的方式,对指定的目标类生成一个子类,并覆盖其中方法实现增强;但因为采用的是继承,所以不能对final修饰的类进行代理。 


3. 静态&动态代理 例子如下:(建议先看接口1相关的内容,进阶再结合接口2)

package com.founder.rcp.controller;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class TestProxy {
	
public static void main(String[] args) {

	//静态代理1:调用静态代理类工厂
	Subject sub1= StaticProxyFactory.getInstance();
	sub1.opearate();
	sub1.op2();
	
	//静态代理2
	Subject2 sub2 = StaticProxyFactory.getInstance2();
	sub2.op3();
	
	//动态代理1
	Subject dynProxyIns = DynProxyFactory.newProxyInstance();
	dynProxyIns.opearate();
	dynProxyIns.op2();
	
	//动态代理2 
	Subject2 dyn2 = DynProxyFactory.newProxyInstance2();
	dyn2.op3();
	//静态代理VS动态代理总结:
	//1. 静态代理,有两个接口就得写两个代理类,扩展性差;而动态代理1和动态代理2 可以共用一个SubjectInvocationHandler,减少了类的数量;
	//2.当接口中有多个方法,静态代理需要每个方法都进行中转;而动态代理可以把接口中所有的方法转移到SubjectInvocationHandler(调用处理器)的一个集中方法(invoke)处理,
		//实际应用中可以用spring AOP把外围业务抽离出来(即invoke方法中不嵌入具体的外围业务),起到解耦合的作用。
}

}

/**
 *  动态代理类对应的调用处理类
 * @author li_yuhua
 *
 */
class SubjectInvocationHandler implements InvocationHandler{//<span style="font-family: Arial, Helvetica, sans-serif;">InvocationHandler: JDK中的调用处理器通用接口,<span style="font-family: Helvetica, Tahoma, Arial, sans-serif; font-size: 14px; line-height: 25.2000007629395px;">它自定义了一个 invoke 方法,用于集中处理在动态代理类对象上的方法调用,通常在该方法中实现对委托类的代理访问。每次生成动态代理类对象时都要指定一个对应的调用处理器对象。 </span></span>
	
	//委托类
	Object sub;
	
	public SubjectInvocationHandler(Object subject){
		this.sub = subject;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		System.out.println("动态预处理。。。。");
		//利用反射将请求分派给为委托类执行
		method.invoke(sub, args);
		System.out.println("动态后处理。。。。");
		return null;
	}
	
}

/**
 * 生成动态代理类的工厂类
 * @author li_yuhua
 *
 */
class DynProxyFactory{
	public static Subject newProxyInstance(){
		Subject realSub = new RealSubject();
		//InvocationHandler:调用处理器接口
		InvocationHandler subInvoHandler = new SubjectInvocationHandler(realSub);
		Subject dynProxy = null;
		//Proxy:所有动态代理类的父类<span style="font-family: Arial, Helvetica, sans-serif;">,</span><span style="font-family: Arial, Helvetica, sans-serif;">它提供了一组静态方法来为一组接口动态地生成代理类及其对象</span>
		dynProxy = (Subject)Proxy.newProxyInstance(realSub.getClass().getClassLoader(), realSub.getClass().getInterfaces(), subInvoHandler);
		return dynProxy;
	}
	
	public static Subject2 newProxyInstance2(){
		Subject2 realSub2 = new RealSubject2();
		//InvocationHandler:调用处理器接口
		InvocationHandler subInvoHandler = new SubjectInvocationHandler(realSub2);
		Subject2 dynProxy = null;
		dynProxy = (Subject2)Proxy.newProxyInstance(realSub2.getClass().getClassLoader(), realSub2.getClass().getInterfaces(), subInvoHandler);
		return dynProxy;
	}
	
}

interface Subject{
	public void opearate();
	public void op2();
}

interface Subject2{public void op3();}

/**
 * 委托类
 * @author li_yuhua
 *
 */
class RealSubject implements Subject{

	@Override
	public void opearate() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void op2() {
		// TODO Auto-generated method stub
		
	}}

/**
 * 委托类2:实现了接口2
 * @author li_yuhua
 *
 */
class RealSubject2 implements Subject2{

	@Override
	public void op3() {
		// TODO Auto-generated method stub
		
	}
	
}

/**
 * 静态代理类1
 * @author li_yuhua
 *
 */
class ProxySubject implements Subject{
	RealSubject real = new RealSubject();

	@Override
	public void opearate() {
		// TODO Auto-generated method stub
		System.out.println("预处理方法1");
		real.opearate();
		System.out.println("后处理方法1");
		
	}

	@Override
	public void op2() {
		System.out.println("预处理方法2");
		real.op2();
		System.out.println("后处理方法2");
		
	}
	
}

/**
 * 静态代理类2
 */
class ProxySubject2 implements Subject2{
	Subject2 real = new RealSubject2();
	@Override
	public void op3() {
		System.out.println("预处理方法3");
		real.op3();
		System.out.println("后处理方法3");
		
	}

}

/**
 * 静态代理工厂类
 */
class StaticProxyFactory{
	
	public static Subject getInstance(){
		return new ProxySubject();
	}
	
	public static Subject2 getInstance2(){
		return new ProxySubject2();
	}
}

输出结果:

预处理方法1
后处理方法1
预处理方法2
后处理方法2
预处理方法3
后处理方法3
动态预处理。。。。
动态后处理。。。。
动态预处理。。。。
动态后处理。。。。
动态预处理。。。。
动态后处理。。。。


4. Cglib动态代理 例子如下:

package com.founder.rcp.controller;

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 TestCGLib {
	public static void main(String[] args) {
		CglibProxy cglib = new CglibProxy();
		//cglib:通过生成子类的方式创建代理类 
		Consigner con = (Consigner)cglib.getProxy(new Consigner());
		con.opearate();
	}
	
	

}

/**
 * 代理类
 */
class CglibProxy implements MethodInterceptor{
	
	//委托类成员声明
	private Object target;

	//创建代理对象
	public Object getProxy(Object target){
		this.target = target;
		Enhancer hancer = new Enhancer();//增强者
		//设置代理类的父类(target)
		hancer.setSuperclass(this.target.getClass());
		hancer.setCallback(this);
		//创建代理对象:通过字节码技术动态创建实例  
		Object agent =hancer.create();
		return agent;
	}
	
	//实现MethodInterceptor接口方法 
	@Override
	public Object intercept(Object obj, Method method, Object[] args,
			MethodProxy proxy) throws Throwable {
		System.out.println("预处理,事务等。。。");
			//通过代理类调用父类中的方法 
			proxy.invokeSuper(obj, args);
		System.out.println("后处理,事务等。。。");
		return null;
	}
	
	
}


/**
 * 委托类
 * @author li_yuhua
 *
 */
class Consigner{
	public void opearate(){System.out.println("方法中");};
}

输出结果:

预处理,事务等。。。
方法中
后处理,事务等。。。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值