静态代理

  • 代理模式大家应该都比较熟悉了,最起码都听过,当初学习SpringAop时,动态代理的源码把我整的是懵懵的
  • 说白了就是在不修改原有逻辑给这个方法前后加一些实现,比如常用的加日志,计算方法执行时间,做事务控制。。。
  • 缺点就是项目庞大后,代理类过于多,并且接口增加方法后,原方法和代理方法都要跟这改

    1. public interface Kernel {
    2. void shopping();
    3. }
    4. class Chaotic implements Kernel{
    5. @Override
    6. public void shopping() {
    7. System.out.println("这里是一团很乱的逻辑,不能再修改本方法了");
    8. }
    9. }
    10. class ChaoticProxy implements Kernel{
    11. public Chaotic chaotic;
    12. public ChaoticProxy(Chaotic teacherDao){
    13. this.chaotic = teacherDao;
    14. }
    15. @Override
    16. public void shopping() {
    17. System.out.println("很乱的逻辑执行前~~~");
    18. long start = System.currentTimeMillis();
    19. chaotic.shopping();
    20. long end = System.currentTimeMillis();
    21. double sj = (end-start)/1000;
    22. log.info("耗时:"+sj)
    23. System.out.println("这团乱糟糟的逻辑执行完了。。。耗时:"+sj);
    24. }
    25. }
    26. class Test{
    27. public static void main(String[] args) {
    28. Kernel iTeacherDao = new ChaoticProxy(new Chaotic());
    29. iTeacherDao.shopping();
    30. 很乱的逻辑执行前~~~
    31. 这里是一团很乱的逻辑,不能再修改本方法了
    32. 这团乱糟糟的逻辑执行完了。。。耗时:0.1
    33. }
    34. }

    动态代理

  • 静态代理的优点动态代理都有,Proxy会帮你创建代理对象

  • 相同接口业务的不需要创建很多代理类,比静态代理灵活
  • newProxyInstance这个方法参数含义:ClassLoader loader指定目标对象使用的类加载器,Class<?>[] interfaces获取传入对象实现的接口,InvocationHandler h 实现代理模式方法,可以实现InvocationHandler重写invoke方法,也可以在入参里重写invoke方法,如果实现InvocationHandler重写invoke,这里入参传this就可以了

    1. public static Object newProxyInstance(ClassLoader loader,
    2. Class<?>[] interfaces,
    3. InvocationHandler h)
    4. throws IllegalArgumentException
  • image.png

public interface Kernel {
    void shopping();
}
class Chaotic implements Kernel{
    @Override
    public void shopping() {
        System.out.println("这里是一团很乱的逻辑,不能再修改本方法了");
    }
}
class ChaoticProxy  {
    private Object object;
    public ChaoticProxy(Object o){
        this.object = o;
    }
    public Object getObject(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader()
                                      , object.getClass().getInterfaces()
                                      , new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("很乱的逻辑执行前~~~");
                long start = System.currentTimeMillis();
                Object invoke = method.invoke(object, args);
                long end = System.currentTimeMillis();
                double sj = (end-start)/1000;
                System.out.println("这团乱糟糟的逻辑执行完了。。。耗时:"+sj);
                return invoke;
            }
        });
    }

}
class Test1{
    public static void main(String[] args) {
        ChaoticProxy chaoticProxy = new ChaoticProxy(new Chaotic());
        Kernel object = (Kernel)chaoticProxy.getObject();
        object.shopping();
    }
}