Spring 底层实现
JDK动态代理 :必须要有接口
CGLIB动态代理 :与接口无关
JDK动态代理
service层
package com.xxxxx.service;
public class UserServiceImpl implements UserService {
@Override
public void add(String name) {
System.out.println("add....." + name);
}
@Override
public void del() {
System.out.println("del.....");
}
@Override
public void update() {
System.out.println("update.....");
}
@Override
public void find() {
System.out.println("find.....");
}
}
代理工厂
public class JDKProxyFactory {
private Object target; // 对象
// 创建目标对象
public JDKProxyFactory(Object target) {
this.target = target;
}
// 创建代理对象
public Object creatProxy() {
//获得类加载器
ClassLoader loader = target.getClass().getClassLoader();
//获得实现的接口
Class[] interfaces = target.getClass().getInterfaces();
//第三个参数需要实现一个InvocationHandler的接口的对象
return Proxy.newProxyInstance(loader, interfaces, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("日志...");
return method.invoke(target, args);
}
}); //
}
测试代码
CGLIB动态代理
CGLIB(Code Generation Library)是一个开源项目
是一个强大的,高性能,高质量的Code生成类库,它可以在运行期扩展Java类与实现Java接口。CGLIB包的底层是通过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的类
如果你要单独使用CGLIB,那么需要导入cglib的jar包还需要一个asm相关jar包,但是spring框架的spring-core.jar包中已经集成了cglib与asm
注意:jdk的动态代理只可以为接口去完成操作,而cglib它可以为没有实现接口的类去做代理,也可以为实现接口的类去做代理。
注意:cglib它可以为没有实现接口的类做代理,也可以为接口类做代理.
问题:spring采用的是哪一种动态机制:
如果目标对象,有接口,优先使用jdk动态代理
如果目标对象,无接口,使用cglib动态代理。
测试代码
@Test
public void test01(){
//创建目标对象
UserService service = new UserServiceImpl();
//通过JDKProxyFactory来创建代理对象
JDKProxyFactory factory = new JDKProxyFactory(service);
UserService userService = (UserService) factory.creatProxy();
userService.add();
}
public class CglibProxyFactory implements MethodInterceptor{
private Object target;//对象
//创建目标对象
public CglibProxyFactory(Object target){
this.target=target;
}
//创建代理对象
public Object creatProxy(){
//创建Enhancer
Enhancer enhancer = new Enhancer();
//传递目标对象的class
enhancer.setSuperclass(target.getClass());
//设置回调操作
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("日志....");
return method.invoke(target, args);
}
}
@Test
public void test01() {
// 创建目标对象
UserService service = new UserServiceImpl();
CglibProxyFactory proxyFactory = new CglibProxyFactory(service);
UserService userService = (UserService) proxyFactory.creatProxy();
userService.add("张三"); //传参
}