动态代理有 jdk代理 及cglib代理,下面描述cglib代理
cglib代理
看了 上云 老师的视频,整理下
pom文件
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>
目标类 IStudentServiceImpl
//目标执行接口
public interface IStudentService {
void save();
List<Student> query();
}
//目标执行类实现
@Service
public class IStudentServiceImpl implements IStudentService {
private static final Logger logger= LoggerFactory.getLogger(IStudentServiceImpl.class);
@Override
public void save() {
logger.info("新增功能...");
}
@Override
public List<Student> query() {
logger.info("查询功能...");
return new ArrayList<>();
}
}
增强类 TransactionService
@Service
public class TransactionService{
private static final Logger logger= LoggerFactory.getLogger(TransactionService.class);
public void before(){
logger.info("开始事务...");
}
public void after(){
logger.info("结束事务...");
}
}
代理类 CglibInterceptor
public class CglibInterceptor implements MethodInterceptor {
TransactionService transactionService;
public CglibInterceptor(TransactionService transactionService) {
this.transactionService = transactionService;
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
//增强操作
transactionService.before();
Object res = methodProxy.invokeSuper(o, objects);
transactionService.after();
return res;
}
}
测试类
@Test
public void testCglib(){
//生成目标代理类
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY,"D:\\programs\\idea\\projects\\demo1\\src\\");
//得到方法拦截器
CglibInterceptor interceptor = new CglibInterceptor(new TransactionService());
//使用cglib框架生成目标类的子类(代理类)实现增强
Enhancer enhancer=new Enhancer();
//设置父类字节码
enhancer.setSuperclass(IStudentServiceImpl.class);
//设置拦截器
enhancer.setCallback(interceptor);
IStudentService studentService = (IStudentService)enhancer.create();
studentService.save();
}
结论
生成文件
可以看到 类文件重写save方法
- 通过继承的方式获取到目标对象的方法[IStudentServiceImplEnhancerByCGLIBdf12e223.class文件是继承目标对象]
- 通过传递方法拦截器MethodInterceptor实现方法拦截,在里面做具体的增强[重写CglibInterceptor实现MethodInterceptor,重写intercept方法]
- 调用生成的代理对象执行重写的save方法,直接去调用方法拦截器里面的interceptor方法[IStudentServiceImplEnhancerByCGLIBdf12e223.class文件的save方法]
- 前后加上了增强操作,从而实现了不修改目标代码实现业务增强
cglib代理与jdk动态代理区别
cglib代理:继承机制,通过继承重写目标方法,使用MethodInterceptor调用父类的目标方法从而实现代理
jdk动态代理:通过实现接口,利用反射机制获取接口的方法,并自定义InvocationHandler接口,实现方法拦截