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

时间:2023-03-08 17:58:33
Spring 静态代理+JDK动态代理和CGLIB动态代理

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

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

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

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

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

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

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

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

静态代理:

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

//抽象主题
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要传的参数

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

invoke要传的参数

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

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(); }
}