关于java代理模式的疑问 真实对象什么时候被创建

来源:百度知道 编辑:UC知道 时间:2024/07/06 20:17:52
public interface Subject
{abstract public void request();}

public class RealSubject implements Subject
{ public void request()
{ 具体对象的方法的实现}
}

代理角色:
public class DynamicSubject implements InvocationHandler {

//InvocationHandler 的实现
代理类的内部属性为Object类,实际使用时通过该类的构造函数DynamicSubject(Object obj)对其赋值;此外,在该类还实现了invoke方法,该方法中的method.invoke(sub,args)其实就是调用被代理对象的将要被执行的方法,方法参数sub是实际的被代理对象,args为执行被代理对象相应操作所需的参数。通过动态代理类,我们可以在调用之前或之后执行一些相关操作。
}

}

客户端:
public class Client

{
static public void main(String[] args) throws Throwable
{
RealSubject rs = new RealSubject(); //在这里指定被代理类

InvocationHandler ds = new DynamicSubject(rs); //初始化代理类

Subject subject = (Subject) Proxy.newProxyInstance(cls.getClassLoader (),cls.getInterfaces(),ds );

subject.request();
}

疑问:
代理模式就是解决真实对象不能访问或不方便

首先声明一点:尽管原对象和代理对象是"同一个类型",但是被代理的和原对象不是完全一样的对象,就好比说,原来的大厦叫河蟹大厦,现在我给大厦安装了电梯,但是他还叫河蟹大厦,我们代理之后的对象就是安了电梯的河蟹大厦,电梯没有用么?当然有用了,但是我们安装电梯后要不要使用原来河蟹大厦的功能比如,电灯呢?当然也要了!这就是代理之后和被代理之前的关系,代理当然是有用的啦!

当然你可能会说了:为什么不在设计之初就按上电梯呢?这个。。。很多时候我们是故意为之,当太多类似的函数的里面都需要同一条语句,并且位置都大致相似的时候,我们需要在每个函数里面都添加上么?一次两次还好,多次了你可能就会烦了。一句两句好,如果一下都是10几句,每个函数都一样的,就太“八股文”了。

下面是一个例子吧,算伪代码,只是想让你看看怎么用,不一定能直接运行。

proxy.newProxyInstance()生成的代理对象,是在传入InvocationHandler的对象基础之上“织入”的即改进的,所以你传入的这个对象必须new出来,要不然怎么对其进行改进呢?而一般来说,我们使用的是代理之后的类,而非原始类,代理之后的类可以对原始传入类的一些函数进行拓展,这就是动态代理的用途。

再具个例子吧。。。

我们有很多类,它们都执行不同的SQL语句来连接数据库。如果我们在每个类里面都在查询代码之前先连接数据库,之后关闭数据库连接,那会导致很多的代码重复,这时候如果我们利用代理就是这么一个效果。

public class MyHandler implements InvocationHandler
{
......被代理对象target传入,省略
.....
Object invoke(Object proxy,
Method method,
Object[] args)
{
..做链接数据库
Object obj = proxy.invoke(target,args);
..做关闭数据库
return