spring aop proxy 静态代理和动态代理

简介: spring aop proxy 静态代理和动态代理

代理的意义就在于,在访问真实的数据前我必须先访问它的代理,那么在客户端代码看来代理和实际的类应该没有分别—他们需要是同一类型。要做到是同一类型有两种方式,第一是代理类作为原类的子类,通过继承并重写父类的方法来达到目的;

最好的方式应该是实现同一接口,这就是接口的意义,接口的意义在于抽象,面向接口编程就是面向抽象编程。如果你的类有非static的public的方法,都应该考虑让他实现一个接口,很多时候我们会觉得给一个DAO或者service类多创建个interface是多余的,但是有朝一日你想到给他一个代理这样的需求的时候,你会发现如果他有个接口就完美了。

静态代理实现中,代理类与被代理类必须实现同一个接口。在代理类中可以实现记录等相关服务,并在需要时再呼唤被代理类,这样代理类就可以仅仅保留与业务相关的职责了。

例如:

接口

public interface Ihello {
        public void hello(String name);
    }
        被代理类
        public class HelloSpeaker implements Ihello{
         @Override
        public void hello(String name) {
            System.out.println("hello "+name);
        }
    }
        代理类
        public class HelloProxy implements Ihello{
        private Logger logger=Logger.getLogger(this.getClass().getName());
        private Ihello helloObject;
        public HelloProxy(Ihello helloObject){
                this.helloObject=helloObject;
        }
        @Override
        public void hello(String name) {
        log("hello method starts...");
        helloObject.hello(name);
        log("hello method ends");
        }
        private void log(String msg) {
        logger.log(Level.INFO, msg);
        }
    }
        测试类
        public class ProxyDemo {
     public static void main(String[] args) {
         //静态代理
        Ihello proxy=new HelloProxy(new HelloSpeaker());
        proxy.hello("Justin");
      }
输出:
2017-4-3 9:58:37 javaEE.spring.proxy.serviceImp.HelloProxy log
信息: hello method starts...
hello Justin
2017-4-3 9:58:37 javaEE.spring.proxy.serviceImp.HelloProxy log
信息: hello method ends
可以看到代理类的一个接口只能服务于一种类型的类,而且如果要代理的方法很多,势必要为每个方法进行代理 ,所以静态代理在程序规模稍大时必定无法胜任。
  而动态代理不需要为特定类和方法编写特定的代理类,运用jdk1.3以后的可协助开发动态代理功能的API相关类别,使得一个处理者handler可以为各个类服务。
      例如:
      接口
public interface Ihello {
                public void hello(String name);
        }
            被代理类
        public class HelloSpeaker implements Ihello{
         @Override
                public void hello(String name) {
                    System.out.println("hello "+name);
                }
        }
            处理类
            public class LogHandler implements InvocationHandler {
    private Object sub;
    public LogHandler(){
    }
    public LogHandler(Object obj){
        sub=obj;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        System.out.println("before you do thing");
        method.invoke(sub, args);
        System.out.println("after you do thing");
        return null;
    }
     }        
        测试  
        public class ProxyDemo {
     public static void main(String[] args) {    
         //动态代理
         HelloSpeaker helloSpeaker=new HelloSpeaker();
         LogHandler logHandler =new LogHandler(helloSpeaker);
         Class cls=helloSpeaker.getClass();
         Ihello ihello=(Ihello)Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), logHandler);
         ihello.hello("Justin");
    }
    }
相关文章
|
2月前
|
监控 Java 开发者
Spring AOP动态代理
Spring AOP动态代理
48 1
|
3月前
|
Java Spring
Spring5源码(38)-SpringAop代理调用过程(二)
Spring5源码(38)-SpringAop代理调用过程(二)
28 0
|
3月前
|
Java Spring
Spring5源码(37)-SpringAop代理调用过程(一)
Spring5源码(37)-SpringAop代理调用过程(一)
23 0
|
3月前
|
缓存 Java Spring
Spring5源码(35)-SpringAop创建代理(一)
Spring5源码(35)-SpringAop创建代理(一)
22 0
|
25天前
|
监控 Java 数据库连接
Spring高手之路17——动态代理的艺术与实践
本文深入分析了JDK和CGLIB两种动态代理技术在Spring框架中的应用。讨论了动态代理的基础概念,通过实例展示了如何实现和应用这两种方法,并比较了它们的性能差异及适用场景。进一步,探讨了在动态代理中实现熔断限流和日志监控的策略,以及如何利用动态代理优化Spring应用的设计和功能。
39 6
Spring高手之路17——动态代理的艺术与实践
|
26天前
|
Java 数据库 Spring
切面编程的艺术:Spring动态代理解析与实战
切面编程的艺术:Spring动态代理解析与实战
27 0
切面编程的艺术:Spring动态代理解析与实战
|
3月前
|
XML Java 数据格式
浅谈基于动态代理的Spring AOP原理
浅谈基于动态代理的Spring AOP原理
26 0
|
3月前
|
设计模式 安全 Java
深入理解Spring Boot AOP:CGLIB代理与JDK动态代理的完全指南
深入理解Spring Boot AOP:CGLIB代理与JDK动态代理的完全指南
368 1
|
3月前
|
Java
Spring5源码(36)-SpringAop创建代理(二)
Spring5源码(36)-SpringAop创建代理(二)
45 0
|
1月前
|
安全 Java Spring
Spring之Aop的底层原理
Spring之Aop的底层原理