• java静态代理,动态代理,cglib代理


    代理模式在我们的应用中是很常见的,例如拦截器,spring的事务管理等。之所以能被代理,是因为java允许我们通过反射机制动态构造目标对象,并调用相应的方法。

    就好像拿到了目标对象的引用,自然可以在目标对象方法执行前后处理一些自己的任务,例如日志服务拦截器,防止重复提交拦截器等。

    1.java的静态代理(纯粹是拿到目标的引用,调用目标方法)

     1 public interface Hello {
     2     public void say(String name);
     3 }
     4 public class HelloImpl implements Hello{
     5     @Override
     6     public void say(String name) {
     7         System.out.println("Hello!" + name);
     8     }
     9 }
    10 public class HelloProxy implements Hello{
    11     private Hello hello;
    12     public HelloProxy() {
    13         hello = new HelloImpl();
    14     }
    15     @Override
    16     public void say(String name) {
    17         before();
    18         hello.say(name);
    19         after();
    20     }
    21     private void before() {
    22         System.out.println("before......");
    23     }
    24     private void after() {
    25         System.out.println("after......");
    26     }
    27     public static void main(String[] args) {
    28         new HelloProxy().say("麦德漂");
    29     }
    30 }

    静态的代理,就是讲目标对象做了一层包装,然后调用目标对象的对应方法。

    2.java的动态代理(基于接口的代理)

     1 public class DynamicProxy implements InvocationHandler {
     2 
     3     private Object target;
     4 
     5     public DynamicProxy(Object target) {
     6         super();
     7         this.target = target;
     8     }
     9 
    10     @Override
    11     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    12         return method.invoke(target, args);
    13     }
    14 
    15     public static void main(String[] args) {
    16         Hello hello = (Hello) Proxy.newProxyInstance(Hello.class.getClassLoader(), new Class[]{Hello.class},new DynamicProxy(new HelloImpl()));
    17         hello.say("麦德漂");
    18     }
    19 }

    动态代理相对于静态代理已经方便了很多,不用再去写单独的代理类,只是基于接口才能生效。

    3.cglib代理(用过Hibernate的同学一定看到过cglib的身影)

     1 public class CGLibProxy implements MethodInterceptor{
     2     
     3     public Object getProxy(Object target) {
     4         return Enhancer.create(target.getClass(), this);
     5     }
     6 
     7     @Override
     8     public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
     9         return methodProxy.invokeSuper(obj, args);
    10     }
    11     
    12     public static void main(String[] args) {
    13         Hello hello = (Hello)new CGLibProxy().getProxy(new HelloImpl());
    14         hello.say("麦德漂");
    15     }
    16 
    17 }

    不再基于接口,强大的高性能生成代码工具。

  • 相关阅读:
    题解 P2296 【寻找道路】
    题解 CF534C 【Polycarpus' Dice】
    题解 CF294B 【Shaass and Bookshelf】
    题解 SP4354 【TWINSNOW Snowflakes】
    题解 UVA10294 【Arif in Dhaka (First Love Part 2)】
    FLV文件格式解析部分代码
    关于“无法定位程序输入点getaddrinfo于动态链接库WS32_32.dll上”的问题
    MinGW介绍与使用
    FFMPEG: 0.4.9
    可以处理UTF8编码的md5函数
  • 原文地址:https://www.cnblogs.com/render-inside/p/5852201.html
Copyright © 2020-2023  润新知