您的位置:首页 > 编程语言 > Java开发

Spring 代理中的静态代理、动态代理

2017-08-30 19:50 387 查看
代理模式:

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

2、代理模式的组成:

抽象角色:通过接口或抽象类声明真实角色实现的业务方法。

代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。

真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。

3、代理模式的优点:

(1).职责清晰

真实的角色就是实现实际的业务逻辑,不用关心其他非本职的事务,通过后期的代理完成一件事务,附带的结果就是编程简洁清晰。

(2).代理对象可以在客户端和目标对象之间起到中介的作用,这样起到了中介的作用和保护了目标对象的作用。

(3).高扩展性

4、代理模式分为静态代理、动态代理。

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

动态代理是在实现阶段不用关心代理类,而在运行阶段才指定哪一个对象。

5、代理模式结构图



实现静态代理的步骤:
1).定义一个抽象的主题接口。

public interface IGetSomething {
void getsomething();
}

2).定义一个真实主题的类,实现抽象主题接口。
public class RealGetSomething implements IGetSomething {
@Override
public void getsomething() {
System.out.println("主人亲自收货并签字了");
}
}
3).定义一个代理主题的类,实现抽象主题接口,但是这个类关联了所代理的主题对象。
public class ProxyGetSomething implements IGetSomething {

private RealGetSomething realGetSomething;//依赖关系
public RealGetSomething getRealGetSomething() {
return realGetSomething;
}
public void setRealGetSomething(RealGetSomething realGetSomething) {
this.realGetSomething = realGetSomething;
}
public ProxyGetSomething(RealGetSomething _realGetSomething){
this.realGetSomething=_realGetSomething;
}
@Override
public void getsomething() {
getbefore();
realGetSomething.getsomething();
getafter();
}
private void getbefore(){
System.out.println("检查快递是否是本小区的");
}
private void getafter(){
System.out.println("快递签收完毕");
}

}
4).编写客户端调用的类(对外部开放)
public class ClientDemo {
private IGetSomething igetsomething;

public IGetSomething getIgetsomething() {
return igetsomething;
}

public void setIgetsomething(IGetSomething igetsomething) {
this.igetsomething = igetsomething;
}
public ClientDemo(IGetSomething _igetsomething){
this.igetsomething=_igetsomething;
}
public void show(){
igetsomething.getsomething();
}
}
5).测试类
public class ProxyStaticTest {
@Test
public void testit(){
RealGetSomething realGetSomething = new RealGetSomething();
IGetSomething igetsomething = new ProxyGetSomething(realGetSomething);
ClientDemo client = new ClientDemo(igetsomething);
client.show();
}
}

结果:



实现动态代理的步骤:
1).定义一个抽象的主题接口。

public interface IData {
public void opdata();
}

2).定义二个真实主题的类,一个查询和删除。实现抽象主题接口。

public class DeleteData implements IData{
@Override
public void opdata() {
System.out.println("这是对于数据库的删除方法");
}
}
public class SelectData implements IData {
@Override
public void opdata() {
System.out.println("这是对于数据库的查询方法");
}
}
3).定义一个动态代理的平台.

public class DataHandler implements InvocationHandler {
private Object obj;

// 添加Set方法
public void setObj(Object obj) {
this.obj = obj;
}

public DataHandler(Object _obj) {
super();
this.obj = _obj;
}

public void getconnection() {
System.out.println("这是动态代理提供的动态代理平台对象的方法的执行开始");
}

public void closeconnection() {
System.out.println("这是动态代理提供的动态代理平台对象的方法的执行完毕");
}

@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// 调用代理对象的方法执行
getconnection();
Object ret = method.invoke(obj, args);
closeconnection();
return ret;
}
} 4).测试类
public class DataTest {
@Test
public void testit() {
// 生成一个动态代理对象,只能针对接口的实现
IData delet = new DeleteData();
// 生成一个动态代理平台
DataHandler dataHandler = new DataHandler(delet);
// 根据动态代理平台实现动态代理对象的生成
IData delete = (IData) Proxy.newProxyInstance(delet.getClass()
.getClassLoader(), delet.getClass().getInterfaces(),
dataHandler);
// 生成一个动态代理对象,只能针对接口的实现
IData selec = new SelectData();
// 生成一个动态代理平台
DataHandler dataHandler2 = new DataHandler(selec);
// 根据动态代理平台实现动态代理对象的生成
IData select = (IData) Proxy.newProxyInstance(selec.getClass()
.getClassLoader(), selec.getClass().getInterfaces(),
dataHandler2);
delete.opdata();
System.out.println("");
select.opdata();
}
}
结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息