java动态代理day-02
动态代理
动态代理的分类
-
jdk动态代理
使用java发射包中的类和接口实现动态代理的功能
反射包java.lang.reflect中的三个类:InvocationHandler、Method、Proxy
目标类必须实现接口,否则只能使用cglib动态代理
-
cglib动态代理
cglib是第三方的工具库,创建代理对象
cglib的原理是继承, cglib通过继承目标类,创建它的子类,在子类中重写父类中同名的方法, 实现功能的修改。
因为是继承重写方法,所以要求目标类不能是final,方法也不能是final的,chlib要求目标类比较宽松,很多框架都在使用,效率高于jdk
jdk的动态代理机制
-
InvocationHandler:
接口,就一个方法invoke()
表示代理对象要执行的功能代码,你的代理类要完成的功能
- 调用目标方法,执行目标方法的功能
- 功能增强,在目标方法调用时增强功能
-
Method:
一个类,表示方法,是目标类中的方法,通过method可以执行某个目标类中方法
-
Proxy:
核心对象,创建代理对象,之前创建对象都是用new,现在使用proxy类的方法代替new的使用
方法:静态方法newProxyInstance()
作用是创建diali代理对象
动态代理的步骤
- 创建接口,定义目标类完成的功能
- 创建目标类实现接口
- 创建InvocationHandler接口的实现类在incoke方法中完成代理类的功能
- 使用proxy类的静态方法,创建代理对象,并把返回值转为接口类型
代码实例
package com.henry.service;
public interface UsbSell {
float sell(int amount);
}
package com.henry.factory;
import com.henry.service.UsbSell;
//目标类
public class UsbKingFac implements UsbSell {
@Override
public float sell(int amount) {
System.out.println("执行目标类方法");
return 85.0f;
}
}
package com.henry.handler;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
//完成代理类的功能(调用目标方法,功能增强)
public class MySellHandler implements InvocationHandler {
private Object target = null;
public MySellHandler(Object target){
this.target = target;
}
/**
*
* @param proxy 代理对象
* @param method 目标类方法
* @param args 参数
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object res = null;
/**
* target:目标类
* args:参数
*/
res = method.invoke(target,args);
if(res!=null){
Float price = (Float)res;
price +=25;
res = price;
}
return res;
}
}
package com.henry;
import com.henry.factory.UsbKingFac;
import com.henry.handler.MySellHandler;
import com.henry.service.UsbSell;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class MyShop {
public static void main(String[] args) {
//创建代理对象
//1.创建目标对象
UsbSell fac = new UsbKingFac();
//2.创建InvocationHandler对象
InvocationHandler handler = new MySellHandler(fac);
//3.创建代理对象
UsbSell proxy = (UsbSell) Proxy.newProxyInstance(fac.getClass().getClassLoader(),
fac.getClass().getInterfaces(),
handler);
//4.通过代理执行方法
float pri = proxy.sell(1);
System.out.println("通过动态代理调用方法"+pri);
}
}