第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定

AOP底層原理之CGlib

標(biāo)簽:
Java Spring Cloud

什么是CGlib

Cglib的官方解释: Byte Code Generation Library is high level API to generate and transform Java byte code. It is used by AOP, testing, data access frameworks to generate dynamic proxy objects and intercept field access.

所以, cglib是一个功能强大、高性能和高质量的代码生成库,它用于扩展JAVA类并在运行时实现接口。

AOP, SPring AOP, Hibernate等都在使用CGlib, EasyMock和jMock是使用模拟对象测试Java代码的库。它们都使用CGLIB库为没有接口的类创建模拟对象。

CGLIB库使用ASM(一个小型但快速的字节码操作框架)转换现有的字节码并生成新类。除了CGLIB库,脚本语言(如Groovy和BeanShell)也使用ASM生成Java字节码。ASM使用类似SAX的解析器机制来实现高性能。

图片描述

图中显示了CGLIB库相关框架和语言之间的关系。注意,一些框架,如Spring AOP和Hibernate,经常同时使用CGLIB库和JDK动态代理来满足它们的需求。Hibernate使用JDK动态代理为WebShere应用服务器实现事务管理器适配器;默认情况下,Spring AOP使用JDK动态代理来代理接口,除非强制使用CGLIB代理。

下面举例介绍下CGLib的典型应用:
准备工作, 创建一个Bean类:

package com.xqljj;
public class Dao {
	public Dao() {
        update();
    }

    public void update() {
        System.out.println("PeopleDao.update()");
    }
    
    public void select() {
        System.out.println("PeopleDao.select()");
    }
}

1.简单的代理模式实现

我们首先实现一个DaoProxy

package com.xqljj;

import java.lang.reflect.Method;

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

public class DaoProxy implements MethodInterceptor {

    @Override
    public Object intercept(Object object, Method method, Object[] objects, MethodProxy proxy) throws Throwable {
        System.out.println("Before Method Invoke");
        proxy.invokeSuper(object, objects);
        System.out.println("After Method Invoke");
        
        return object;
    }
    
}

那么在调用的时候,直接调用

public static void testCglib() {
        DaoProxy daoProxy = new DaoProxy();
        
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(Dao.class);
        enhancer.setCallback(daoProxy);
        
        Dao dao = (Dao)enhancer.create();
        dao.update();
        dao.select();
    }

通过setCallback, 实现代理.

  1. 实现一个带拦截器的Proxy
package com.xqljj;

import java.lang.reflect.Method;

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

public class DaoAnotherProxy implements MethodInterceptor {

    @Override
    public Object intercept(Object object, Method method, Object[] objects, MethodProxy proxy) throws Throwable {
        
        System.out.println("StartTime=[" + System.currentTimeMillis() + "]");
        //method.invoke(object, objects);
        proxy.invokeSuper(object, objects);
        System.out.println("EndTime=[" + System.currentTimeMillis() + "]");
        return object;
    }
    
}

在Enhancer里面set filter, filter可以根据需求来定制:

package com.xqljj;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.CallbackFilter;

public class DaoFilter implements CallbackFilter {

    @Override
    public int accept(Method method) {
        if ("select".equals(method.getName())) {
            return 0;
        }
        return 1;
    }
    
}
  1. 构造函数不拦截方法

那么在enhancer.setInterceptDuringConstruction(false);

public static void testCglib3() {
        DaoProxy daoProxy = new DaoProxy();
        DaoAnotherProxy daoAnotherProxy = new DaoAnotherProxy();
        
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(Dao.class);
        enhancer.setCallbacks(new Callback[]{daoProxy, daoAnotherProxy, NoOp.INSTANCE});
        enhancer.setCallbackFilter(new DaoFilter());
        enhancer.setInterceptDuringConstruction(false);
        
        Dao dao = (Dao)enhancer.create();
        dao.update();
        dao.select();
    }
  1. 返回相同的值

Bean类:

package com.xqljj;
public class PersonService {
    public String sayHello(String name) {
        return "Hello " + name;
    }
 
