美文网首页
2019-04-27_CGlib相关概念

2019-04-27_CGlib相关概念

作者: kikop | 来源:发表于2019-04-27 16:49 被阅读0次

    CGlib相关概念

    1.****CGlib概述

    cglib代理,也叫做子类代理。在内存中构建一个子类对象从而实现对目标对象功能的扩展。

    CGLIB是一个强大的高性能的代码生成包,它可以在运行期扩展Java类与实现Java接口。它广泛的被许多AOP的框架使用,例如Spring AOP和dynaop,为他们提供方法的interception(拦截)。

    CGLIB包的底层是通过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的类。不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉。

    弥补动态代理无法实现的功能:被代理的对象没有实现接口。

    2.CGlib子类代理特点

    1. 需要引入cglib – jar文件, 但是spring的核心包中已经包括了cglib功能,我这里引入spring-core-5.0.0.jar。

    2)引入功能包后,就可以在内存中动态构建子类

    3)代理的类不能为final, 否则报错。

    4)目标对象的方法如果为final/static, 那么就不会被拦截,即不会执行目标对象额外的业务方法。

    3.练习

    3.1.实体定义

    package com.tech.ability.CGlibStudy;

    /**

    • Created by kikop on 2019/4/27.

    */

    public class Book {

    private String strName;
    
    public String getStrName() {
    
        return strName;
    
    }
    
    public void setStrName(String strName) {
    
        this.strName = strName;
    
    }
    
    public Book(String strName) {
    
        this.strName = strName;
    
    }
    
    @Override
    
    public String toString() {
    
        return "Book{" +
    
                "strName='" + strName + '\'' +
    
                '}';
    
    }
    

    }

    3.2.被代理对象

    package com.tech.ability.CGlibStudy;

    /**

    • Created by kikop on 2019/4/27.

    */

    public class Boss {

    /**
    
     * 卖书
    
     */
    
    public void saleBook(Book book) {
    
        System.out.println("走代理,开始卖书:" + book);
    
    }
    
    public final void watchFilm() {
    
        System.out.println("不走代理,老板去看电影!");
    
    }
    
    public void playSwim() {
    
        System.out.println("不走代理,老板去游泳!");
    
    }
    

    }

    3.3.代理对象

    package com.tech.ability.CGlibStudy;

    import org.springframework.cglib.proxy.Enhancer;

    import org.springframework.cglib.proxy.MethodInterceptor;

    import org.springframework.cglib.proxy.MethodProxy;

    import java.lang.reflect.Method;

    import java.util.HashSet;

    import java.util.Set;

    /**

    • 代理对象

    • Created by kikop on 2019/4/27.

    */

    public class CGlibProxyFactory implements MethodInterceptor {

    /**
    
     * 无序
    
     * 不可重复
    
     */
    
    private static Set<String> stringHashSet=new HashSet<String>();
    
    static {
    
        stringHashSet.add("saleBook");
    
        stringHashSet.add("watchFilm");
    
        stringHashSet.add("saleBook1");
    
        stringHashSet.add("watchFilm1");
    
        stringHashSet.add("saleBook2");
    
        stringHashSet.add("watchFilm2");
    
        stringHashSet.add("saleBook3");
    
        stringHashSet.add("watchFilm3");
    
    }
    
    /**
    
     * 被代理对象
    
     * 这里:Boss
    
     */
    
    public Object target;
    
    public CGlibProxyFactory(Object target) {
    
        this.target = target;
    
    }
    
    /**
    
     * 创建代理对象
    
     * Waiter
    
     *
    
     * @return
    
     */
    
    public Object getProxyInstance() {
    
        Enhancer enhancer = new Enhancer();
    
        enhancer.setSuperclass(target.getClass());
    
        enhancer.setCallback(this);
    
        //创建子类(代理对象)
    
        return enhancer.create();
    
    }
    
    /**
    
     * @param o           代理对象
    
     * @param method      被代理对象方法
    
     * @param objects     被代理对象参数
    
     * @param methodProxy
    
     * @return
    
     * @throws Throwable
    
     */
    
    @Override
    
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
    
        if (stringHashSet.contains(method.getName())) {//这里只改造被代理对象的saleBook方法
    
            System.out.println("开始事务之前...");
    
            // 执行被代理对象的方法
    
            Object invoke = method.invoke(target, objects);
    
            System.out.println("提交事务后!");
    
            return invoke;
    
        } else {//其余方法按原样执行
    
            return method.invoke(target, objects);
    
        }
    
    }
    

    }

    3.4.测试

    package com.tech.ability.CGlibStudy;

    /**

    • Created by kikop on 2019/4/27.

    */

    public class CGlibTest {

    public static void main(String[] args) {
    
        Book book = new Book("jvm");
    
        Boss boss = new Boss();
    
        System.out.println(book.getClass());
    
        Boss proxyBoss = (Boss) new CGlibProxyFactory(boss).getProxyInstance();
    
        System.out.println(proxyBoss.getClass());
    
        proxyBoss.saleBook(book);
    
        proxyBoss.playSwim();
    
        proxyBoss.watchFilm();
    
    }
    

    }

    3.5.结果

    class com.tech.ability.CGlibStudy.Book

    class com.tech.ability.CGlibStudy.BossEnhancerByCGLIB637fe51f

    开始事务之前...

    走代理,开始卖书:Book{strName='jvm'}

    提交事务后!

    不走代理,老板去游泳!

    不走代理,老板去看电影!

    参考

    1.浅谈java中的cglib代理

    https://blog.csdn.net/wang1171405487/article/details/80633883

    相关文章

      网友评论

          本文标题:2019-04-27_CGlib相关概念

          本文链接:https://www.haomeiwen.com/subject/wtbknqtx.html