`

设计模式:代理模式(Proxy Pattern)

阅读更多


代理模式

代理模式为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个 客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间 起到中介的作用。

 

 

 

代理模式一般涉及到三个角色

1>抽象角色:声明真实对象和代理对象的共同接口;

2>代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象迚行封装。

3>真实角色:代理角色所代表的真实对象,是我们最终要引用的对象。

 

 

一、我们自己建一个简单的代理模式

1.新建一个抽象角色:Subject接口 

 

package com.kaishengit.proxy;

public interface Subject {
	public void sales();//销售
}

 

 2.新建一个真实角色:RealSubject(实现Subject接口)

 

package com.kaishengit.proxy;
//Dell
public class RealSubject implements Subject{

	@Override
	public void sales() {
		System.out.println("Dell销售电脑");
	}

}

 

 3.新建一个代理角色:SubjectProxy(实现Subject接口) 

 

package com.kaishengit.proxy;

//代理
public class SubjectProxy implements Subject{
	
	private Subject subject;
	
	/**
	 * 传进去要代理的对象
	 * @param subject
	 */
	public SubjectProxy(Subject subject){
		this.subject = subject;
	}
	@Override
	public void sales() {
		System.out.println("忽悠");//销售之前做点...
		subject.sales();
		System.out.println("送东西");//销售之后做点...
	}

}

 

 4.我们测试一下:

 

package com.kaishengit.proxy;

public class Test {
	public static void main(String[] args) {
		//被代理对象
		RealSubject rs = new RealSubject();
		
		//代理
		SubjectProxy sp = new SubjectProxy(rs);
		
		sp.sales();
	}
}

 

 运行结果:

--------------------------------------

 

忽悠

Dell销售电脑

送东西

 

--------------------------------------

 

ok......

 

 

二、Java动态代理

Java中动态代理一定要面向接口编程,也就是被代理对象必须实现接口,这是Java动态代理的缺陷。Java动态代理借助的是InvocationHandler接口。

Spring中的AOP使用到Java动态代理

 

1.由于被代理对象必须实现接口,我们先新建一个接口(Dao)

 

package com.kaishengit.proxy.java;

public interface Dao {
	public void save();
}

 接下来我们创建被代理对象(实现接口):UserDao

 

package com.kaishengit.proxy.java;

public class UserDao implements Dao{

	@Override
	public void save() {
		System.out.println("save success!");
	}

}
 

2.我们创建一个实现InvocationHandler接口的类:MyInvocationHandler

 

package com.kaishengit.proxy.java;

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

public class MyInvocationHandler implements InvocationHandler{
	
	private Object obj;
	
	//传进去被代理对象
	public MyInvocationHandler(Object obj){
		this.obj = obj;
	}
	
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		System.out.println("before");//之前做点什么
		Object result = method.invoke(obj, args);//执行被代理对象的方法
		System.out.println("after");//之后做点什么
		return result;
	}

}

 3.我们测试一下:

 

 

package com.kaishengit.proxy.java;

import java.lang.reflect.Proxy;

public class Test {
	public static void main(String[] args) {
		UserDao ud = new UserDao();//被代理对象
		
		MyInvocationHandler mih = new MyInvocationHandler(ud);//我们新建的实现InvocationHandler接口的类
		//创建代理proxyDao
		Dao proxyDao = (Dao) Proxy.newProxyInstance(ud.getClass().getClassLoader(), ud.getClass().getInterfaces(), mih);
		
		proxyDao.save();
	}
}

 运行结果:

------------------------------------------

 

before

save success!

after

------------------------------------------

 

三、使用CGLib进行动态代理

需要导入cglib的jar包,原理:如果被代理对象没有实现接口,动态产生一个子类来实现代理模式;否则采用Java动态代理模式。需要借助的是cglib包中的MethodInterceptor接口。

Spring中就导入了cglib的jar包,因为其中的AOP用到代理模式,以应对被代理对象没有实现接口

 

1.我们新建一个被代理对象:UserDao(呵呵,没有实现任何接口啊)

 

package com.kaishengit.proxy.cglib;

public class UserDao {
	public void save(){
		System.out.println("save success!");
	}
}

2.我们新建一个类实现 MethodInterceptor接口:DaoIntercept

 

 

package com.kaishengit.proxy.cglib;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class DaoIntercept implements MethodInterceptor{

	@Override
	public Object intercept(Object object, Method method, Object[] args,
			MethodProxy methodProxy) throws Throwable {
		System.out.println("before");//执行之前做点...
		//注意是methodProxy和invokeSuper
		Object result = methodProxy.invokeSuper(object, args);
		System.out.println("after");//执行之后做点...
		return result;
	}

}

 3,我们测试一下:

 

package com.kaishengit.proxy.cglib;

import net.sf.cglib.proxy.Enhancer;

public class Test {
	public static void main(String[] args) {
		UserDao dao = new UserDao();
		
		//Enhancer同样是cglib包中的
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(dao.getClass());
		enhancer.setCallback(new DaoIntercept());
		
		//创建代理对象
		UserDao proxyDao = (UserDao) enhancer.create();
		proxyDao.save();
	}
}

 运行结果:

----------------------------------------------------

 

before

save success!

after

----------------------------------------------------

 

----end----

 

2
0
分享到:
评论

相关推荐

    java 设计模式之代理模式(Proxy Pattern)实现代码及设计详解:动态代理模式、静态代理模式

    在这些模式中,代理模式(Proxy Pattern)是一种常用的结构型设计模式,它允许我们为一个对象创建一个代理,该代理对象在客户端和目标对象之间起到中介的作用,可以增加额外的功能或控制访问。 代理模式分为两种...

    设计模式:可复用面向对象软件的基础--详细书签版

     “[设计模式]在实用环境下特别有用,因为它分类描述了一组设计良好,表达清楚的面向对象软件设计模式。整个设计模式领域还很新,本书的四位作者也许已占据了这个领域造诣最深的专家中的半数,因而他们定义模式的方法...

    设计模式之代理模式proxy

    **设计模式之代理模式(Proxy Pattern)** 设计模式是软件工程中的一种最佳实践,它是在特定情境下解决常见问题的模板。代理模式是其中一种行为设计模式,它的核心思想是为一个对象提供一个替身或者代理,以控制对...

    Android设计模式之代理模式(Proxy Pattern)

    5. **异步操作**:代理模式可以用来包裹异步操作,比如在执行耗时任务前显示进度条,任务完成后关闭进度条。这样可以使得代码结构清晰,易于维护。 **总结** 代理模式在Android开发中扮演着重要角色,它提供了扩展...

    c++-设计模式之代理模式(Proxy)

    代理模式(Proxy Pattern)是一种结构型设计模式,用于为其他对象提供一种代理以控制对这个对象的访问。代理模式通常用于保护、延迟加载、记录请求等场景,可以在不改变原有对象的情况下为其增加新的功能。 代理...

    设计模式 之 “代理模式[Proxy Pattern]”

    **代理模式(Proxy Pattern)**是软件设计模式中的结构型模式之一,它在对象访问控制、增加额外功能或在客户端与目标对象之间提供一个中介等方面有广泛的应用。在代理模式中,代理类作为真实对象的代表,它持有真实...

    代理模式 Proxy Pattern

    ### 代理模式 Proxy Pattern #### 概念定义 代理模式是一种结构型设计模式,它允许程序员为某对象创建一个代理对象来控制对该对象的访问。简单来说,就是在不修改原始类的基础上,通过引入代理对象来扩展类的行为...

    C++设计模式基础教程.pdf

    6. 代理模式(Proxy Pattern):为其他对象提供一种代理以控制对这个对象的访问。 7. 装饰者模式(Decorator Pattern):动态的给一个对象添加一些额外的职责。 8. 适配器模式(Adapter Pattern):将一个类的接口...

    设计模式PPT

     代理模式(Proxy Pattern) 行为型模式用来对类或对象怎样交互和怎样分配职责进行描述,主要包含以下11种设计模式:  责任链模式(Chain of Responsibility Pattern)  命令模式(Command Pattern)  解释...

    设计模式代理模式PPT学习教案.pptx

    代理模式(Proxy Pattern)是一种结构型设计模式,它提供了一个代理对象以控制对另外一个对象的访问。代理对象充当着中间人的角色,帮助客户端访问目标对象,并可以在访问过程中添加一些额外的操作。 知识点2:代理...

    代理模式(Proxy Pattern)完整示例代码

    代理模式是一种设计模式,它允许我们为一个对象创建一个代理对象,这个代理对象可以在原对象进行某些操作之前或之后添加额外的功能。代理模式的核心在于,它提供了一种方式来间接访问或控制目标对象,增加了系统的...

    JavaScript设计模式.pdf

    8. 代理模式(Proxy Pattern): 代理模式是控制对象的访问,包括推迟对其创建需要耗用大量计算资源的类的实例化。它的主要作用是控制对象的访问,提高系统的安全性和可扩展性。 9. 观察者模式(Observer Pattern)...

    C++设计模式课件15_Proxy_代理模式.pdf

    代理模式(Proxy Pattern)是一种结构型设计模式,它在客户端与目标对象之间提供了一个代理对象。这个代理对象能够控制对目标对象的访问,并且可以添加额外的功能或操作。简而言之,代理模式的核心在于提供一个代理...

    Java设计模式之禅

    2. 代理模式(Proxy Pattern):为其他对象提供一种代理以控制对这个对象的访问,常用于延迟初始化或访问控制等场景。 3. 单例模式(Singleton Pattern):确保一个类只有一个实例,并提供一个全局访问点。 4. 多例...

    Python设计模式之代理模式实例详解

    代理模式(Proxy Pattern):为其他对象提供一种代理以控制对这个对象的访问 #!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'Andy' """ 大话设计模式 设计模式——代理模式 代理模式(Proxy Pattern):为...

    设计模式课程设计---使用5个以上不同的设计模式完成(java)

    4. **代理模式(Proxy Pattern)**:代理模式为其他对象提供一种代理以控制对这个对象的访问。在Java中,我们可以使用动态代理(`java.lang.reflect.Proxy`和`java.lang.reflect.InvocationHandler`)或者静态代理...

    GOF之23种设计模式的C#实现:DesignPattern.zip

    - 代理模式(Proxy):为其他对象提供一种代理以控制对这个对象的访问。 - 外观模式(Facade):为子系统提供一个统一的接口,使子系统更加易用。 - 适配器模式(Adapter):使两个不兼容的接口能够协同工作。 -...

    设计模式专题,代理模式,工厂模式

    **代理模式(Proxy Pattern)** 代理模式的核心思想是在原始对象和客户端之间插入一个代理对象,这个代理对象在客户端和原始对象之间起到中介作用,可以控制或扩展对原始对象的访问。在Java中,代理模式主要有静态...

    C#23种设计模式【完整】.pdf

    12. 代理模式(Proxy Pattern):为其他对象提供一个代理,以控制对这个对象的访问。 13. 模板方法模式(Template Method):定义一个操作中的算法骨架,而将一些步骤延迟到子类中,实现了基类的算法可复用。 行为...

Global site tag (gtag.js) - Google Analytics