代理模式 Proxy Pattern

代理模式 Proxy Pattern


Provide a surrogate or placeholder for another object to control access to it.
为其他对象提供一种代理以控制对这个对象的访问。
«Java设计模式»


1.静态代理

静态代理是指 代理类在程序运行前就已经定义好,其与目标类的关系在程序运行前就已经确立。
怎么区分静态代理和动态代理呢
如果有代理类 说明程序启动时就加载了 是静态代理
动态代理没有代理类 代理对象是通过工厂或者工具类生成的。

静态代理在使用时,需要定义接口或父类,被代理对象与代理对象一起实现接口或者继承相同父类。
举个栗子:

public interface ISomeService{
	String doFirst();
	void doSecond();
}  

//被代理类  
public class SomeServiceImpl implements ISomeService{
	public String doFirst(){
		System.out.println("执行了doFirst方法");
		String result = "azheng";
		System.out.println("result = " + result);
		return result;
	}

	public void doSecond(){
		System.out.println("执行doSecond方法");
	}
}

//代理类 
//这里实现将doFirst()返回的字符串转大写功能
public class SomeServiceProxy implements ISomeService(){
	public String doFirst(){
		ISomeService service = new SomeServiceImpl();
		String result = service.doFirst();
		return result.toUpperCase();
	}

	public void doSecond(){
		//这里不做功能扩展
	}
}

//测试代理类
public class MyTest(){
	public void main(String args[]){
		ISomeService service = new SomeServiceProxy();
		String result = service.doFirst();
		System.out.println("result = " + result);  
		service.doSecond();
	} 
}

输出结果:被代理类执行了doFirst方法
result = AZHENG
执行doSecond方法


2.动态代理

代理类在程序运行时创建的代理方式被成为 动态代理。
动态代理又分为两种方式,

  • 1.通过jdk的Proxy动态代理
    要求目标类与代理类必须实现相同接口,如目标类米有接口,则不能用这个方法。
    因为底层执行原理,与静态代理的相同
    api方法说明
    栗子来了:
//接口还是那个接口
public interface ISomeService {
	String doFirst();
	void doSecond();
}
//被代理类也还是那个被代理类
public class SomeServiceImpl implements ISomeService{
	public String doFirst(){
		System.out.println("执行了doFirst方法");
		String result = "azheng";
		System.out.println("result = " + result);
		return result;
	}

	public void doSecond(){
		System.out.println("执行doSecond方法");
	}
}
//不过这里就没有SomeServiceProxy()代理类了,直接实现了接口
//MyTest.java
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import com.azheng.service.ISomeService;
import com.azheng.service.SomeServiceImpl;

public class MyTest{
	public void main(String args[]){
		final ISomeService target = new SomeServiceImpl();
		ISomeService service = (ISomeService)Proxy.newProxyInstance(
			target.getClass().getClassLoader(), //目标类的类加载器
			target.getClass().getInterfaces(),  //目标类所实现的所有接口
			new InvocationHandler(){ //匿名内部类
			 	@Override
			 	public Object invoke(Object proxy, Method method, Object[] args)throws Throwable{
				//proxy 代理对象
				//method 目标方法
				//args 目标方法的参数列表
					Object result = method.invoke(target,args);	
					if(result != null){
						result = ((String)result).toUpperCase();
						return result;
					}
				return null;
				}
			});
		 String result = service.doFirst();
		System.out.println("result = " + result);
		service.doSecond();
	}
}

输出结果:被代理类执行了doFirst方法
result = AZHENG
执行doSecond方法

  • 2.cglib动态代理(Code Generation Library)
    这是对于米有接口的类,要使用cglib。
    cglib也可以实现代理有接口的目标类。
    cglib代理的生成原理是生成目标类的子类,而子类是增强过的,这个子类对象就是代理对象。
    但是也有条件,目标类必须是可继承的,不能是fianl的。
    在这里用的是这个jar包 : cglib-full.jar
//接口就米有了 
//目标类
public class SomeService{
	public String doFirst() {
		System.out.println("执行doFirst方法");
		return "azheng";
	}

	public void doSecond() {
		System.out.println("执行doSecond方法");
	}
}
//代理类
public class MyCglibFactory implements MethodInterceptor{
	private SomeService target;
	public MyCglidFactory{
		target = new SomeService();
	}
	public SomeService myCglibCreator(){
		//创建增强器对象
		Enhancer enhancer = new Enhancer();
		//制定目标类,即父类
		enhancer.setSuperClass(SomeService.class);
		//设置回调接口对象
		enhancer.setCallbabk(this);
		//返回的是子类,即代理对象
		return (SomeService)enhancer.create();
	}
	//回调方法
	@Override
	public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy)throws Throwable{
		Object result = method.invoke(target, args);
		if (result != null) {
			return result = ((String) result).toUpperCase();
		}
		return null;
	}
}

//MyTest
import com.azheng.factory.MyCglibFactory;
import com.azheng.service.SomeService;

public class MyTest {
	public static void main(String[] args) {
		SomeService service = new MyCglibFactory().myCglibCreator();
		String result = service.doFirst();
		System.out.println("result = " + result);
		service.doSecond();
	}
}

输出结果同上
在这里插入图片描述
瞅瞅为啥是回调方法
到这里就结束啦~
只有让自己变得更强 才会无所畏惧

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值