java基础与基础加强 动态代理/代理模式

来源:互联网 发布:如何处理sql注入 编辑:程序博客网 时间:2024/06/06 20:36
代理模式一般涉及到的角色有
– 抽象角色:声明真实对象和代理对象的共同接口
– 代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装

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


Subject.java ( 抽象角色)   ,RealSubject.java (真实角色)   ,ProxySubject.java (代理角色)     ,   Client.java (测试类)


①.


//抽象角色,一个接口提供一个方法.交给子类去实现。

package com.itheima.study.proxy;


public interface Subject
{
public void print();
}


②.



package com.itheima.study.proxy;


//真实角色
public class RealSubject implements Subject
{


//真实对象复写抽象角色的方法
@Override
public void print()
{
System.out.println("this is RealSubject");
}


}


③.


package com.itheima.study.proxy;

//代理角色,提供一个对真实对象的引用,也实现抽象角色,但是可以添加功能。
public class ProxySubject implements Subject
{
//代理角色内部引用了真实角色
private RealSubject realSubject;




@Override
public void print()
{
//在真实角色操作之前所附加的操作
this.printA();

if(realSubject == null)
{
realSubject = new RealSubject();
}

//真实角色所完成的事情
realSubject.print();

//在真实角色操作之后所附加的操作
this.printB();
}

private void printA()
{
System.out.println("A");
}

private void printB()
{
System.out.println("B");
}


}


④.


测试类:


package com.itheima.study.proxy;


public class Client
{
public static void main(String[] args)
{
Subject proxy = new ProxySubject();
proxy.print();
}
}


运行结果:

A
this is RealSubject
B


现在我们来实现动态代理

动态代理主要涉及到两个类:Proxy(提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类), 和InvocationHandler(是代理实例的调用处理程序 实现的接口); 解释能力有限,还是用实例来说明,较为直接。

创建步骤:

1.创建一个实现接口InvocationHandler的类,它必须实现invoke方法
2.创建被代理的类以及接口
3.通过Proxy的静态方法newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h) 创建一个代理
4.通过代理调用方法


①.

//抽象角色

//提供四个方法,实现对两个数的加减乘除。

package com.itheima.study.proxy;


public interface Subject1
{
public void add();
public void reduce();
public void multiply();
public void divide();
}



②.

//具体角色

//该类构造方法接收连个参数

//四个方法分别实现两个整型的加减乘除

package com.itheima.study.proxy;


public class RealSubject1 implements Subject1
{


private int a;
private int b;

public RealSubject1(int a, int b)
{
this.a = a;
this.b = b;
}
@Override
public void add()
{
System.out.println(a + b);
}


@Override
public void reduce()
{


System.out.println(a - b);
}


@Override
public void multiply()
{


System.out.println(a * b);
}


@Override
public void divide()
{


System.out.println(a / b);
}


}



③.

//处理器角色

//实现了InvocationHandler(调用处理器的类)当执行动态代理的时候就会转移该该盗用处理器类的invoke方法来。


package com.itheima.study.proxy;


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


public class DynamicSubject implements InvocationHandler
{

//定义一个类的应用通过构造方法初始化
private Object obj;

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


//重写invoke方法
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable
{

//调用obj的方法之前执行的代码
System.out.println("before:" + method);

method.invoke(obj, args);
//调用obj方法之后执行的代码
System.out.println("after:" + method);


return null;

}


}


④.


//测试类

package com.itheima.study.proxy;


import java.lang.reflect.Proxy;



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

//创建真实对象实例
Subject1 subject = new RealSubject1(8, 4);


//创建代理对象,已知代理对象是一个Subject1的实现类,所以强制类型转换成Subject1
Subject1 subject1 = (Subject1) Proxy.newProxyInstance(subject.getClass().getClassLoader(), subject.getClass().getInterfaces(), new DynamicSubject(subject));


//执行这几个方法。
subject1.add();
System.out.println();
subject1.reduce();
System.out.println();
subject1.multiply();
System.out.println();
subject1.divide();
}
}


运行结果:

before:public abstract void com.itheima.study.proxy.Subject1.add()
12
after:public abstract void com.itheima.study.proxy.Subject1.add()


before:public abstract void com.itheima.study.proxy.Subject1.reduce()
4
after:public abstract void com.itheima.study.proxy.Subject1.reduce()


before:public abstract void com.itheima.study.proxy.Subject1.multiply()
32
after:public abstract void com.itheima.study.proxy.Subject1.multiply()


before:public abstract void com.itheima.study.proxy.Subject1.divide()
2
after:public abstract void com.itheima.study.proxy.Subject1.divide()


如此我们发现:通过这种方式,被代理的对象(RealSubject)可以在运行时动态改变,需要控制的接口(Subject接口)可以在运行时改变,控制的方式(DynamicSubject类)也可以动态改变,从而实现了非常灵活的动态代理关系



原创粉丝点击