猿创征文|Cglib代理之代理类方法的动态传递

导读:本篇文章讲解 猿创征文|Cglib代理之代理类方法的动态传递,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

💪Cglib代理之代理类方法的动态传递 有什么不对的地方还请大佬们多多指正


前言

通过传递的方式,动态传递给代理类,代理类接收到后将会执行当前方法 如方法执行前… 方法执行后…


提示:以下是本篇文章正文内容,下面案例可供参考

🍓Cglib代理是什么?

1)静态代理和JDK代理模式都要求目标对象是实现一个接口,但是有时候目标对象只是一个单独的对象,并没有实现任何的接口,这个时候可使用目标对象子类来实现代理-这就是Cglib代理
2)Cglib代理也叫作子类代理,它是在内存中构建一个子类对象从而实现对目标对象功能扩展,有些书也将Cglib代理归属到动态代理。
3)Cglib是一个强大的高性能的代码生成包,它可以在运行期扩展iava类与实现iava接口.它广泛的被许多AOP的框架使用,例如Spring AOP,实现方法拦截
4)在AOP编程中如何选择代理模式:
4.1目标对象需要实现接口,用JDK代理
4.2目标对象不需要实现接口,用Cglib代理
5)Cglib包的底层是通过使用字节码处理框架ASM来转换字节码并生成新的类

🍓实现步骤

🍇被代理的类

package com.view.cglib;
/**
 * @author tanyongpeng
 * <p>被代理的类</p>
 **/
public class CglibService {

    public void cg1(){
        System.out.println("代理类 正在执行============");
    }

}

🍇代理类

package com.view.cglib;

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

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author tanyongpeng
 * <p>代理类</p>
 **/
public class CgServiceInterceptor implements MethodInterceptor {

    // 被代理的类
    private Object target;

    // 前置执行的类
    private Class<?> afterClass;

    // 前置执行的方法
    private String afterMethod;

    // 后置执行的类
    private Class<?> befClass;

    // 后置执行的方法
    private String befMethod;


    public CgServiceInterceptor(Object target, Class<?> afterClass, String afterMethod, Class<?> befClass, String befMethod) {
        this.target = target;
        this.afterClass = afterClass;
        this.afterMethod = afterMethod;
        this.befClass = befClass;
        this.befMethod = befMethod;
    }

    public CgServiceInterceptor(Object target) {
        this.target = target;
    }

    public void CgMethod(String methodName, Class<?> cls) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Object newInstance = cls.newInstance();
        Method method = cls.getMethod(methodName);
        // 执行被代理类的方法 之前执行的方法或者之后执行的方法
        method.invoke(newInstance);
    }

    public void after() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        if (afterClass != null){
            CgMethod(afterMethod,afterClass);
        }
    }

    public void bef() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        if (befClass != null){
            CgMethod(befMethod,befClass);
        }
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        after();
        Object result = methodProxy.invokeSuper(o, objects);
        bef();
        return result;
    }

    public static <T> T createProxy(T target) {
        return createProxy(target,null,null,null,null);
    }

    public static <T> T createProxy(T target,Class<?> afterClass,String afterMethod) {
        return createProxy(target,afterClass,afterMethod,null,null);
    }

    public static <T> T createProxy(T target,Class<?> afterClass,String afterMethod,Class<?> befClass,String befMethod) {
        CgServiceInterceptor cglibProxyTest = new CgServiceInterceptor(target,afterClass,afterMethod,befClass,befMethod);
        Enhancer enhancer = new Enhancer();
        enhancer.setCallback(cglibProxyTest);
        enhancer.setSuperclass(target.getClass());
        return (T) enhancer.create();
    }
}

🍇编写两个操作类

🍌学生类

package com.view.cglib.exec;

/**
 * @author tanyongpeng
 * <p>对学生操作类</p>
 **/
public class StudentAll {

    public void add(){
        System.out.println("学生 的添加操作");
    }

    public void log(){
        System.out.println("学生 日志添加");
    }
}

🍌老师类

package com.view.cglib.exec;

/**
 * @author tanyongpeng
 * <p>对老师操作类</p>
 **/
public class TeacherAll {

    public void add(){
        System.out.println("老师 的添加操作");
    }

    public void log(){
        System.out.println("老师 日志添加");
    }
}

🍇测试

🍌默认执行操作

    public static void main(String[] args) {
        CglibService cglibService = CgServiceInterceptor.createProxy(new CglibService());
        cglibService.cg1();
    }

输出:
在这里插入图片描述

🍌带前置学生执行添加方法

    public static void main(String[] args) {
        CglibService cglibService = CgServiceInterceptor.createProxy
                (new CglibService(),StudentAll.class,"add");
        cglibService.cg1();
    }

输出
在这里插入图片描述

🍌带前置学生执行日志方法

    public static void main(String[] args) {
        CglibService cglibService = CgServiceInterceptor.createProxy
                (new CglibService(),StudentAll.class,"log");
        cglibService.cg1();
    }

在这里插入图片描述

🍌只执行后置方法

    public static void main(String[] args) {
        CglibService cglibService = CgServiceInterceptor.createProxy
                (new CglibService(),null,null,TeacherAll.class,"add");
        cglibService.cg1();
    }

输出
在这里插入图片描述

🍌带前置和后置的学生方法和老师方法

    public static void main(String[] args) {
        CglibService cglibService = CgServiceInterceptor.createProxy
                (new CglibService(),StudentAll.class,"log",TeacherAll.class,"add");
        cglibService.cg1();
    }

输出
在这里插入图片描述


总结

以此内推,前置和后置执行的方法变成动态传递,并且目标类也是动态传入

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/112550.html

(0)
Java光头强的头像Java光头强

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!