一天一个Java知识点----代理

代理

  • 代理就是可以对象的某些方法进行增强,好处是解耦,而且一般是和本逻辑不太相关的增强,种类上分为静态代理动态代理,在面向对象编程设计模式中,也有代理设计模式

科普:什么是目标对象、目标类、代理对象和代理类?

  • 目标对象:需要被增强的对象
  • 目标类:需要被增强的对象所在的类
  • 代理对象:增强之后的对象,分为静态和动态代理对象
  • 代理类:增强之后的对象所在的类,分为静态和动态代理类

静态代理

两种方式:

  • 继承父类:通过直接在工程中创建子类继承目标类作为父类,这个子类可以称为静态代理类,然后在子类中重写父类方法进行增强,同时子类会持有对目标对象的引用,通过静态代理类创建处理的对象称为静态代理对象
  • 实现接口:目标类如果有实现接口的情况下,而且需要被增强的方法就是接口定义的方法,这种情况下,可以新建一个实现类来实现和目标类相同的接口,然后同时新的实现类内部持有目标对象的引用

缺点:针对每一个需要被增强的目标类都需要自己在项目中手写一个子类或者实现类进行增强,如果有很多个目标类都需要增强同一个逻辑,会非常麻烦。

被加强类和接口:

Java
Star
public class Star implements StartInterface{

    @Override
    public void sing() {
        System.out.println("+++++唱歌+++++");
    }

}

Java
StartInterface
public interface StartInterface {
    void sing();
}

继承父类

Java
InheritedProxy
public class InheritedProxy extends Star{
    private Star star;

    public InheritedProxy(Star star) {
        this.star = star;
    }

    @Override
    public void sing() {
        System.out.println("++++++继承增强++++++");
        star.sing();
    }
}

Java
InheritedProxyTest
public class InheritedProxyTest {
    public static void main(String[] args) {
        Star star = new Star();
        InheritedProxy starProxy = new InheritedProxy(star);
        starProxy.sing();
    }
}

实现接口

Java
ImplementProxy
 public class ImplementProxy implements StartInterface{
    private StartInterface star;
    public ImplementProxy(StartInterface star) {
        this.star = star;
    }
    @Override
    public void sing() {
        System.out.println("++++++实现增强++++++");
        star.sing();
    }
}

Java
ImplementProxyTest
public class ImplementProxyTest{
    public static void main(String[] args) {
        Star star = new Star();
        ImplementProxy starProxy = new ImplementProxy(star);
        starProxy.sing();
    }
}

动态代理

动态代理技术其实也有好几种,比较常用有jdk动态代理(基于实现接口,目标类要有实现接口才可以使用),还有cglib(基于继承父类,底层基于asm字节码技术实现,只要是一个类都可以使用),今天主要给大家介绍jdk动态代理。

  • java.lang.reflect.Proxy类:提供了为对象产生代理对象的方法:

一天一个Java知识点----代理_第1张图片

Java
StartInvocationHandler
public class StartInvocationHandler implements InvocationHandler {
    private StartInterface target;
    public StartInvocationHandler(StartInterface target) {
        this.target = target;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Before method:"+method.getName());
        Object result = method.invoke(target,args);//调用原始方法
        System.out.println("After method:"+method.getName());
        return result;
    }
}

StartInvocationHandlerTest
public class StartInvocationHandlerTest {
    public static void main(String[] args) {
        Star star = new Star();
        StartInterface startProxy = (StartInterface) Proxy.newProxyInstance(star.getClass().getClassLoader(),star.getClass().getInterfaces(),new StartInvocationHandler(star));
        startProxy.sing();
    }
}

静态代理和动态代理的区别

静态代理是在编译阶段已经生成了代理类了,动态代理是在程序运行过程中才会生成代理类,项目中更多推荐是使用动态代理

你可能感兴趣的:(开发语言,java)