目录
JDK面向接口编程
动态代理的概念
JDK动态代理
JDK动态代理用到的类和接口
1)Proxy类
2)Method类
3)InvocationHandler接口
CGLib动态代理
JDK面向接口编程
类中的成员变量设计为接口,方法的形参设计为接口,方法的返回值设计为接口,调用时接口指向实现类。
个人理解为一个插板,插板在现实生活中有两种一种是三头、一种是双头,打比方有三头插口,冰箱是三头插头,电脑的插头也是三头,这两个都可使用。冰箱和电脑都可以插在这个三孔插板上,冰箱、电脑都是电器(目标对象)我们的插板只有一个三孔插口,
this.是调用类中成员变量(第一个target,后面的this.target是指调用前面的那个target)agent是代理的功能
接口指向实现类,实现类是什么,用到的就是什么,那个目标对象来,就是那个目标对象使用。
这就是用接口与实现灵活的切换
父类的引用指向子类实现的时候,最终得到的结果应该是子类。也就是说子类重写了父类的方法后,看到的也只能是重写后的方法。(多态)
接口其实就是另外一种意义的父类,所以调用后都是重写后的内容。
动态代理的概念
业务功能需要灵活切换,所以需要动态代理。
动态代理的代理对象在程序运行的过程中动态在内存构建,可以灵活的进行业务功能切换。
JDK动态代理
1)目标对象必须实现业务接口
2)JDK代理对象不需要实现业务接口
3)JDK动态代理的对象在程序运行前不存在.在程序运行时动态的在内存中构建
4)JDK动态代理灵活的进行业务功能的切换
5)本类中的方法(非接口中的方法)不能被代理
JDK动态代理用到的类和接口
它是使用现在的工具类完成JDK动态实现
1)Proxy类
它是java.lang.reflect.Proxy包下的类. 它有一个方法Proxy.newProxyInstance(.....)专门用来生成动态代理对象。
public static Object newProxyInstance(ClassLoader loader, //类加载器
Class>[] interfaces,//目标对象实现的所有接口
InvocationHandler h //它就类似于Agent的功能,代理的功能和目标对象的业务功能调用在这
)
throws IllegalArgumentException
{...}
>泛型,表示任意的类型(一个类可以实现多个接口)
2)Method类
反射用的类,用来进行目标对象的方法的反射调用。
method对象接住我们正在调用的方法sing(),show()
method==sing(),show() 就是方法的传参
method.invoke();==>手工调用目标方法 sing(); show();
3)InvocationHandler接口
new接口的同时实现内部功能,所以从new后面开始就是匿名内部类的实现。
它是实现代理和业务功能的.我们在调用时使用匿名内部实现。(下面代码实现使用两个类一个接口)
public class ProxyFactory {
//类中的成员变量设计为接口,目标对象
Service target;
//传入目标对象
public ProxyFactory(Service target){
this.target = target;
}
//返回动态代理对象
public Object getAgent(){
return Proxy.newProxyInstance(
//ClassLoader loader, 类加载器,完成目标对象的加载
target.getClass().getClassLoader(),
//Class>[] interfaces,目标对象实现的所有接口
target.getClass().getInterfaces(),
//InvocationHandler h,实现代理功能的接口 ,我们传入的是匿名内部实现
new InvocationHandler() {
@Override
public Object invoke(
//创建代理对象
Object proxy,
//method就是目标方法sing(),show()
Method method,
//目标方法的参数
Object[] args) throws Throwable {
//代理功能
System.out.println("预订时间........");
//代理功能
System.out.println("预订场地........");
//主业务功能实现
//target.sing();还是写死了方法的调用, 不成
//sing(),show(),one()
Object obj = method.invoke(target,args);
//代理功能
System.out.println("结算费用........");
return obj; //切记:这个是目标方法的返回值
}
}
);
}
}
调用当前方法的意思
JDK动态代理(需要回顾反射的知识点!)
CGLib动态代理
又称为子类.通过动态的在内存中构建子类对象,重写父类的方法进行代理功能的增强。 如果目标对象没有实现接口,则只能通过CGLib子类代理来进行功能增强。子类代理是对象字节码框架ASM来实现的。
注意:
被代理的类不能为final, 否则报错.
目标对象的方法如果为final/static, 那么就不会被拦截,即不会执行目标对象额外的业务方法。final变量变常量,直接就死了!
public Object getProxyInstance(){
//1.使用工具类
Enhancer en=new Enhancer();
//2.设置父类
en.setSuperclass(target.getClass());
//3.设置回调函数
en.setCallback(this);
//4.创建子类(代理)对象
return en.create(); ===>返回的是子类代理对象
暑期编程PK赛 得CSDN机械键盘等精美礼品!



