Java CGLIB动态代理

JDK InvocationHandler的动态代理是基于接口来实现的,从newProxyInstance()方法中的参数也可以看出来,假如被代理的对象的类并没有实现接口,而是一个普通的类,那么久可以通过CGLIB动态代理来实现

了解了JDK动态代理之后,再来理解CGLIB相对容易一些,大致流程

1、通过CGLIB的Enhancer对象注入被代理类和方法属性,进而调用create()方法来创建代理对象

2、实现MethodInterceptor接口,重写intercept()方法,可以修改方法实现,功能和JDK动态代理的invoke()方法一样

3、当代理类调用方法时,会转发给MethodInterceptor实现类Override的intercept()方法,最终通过proxy.invokeSuper()方法转发给被代理的对象,完成方法的调用

可以看到,和JDK动态代理思路异曲同工,这里关键可以实现非接口实现类的动态代理

 

首先新增依赖

<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>

被代理类,普通类即可

package com.lihuia.cglib;

/**
* Copyright (C), 2018-2019
* FileName: Hello
* Author: lihui
* Date: 2019/11/21
*/

public class Hello {

public String sayHello(String message) {
return "Hello " + message;
}
}

接着必须要实现MethodInterceptor接口,重写intercept,才能接收转发过来的方法,以及通过methodProxy.invokeSuper()转发给被代理类对象执行

package com.lihuia.cglib;

import java.lang.reflect.Method;
import java.util.Arrays;

import lombok.extern.slf4j.Slf4j;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

/**
* Copyright (C), 2018-2019
* FileName: HelloInterceptor
* Author: lihui
* Date: 2019/11/21
*/

@Slf4j
public class HelloInterceptor implements MethodInterceptor {

@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
log.info(Arrays.toString(objects));
return methodProxy.invokeSuper(o, objects);
}
}

最关键的是的注入这里

创建Enhancer类对象,设置SuperClass,以及回调方法

package com.lihuia.cglib;

import net.sf.cglib.proxy.Enhancer;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
* Copyright (C), 2018-2019
* FileName: HelloConfig
* Author: lihui
* Date: 2019/11/21
*/

@Configuration
public class HelloConfig {

@Bean
public HelloInterceptor helloInterceptor() {
return new HelloInterceptor();
}

@Bean
public Enhancer enhancer() {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(Hello.class);
enhancer.setCallback(helloInterceptor());
return enhancer;
}
}

最后是测试类

package com.lihuia.cglib;

import javax.annotation.Resource;

import lombok.extern.slf4j.Slf4j;
import net.sf.cglib.proxy.Enhancer;
import org.testng.annotations.Test;

import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;

/**
* Copyright (C), 2018-2019
* FileName: HelloTest
* Author: lihui
* Date: 2019/11/21
*/

@ContextConfiguration(classes = {HelloConfig.class})
@Slf4j
public class HelloTest extends AbstractTestNGSpringContextTests {

@Resource
private Enhancer enhancer;

@Test
public void cglibHelloTest() {

Hello proxy = (Hello) enhancer.create();
log.info(proxy.sayHello("World"));
}

}

调用Enhancer的create()方法创建代理类,通过调用方法回调给intercept,最终转发给被代理类的sayHello()方法

 

OVER

发表回复