设计模式-动态代理

概述:在不改变原有功能代码的前提下,能够动态的实现方法的增强

 

 

前期准备:

辅助jar包

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<!--<scope>test</scope>-->
</dependency>

业务类

import com.hdx.cglib.dto.Student;

public interface IStudentService {
    public void save(Student student);

    public Student query(Long id);

}
public class StudentServiceImpl implements IStudentService {
    public void save(Student student) {
        System.out.println("保存学生信息");
    }

    public Student query(Long id) {
        System.out.println("查询操作");
        Student student = new Student();
        student.setName("sy");
        student. setAge (18);
        return student;
    }
}
import lombok.Data;

@Data
public class Student {

    private String name;

    private int age;

}
 

 

一:jdk动态代理

 

 

 

 

 1.1实现InvocationHandler接

 InvocationHandler 接口,用来做方法拦截

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

public class DynamicHandler implements InvocationHandler {
@Override
public Object invoke(Object oProxy, Method method, Object[] objects) throws Throwable {

return null;
}
}

分别介绍里面的参数

oProxy:代理实例,可以通过newProxylnstance创建代理实例。

Method:执行目标方法的,invoke 方法执行

oargs:参数数组

 

1.2:动态代理类

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

/**
 *
 */
public class DynamicHandler implements InvocationHandler {
    //动态代理类需要被代理的实例
    private Object bean;
    
    public DynamicHandler(Object bean) {
        this.bean = bean;
    }

    @Override
    public Object invoke(Object oProxy, Method method, Object[] objects) throws Throwable {
        // 执行前置业务
        System.out.println("执行前置业务");

        //此处就是执行被代理类的方法
        Object invoke = method.invoke(bean, objects);

        // 执行后置业务
        System.out.println("执行后置业务");
        return invoke;
    }
}

 

1.3:测试

import com.hdx.cglib.dto.Student;
import com.hdx.cglib.service.IStudentService;
import com.hdx.cglib.service.StudentServiceImpl;
import org.junit.jupiter.api.Test;

import java.lang.reflect.Proxy;

class DynamicHandlerTest {

    @Test
    void invoke() {

        // 目标执行类
        IStudentService service = new StudentServiceImpl();

        // 方法拦截处理类
        DynamicHandler dynamicHandler = new DynamicHandler(service);

        // 获取代理实例对象
        IStudentService proxyBean = (IStudentService) Proxy.newProxyInstance(service.getClass().getClassLoader(), service.getClass().getInterfaces(), dynamicHandler);

        Student student = proxyBean.query(88l);

    }
}

分别介绍里面的参数

Proxy:代理实例,可以通过newProxylnstance创建代理实例

public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)

  ClassLoader类加载器,直接通过需要代理的类获取就行

  Class[]:目标类所实现的所有接口

  lnvocationHandler:方法拦截处理器,可以在里面实现方法的增强

Method:执行目标方法的,invoke 方法执行

args:参数数组

 

 

二:cglib代理

2.1:引入cglib依赖

<!-- https://mvnrepository.com/artifact/cglib/cglib -->
<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>2.2.2</version>
</dependency>

 2.2:代理了拦截类

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 *
 * cglib动态代理类
 */
public class CglibInterceptor implements MethodInterceptor {
    @Override
    public Object intercept(Object bean, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        // 执行前置增强业务
        System.out.println("befor");
        //执行代理的目标类方法
        Object result = methodProxy.invokeSuper(bean, objects);
        // 执行后置增强业务
        System.out.println("after");
        return result;
    }

}

2.3:代理测试类

import com.hdx.cglib.dto.Student;
import com.hdx.cglib.service.IStudentService;
import com.hdx.cglib.service.StudentServiceImpl;
import net.sf.cglib.core.DebuggingClassWriter;
import net.sf.cglib.proxy.Enhancer;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

class CglibInterceptorTest {

    @Test
    void intercept() {

        // 生成目标代理类
        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY,"D:\\workspace\\kafkaWork\\hkafka\\src\\main\\resources\\static");


        // 得到方法拦截器
        CglibInterceptor cglibInterceptor = new CglibInterceptor();
        //使用CGLIB框架生成目标类的子类(代理类)实现增强
        Enhancer enhancer = new Enhancer();
        // 设置父类字节码
        enhancer.setSuperclass(StudentServiceImpl.class);
        // 设置拦截处理器
        enhancer.setCallback(cglibInterceptor);



        IStudentService studentService = (IStudentService) enhancer.create();
        studentService.save(new Student());
    }
}

 

2.4:实现原理

。通过继承的方式去获取到目标对象的方法

。通过传递方法拦截器Methodlnterceptor实现方法拦截,在这里面做具体的增强

。调用生成的代理类对象具体执行重写的save方法,直接去调用方法拦截器里面的intercept 方法

。前后加上了增强操作,从而实现了不修改目标代码实现业务增强

 

三:区别

 

posted @ 2023-03-01 21:23  银河系的极光  阅读(14)  评论(0编辑  收藏  举报