本文面向初接触动态代理的学者,代码贴在最后
静态代理
其实现思路:
从前有A,B商家注册到了C平台上,A提供一些初级的服务,B对A的服务进行了一些封装从而能实现更厉害的服务。
(写到这里我突然发现和SpringCloud咋这么像。。。。。)
其映射在Java中就是:
C是一个接口,A,B都实现了该接口,B中持有A的引用,B调用方法都是通过A来实现,只不过在实现前后增加了一些操作。
(和装饰者模式咋这么像。。。。。)
其实虽然实现方式是差不多的,但是其终究目的却不同:装饰着模式是增强方法而静态代理是保护和隐藏被代理对象
动态代理
实现思路:
同样有C平台和A,B商家。同样是A提供一些初级的服务,B对A的服务进行了一些封装从而能实现更厉害的服务。差别就在B对A提供的散装服务不用一个一个处理了,而是一起处理
其体现在Java代码中是这样的:
对于B类,不用去实现C接口了,而是持有一个实现C接口的A类引用(在B中要用Object,不然要转换十分麻烦,但是在调用的时候却要传入一个A类的引用),自己实现InvocationHandler接口,其就是jdk为我们提供的动态生成代码的方式:
在以下代码中:C ==Dormitory,B == DormitoryProxy(静态),DynamicDormitory(动态),A==MyDormitory
package sjms.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* @Author Yan1less
* @Date 2019/5/1 15:22
* @Description TODO
**/
public class DynamicProxy implements InvocationHandler {
// 这个就是我们要代理的真实对象
private Object subject;
// 构造方法,给我们要代理的真实对象赋初值
public DynamicProxy(Object subject)
{
this.subject = subject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 在代理真实对象前我们可以添加一些自己的操作
System.out.println("使用方法之前");
System.out.println("Method:" + method);
// 当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handler对象的invoke方法来进行调用
Object invoke = method.invoke(subject, args);
// 在代理真实对象后我们也可以添加一些自己的操作
System.out.println("使用方法之后");
return invoke;
}
}
package sjms.proxy;
/**
* @Author Yan1less
* @Date 2019/5/1 14:53
* @Description 被代理类,静态代理其实和装饰这模式有点像,这其实可以类比成被装饰者
**/
public class MyDormitory implements Dormitory{
@Override
public void OneFloor() {
System.out.println("这里是一层");
}
@Override
public void TwoFloor() {
System.out.println("这里是二层");
}
@Override
public void ThreeFloor() {
System.out.println("这里是三层");
}
@Override
public int FourFloor() {
System.out.println("这里是四层");
return 8888;
}
}
package sjms.proxy;
/**
* @Author Yan1less
* @Date 2019/5/1 14:53
* @Description 可以类比成装置这模式中的装饰者,不过其较动态代理麻烦的地方在于:
* 1.方法都要重写一遍,有点麻烦
* 2.构造方法传参需要类型转化
* 最大的区别还是在与:装饰者模式主要目的是增强方法,静态代理目的是保护与隐藏被代理对象
**/
public class DormitoryProxy implements Dormitory{
private MyDormitory myDormitory;
public DormitoryProxy(Dormitory dormitory) {
if(dormitory.getClass() == MyDormitory.class){
myDormitory = (MyDormitory)dormitory;
}
}
@Override
public void OneFloor() {
System.out.println("抵达XX公寓");
myDormitory.OneFloor();
}
@Override
public void TwoFloor() {
System.out.println("抵达XX公寓");
myDormitory.TwoFloor();
}
@Override
public void ThreeFloor() {
System.out.println("抵达XX公寓");
myDormitory.ThreeFloor();
}
@Override
public int FourFloor() {
System.out.println("抵达XX公寓");
myDormitory.FourFloor();
return 8888;
}
}
package sjms.proxy;
/**
* @Author Yan1less
* @Date 2019/5/1 14:52
* @Description 这是一个接口,被代理类和代理类都要实现它
**/
public interface Dormitory {
void OneFloor();
void TwoFloor();
void ThreeFloor();
int FourFloor();
}
package sjms.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @Author Yan1less
* @Date 2019/5/1 14:50
* @Description TODO
**/
public class Main {
public static void main(String[] args) {
Dormitory dormitory = new MyDormitory();
Dormitory proxy = new DormitoryProxy(dormitory);
proxy.OneFloor();
System.out.println("--------------------------------");
DynamicProxy dynamicProxy = new DynamicProxy(dormitory);
Dormitory a = (Dormitory)Proxy.newProxyInstance(dynamicProxy.getClass().getClassLoader(),
dormitory.getClass().getInterfaces(),dynamicProxy
);
int i = a.FourFloor();
System.out.println(i);
}
}