动态代理.

动态代理是指代理类对象在程序运行时由 JVM 根据反射机制动态生成的。动态代理不需要定义代理类的.java 源文件。动态代理其实就是 jdk 运行期间,动态创建 class 字节码并加载到 JVM。动态代理的实现方式常用的有两种:使用 JDK 动态代理和 CGLIB 动态代理。

    1.  JDK动态代理

JDK动态代理是基于 Java 的反射机制实现的。使用 JDK中接口和类实现代理对象的动态创建。JDK的动态代理要求目标对象必须实现接口,而代理对象不必实现业务接口,这是 java 设计上的要求。从 jdk1.3 以来,java 语言通过 java.lang.reflect 包提供三个类和接口支持代理模式,它们分别Proxy, Method和 InvocationHandler。

      1. InvocationHandler接口

InvocationHandler 接口叫做调用处理器,负责完成调用目标方法,并增强功能。通过代理对象执行目标接口中的方法 , 会把方法的调用分派给调用处理器(InvocationHandler)的实现类,执行实现类中的 invoke()方法,我们需要把功能代理写在 invoke()方法中 。此接口中只有一个方法。

在 invoke 方法中可以截取对目标方法的调用。在这里进行功能增强。Java 的动态代理是建立在反射机制之上的。实现了 InvocationHandler 接口的类用于加强目标类的主业务逻辑。这个接口中有一个方法 invoke(),具体加强的代码逻辑就是定义在该方法中的。通过代理对象执行接口中的方法时,会自动调用 invoke()方法。

invoke()方法的介绍如下:

public Object invoke ( Object proxy, Method method, Object[] args)

proxy:代表生成的代理对象

method:代表目标方法

args:代表目标方法的参数

第一个参数 proxy 是 jdk 在运行时赋值的,在方法中直接使用,第二个参数后面介绍,

第三个参数是方法执行的参数, 这三个参数都是 jdk 运行时赋值的,无需程序员给出。

      1. Method

invoke()方法的第二个参数为 Method 类对象,该类有一个方法也叫 invoke(),可以调用目标方法。这两个 invoke()方法,虽然同名,但无关。

public Object invoke ( Object obj, Object... args)

obj:表示目标对象

args:表示目标方法参数,就是其上一层 invoke 方法的第三个参数

该方法的作用是:调用执行 obj 对象所属类的方法,这个方法由其调用者 Method 对象确定。在代码中,一般的写法为

method.invoke(target, args);

其中,method 为上一层 invoke 方法的第二个参数。这样,即可调用了目标类的目标方法。

      1. Proxy类

通过JDK的java.lang.reflect.Proxy类实现动态代理,会使用其静态方法newProxyInstance(),依据目标对象、业务接口及调用处理器三者,自动生成一个动态代理对象。

public static newProxyInstance ( ClassLoader loader, Class<?>[] interfaces,

InvocationHandler handler)

loader:目标类的类加载器,通过目标对象的反射可获取

interfaces:目标类实现的接口数组,通过目标对象的反射可获取

handler:调用处理器。

      1. 实现步骤
  1. 代理对象不需要实现接口
  2. 代理对象的生成是利用JDKAPI中的Proxy类, 动态的在内存中构建代理对象
  3. 代码实现结构

  1. ProxyFactory.java代理实例生成工厂

 

public class ProxyFactory {

//任何的代理对象,都要清楚目标对象,在此得设置一个目标对象,

private IService superStar;

//传入目标对象

public ProxyFactory(IService superStar){

this.superStar=superStar;

}

//给目标对象生成代理实例

public Object getProxyInstance(){

return Proxy.newProxyInstance(

//指定当前目标对象,使用类加载器获得

superStar.getClass().getClassLoader(),

//获得目标对象实现的所有接口

superStar.getClass().getInterfaces(),

//处理代理实例上的方法并返回调用结果

new InvocationHandler(){

@Override

public Object invoke(

//代理对象的实例

Object proxy,

//代理的目标对象的实现方法

Method method,

//代理的目标对象实现方法的参数

Object[] args) throws Throwable {

System.out.println("预定场地..........");

//目标对象执行自己的方法

Object returnValue=method.invoke(superStar, args);

System.out.println("结帐走人.........");

return returnValue;

} });}}
  1. 测试类
@Test

public void testDynamicProxy(){

//先创建目标对象

IService superStar=new SuperStar();

//创建代理对象

IService agent=(IService) new ProxyFactory(superStar).getProxyInstance();

agent.sing();

}

  注意:JDK动态代理中,代理对象不需要实现接口,但是目标对象一定要实现接口,否则不能用JDK动态代理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值