当前位置: 代码迷 >> 综合 >> Spring动态代理(JDK+CGLIB)
  详细解决方案

Spring动态代理(JDK+CGLIB)

热度:30   发布时间:2024-03-05 21:00:58.0

前言

强烈推荐 B站 宝藏男孩 遇见狂神说

JDK动态代理(基于接口)

  • 学习之前,主要了解**代理模式**

  • 用一个简单的例子来了解:

1、创建UserDao接口


public interface UserDao {
    void save();void delete();
}

2、实现接口


public class UserDaoImpl implements UserDao {
    public void save() {
    System.out.println("保存");}public void delete() {
    System.out.println("删除");}
}

3、方面,公共的组件


public class MyAspect {
    public void before(){
    System.out.println("before方法");}public void after(){
    System.out.println("after方法");}}

4.代理类

  • InvocationHandler 接口
  • 是proxy代理实例的调用处理程序实现的一个接口,需要实现

  • proxy是代理对象,method目标对象方法,args目标对象方法的参数
  • .Proxy类就是用来创建一个代理对象的类

public Object invoke(Object proxy, Method method, Object[] args)


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;public class MyProxy implements InvocationHandler {
    private UserDao userDao;private MyAspect myAspect;public MyProxy(UserDao userDao, MyAspect myAspect) {
    this.userDao = userDao;this.myAspect = myAspect;}//创建代理对象public Object getProxy(){
    return Proxy.newProxyInstance(this.getClass().getClassLoader(),userDao.getClass().getInterfaces(),this);}public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    myAspect.before();method.invoke(userDao,args);System.out.println("方法名:"+method.getName());myAspect.after();return null;}
}

5、测试

public class Test {
    public static void main(String[] args) {
    // 被代理类,真实类UserDao userDao = new UserDaoImpl();// 方面,抽出的公共方法MyAspect aspect = new MyAspect();// 代理类MyProxy proxy = new MyProxy(userDao,aspect);UserDao user = (UserDao) proxy.getProxy();user.save();

CGLIB动态代理(基于类)

  • MethodInterceptor

实现MethodInterceptor 接口,在调用目标对象的方法时,
就可以实现在调用方法之前、调用方法过程中、调用方法之后对其进行控制。

  • Enhancer

Enhancer允许为非接口类型创建一个Java代理。Enhancer动态创建了给定类型的子类但是拦截了所有的方法。和Proxy不一样的是,不管是接口还是类他都能正常工作。

代理类

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;import java.lang.reflect.Method;/* * 实现MethodInterceptor 接口,在调用目标对象的方法时, * 就可以实现在调用方法之前、调用方法过程中、调用方法之后对其进行控制。 * */
public class MyProxy<T> implements MethodInterceptor {
    private T byProxy;private MyAspect myAspect;public MyProxy(T byProxy, MyAspect myAspect) {
    this.byProxy = byProxy;this.myAspect = myAspect;}public T getProxy(){
    // Enhancer可以用来为无接口的类创建代理。
// 它的功能与java自带的Proxy类挺相似的// 通过Enhancer创建代理类Enhancer enhancer = new Enhancer();// 设置需要代理的类enhancer.setSuperclass(UserDaoImpl.class);enhancer.setCallback(this);T obj = (T)enhancer.create();return obj;}/** Method method 调用的被代理对象的方法** */public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
    myAspect.before();method.invoke(byProxy,objects);myAspect.after();return null;}
}

测试

public class Test {
    public static void main(String[] args) {
    // 被代理对象UserDaoImpl userDao = new UserDaoImpl();// 方面MyAspect myAspect = new MyAspect();// 代理类MyProxy<UserDaoImpl> myProxy = new MyProxy<UserDaoImpl>(userDao,myAspect);UserDaoImpl userDao1 =  myProxy.getProxy();userDao1.save();userDao1.delete();}
}

总结
1、两者实现动态代理,主要是在代理类的实现接口不同,创建代理类的类不同

jdk实现InvocationHandler接口,Proxy创建代理类

cglib实现MethodInterceptor接口,Enhancer 创建代理类

共同成长,共同进步~

  相关解决方案