动态代理概念:
动态代理对象在程序运行中才进行构建,相比静态代理,程序运行前就构建代理对象
优点:可以灵活切换业务功能
静态和动态代理:都可以灵活切换目标对象,但是静态代理不可以切换业务功能,动态代理是通过反射机制可以获取调用的目标方法,然后再进行调用。
如上图所示:
业务接口:编写具体的业务功能
业务实现类:具体实现业务接口的业务功能
**代理工厂(上图的动态代理B 图写的有些不清楚):获取动态代理对象
测试:负责动态代理测试
代理工厂中主要用到的知识点(用实例代码分析):
public class ProxyFactory {
//设置成员变量,就是目标对象的接口
Service target;
//使用构造方法把目标对象传递过来
//这里用到了多态父类引用指向子类对象 target指向传递过来的具体实现service接口的实现类 可能是liu也可能是zhou
public ProxyFactory(Service target) {
this.target = target;
}
//得到代理对象
public Object getArgeen() {
return Proxy.newProxyInstance(
//ClassLoader loader,类加载器
target.getClass().getClassLoader(),
//Class<?>[] interfaces,//目标对象实现的接口
target.getClass().getInterfaces(),
//InvocationHandler h)//代理功能和业务功能)
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//代理功能
System.out.println("演出费用.......");
//代理功能
System.out.println("演出场地.......");
//业务功能
Object obj = method.invoke(target, args);//method.invoke(target, args);利用反射来调用当前正在调用的目标对象的方法 也正是它实现了业务功能的切换。
//代理功能
System.out.println("演出费用........");
return obj;
}
}
);
}
}
测试动态代理:
public void test01(){
//创建代理对象工厂对象
ProxyFactory proxyFactory = new ProxyFactory(new ServiceLiuImpl());
//通过getArgeen方法拿到代理对象
// 这里有点不明白就是为啥可以强制转换成service所以我输出了强制转换和不强制转换的class类型
// 结果都是class com.sun.proxy.$Proxy2 jdk代理对象
// 归根结底就是getArgent方法用到的Proxy.newProxyInstance方法就是返回代理对象的
// 强制转换成为业务接口对象 就是为了好调用业务接口里面的方法
Object argeen1 = proxyFactory.getArgeen();
System.out.println(argeen1.getClass());
Service argeen = (Service) proxyFactory.getArgeen();
System.out.println(argeen.getClass());
//强制转换为业务接口类型来调用业务方法
argeen.sing();//无参无返的
double show = argeen.show("你好!");//有参有返的
System.out.println(show);
}