    public Integer lengthOfName(String name) {
        return name.length();
    }
}

对于上面的类,我们创建一个拦截器,来拦截SayHello方法.Cglib里面Enhancer,我们可以利用它来创建一个动态代理. enhancer.setSuperclass(PersonService.class);
我们想要每次都返回相同的值,实现方法如下:

public static void fixvalue() {
	Enhancer enhancer = new Enhancer();
	enhancer.setSuperclass(PersonService.class);
	enhancer.setCallback((FixedValue) () -> "Hello Tom!");
	PersonService proxy = (PersonService) enhancer.create();
	 
	String res = proxy.sayHello("HAHA");
	 
	System.out.println(res);
}
  1. 不同方法实现不同的拦截

实现代码如下:

public static void methodDepend() {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(PersonService.class);
enhancer.setCallback((MethodInterceptor) (obj, method, args, proxy) -> {
if (method.getDeclaringClass() != Object.class && method.getReturnType() == String.class) {
return “Hello Tom!”;
} else {
return proxy.invokeSuper(obj, args);
}
});

PersonService proxy = (PersonService) enhancer.create();
 
System.out.println(proxy.sayHello(null));
//assertEquals("Hello Tom!", proxy.sayHello(null));
int lengthOfName = proxy.lengthOfName("Mary");
  
//assertEquals(4, lengthOfName);
System.out.println(lengthOfName);

}

  1. Cglib实现BeanGenerator

public static void beanGenerator() {
BeanGenerator beanGenerator = new BeanGenerator();

beanGenerator.addProperty("name", String.class);
Object myBean = beanGenerator.create();

try {
	Method setter = myBean.getClass().getMethod("setName", String.class);
	setter.invoke(myBean, "some string value set by a cglib");
	Method getter = myBean.getClass().getMethod("getName");
    System.out.println(getter.invoke(myBean));
} catch (Exception e) {
	
}

}

  1. 创建Mixin

mixin 就是可以merge多个对象成一个,Cglib支持把多个对象合并成一个, 当然,这些对象需要实现Interface.

举例如下:

public interface Interface1 {
    String first();
}
 
public interface Interface2 {
    String second();
}
 
public class Class1 implements Interface1 {
    @Override
    public String first() {
        return "first behaviour";
    }
}
 
public class Class2 implements Interface2 {
    @Override
    public String second() {
        return "second behaviour";
    }
}

为了合并这两个Interface, 我们需要定义一个mergeinterface
public interface MixinInterface extends Interface1, Interface2 { }

合并后, 调用Mixin.create

public static void testMiXin() {
Mixin mixin = Mixin.create(
new Class[]{ Interface1.class, Interface2.class, MixinInterface.class },
new Object[]{ new Class1(), new Class2() }
);
MixinInterface mixinDelegate = (MixinInterface) mixin;

		System.out.println(mixinDelegate.first());
		System.out.println(mixinDelegate.second());

}

运行,打印的结果是:

first behaviour
second behaviour

总结:
Cglib广泛用于Spring,Hibernate,Mock等,是一个高性能的代码生成库,还有很多使用场景,例如Java Security, Java序列化等,需要仔细摸索.
另外,以上代码,好多没有写打印结果,但作者都一一编译运行过了,你不妨也试试,可以有很深的体会.

點(diǎn)擊查看更多內(nèi)容
1人點(diǎn)贊

若覺得本文不錯(cuò),就分享一下吧!

評(píng)論

作者其他優(yōu)質(zhì)文章

正在加載中
感謝您的支持,我會(huì)繼續(xù)努力的~
掃碼打賞,你說多少就多少
贊賞金額會(huì)直接到老師賬戶
支付方式
打開微信掃一掃,即可進(jìn)行掃碼打賞哦
今天注冊(cè)有機(jī)會(huì)得

100積分直接送

付費(fèi)專欄免費(fèi)學(xué)

大額優(yōu)惠券免費(fèi)領(lǐng)

立即參與 放棄機(jī)會(huì)
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)

舉報(bào)

0/150
提交
取消