码迷,mamicode.com
首页 > 编程语言 > 详细

Spring 静态代理+JDK动态代理和CGLIB动态代理

时间:2018-11-23 14:27:11      阅读:246      评论:0      收藏:0      [点我收藏+]

标签:磁盘空间   内存   dos   代理   etc   vat   load   lang   odi   

代理分为两种:静态代理  动态代理

静态代理:本质上会在硬盘上创建一个真正的物理类

动态代理:本质上是在内存中构建出一个类。

如果多个类需要进行方法增强,静态代理则需要创建多个物理类,占用磁盘空间。而动态代理则是在内存中创建,不会对磁盘进行影响。

静态代理和JDK动态代理需要有接口。  CGLIB动态代理无需有接口的情况下进行代理。实质:内存中构建出了目标类型的子类。

JDK动态代理是JDK提供的,CGLIB动态代理是Spring提供的。

代理模式的三个组件:抽象主题  真实主题  代理主题

技术分享图片

静态代理:

   接口(抽象主题)的代码:

//抽象主题
public interface Subject {
    public void request();
}

  目标对象(真实主题)的代码:

//真实主题
public class RealSubject implements Subject{
    @Override
    public void request() {
        System.out.println("Subject     RealSubject");
    }
}

  代理对象(代理主题)的代码:

package cn.Spring.Day09Staticporxy;
//代理主题
public class ProxySubject implements Subject {
    //把真实主题当成代理主题的成员变量
    private RealSubject rs=new RealSubject();
    @Override
    public void request() {
        System.out.println("proxy");//在调用真实主题要增强的方法前进行增强
        rs.request();
        System.out.println("ProxySubject");//在调用真实主题要增强的方法后进行增强
    }
}

 

JDK动态代理:

  接口:

package cn.Spring.Day14JDKproxy;

public interface ISomeService {
    public void request();
}

  目标对象:

package cn.Spring.Day14JDKproxy;

public class SomeService implements ISomeService {
    @Override
    public void request() {
        System.out.println("977+7777");
    }
}

  代理对象:

package cn.Spring.Day14JDKproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class JdkProxy {
    public static void main(String[] args) {
        /*
        * 1.使用Proxy点出newProxyInstance方法     方法有三个参数
        *                                 ClassLoader loader,    类加载器类型的一个对象
        *                                 Class<?>[] interfaces,接口数组对象
        *                                 InvocationHandler h    InvocationHandler 对象
        * 2.实例化目标对象 目标对象去传入参数。
        * 3.invoke方法中使用method.invoke传入目标对象,和参数数组。
        * 
        * 
        * */
        final SomeService ss=new SomeService();
        ISomeService proxy = (ISomeService)Proxy.newProxyInstance(ss.getClass().getClassLoader(), ss.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("我是增强666666");
                method.invoke(ss,args);
                return null;
            }
        });
        proxy.request();
    }
}
newProxyInstance要传的参数

技术分享图片

invoke要传的参数

 

 技术分享图片

 

CGLIB动态代理:

目标对象:

 

package cn.Spring.Day10cglibProxy;

public class Service {
    public void doSome(){
        System.out.println("SSSSSService");
    }
}

 

代理对象:

package cn.Spring.Day10cglibProxy;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class ServiceTest {
    public static void main(final String[] args) {
        final Service service=new Service();
        Enhancer enhancer=new Enhancer();
        enhancer.setSuperclass(Service.class);
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                System.out.println("写入日志");
                Object invoke = methodProxy.invoke(service, args);
                return invoke;
            }
        });
        Service o = (Service)enhancer.create();
        o.doSome();

    }
}

 

Spring 静态代理+JDK动态代理和CGLIB动态代理

标签:磁盘空间   内存   dos   代理   etc   vat   load   lang   odi   

原文地址:https://www.cnblogs.com/java-263/p/10006809.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!