springaop底层使用了动态代理,spring框架会生成代理类,并管理起代理对象。spring底层是如何生成代理类呢?
在这之前先了解一下jdk自己封装的Proxy代理类
例子:删除id为11的图书
业务层:BookServiceImpl
public void delete(Integer id) {
System.out.println("删除了id为"+id+"的学生");
}
TestProxy代理类
import com.baizhi.service.BookService;
import com.baizhi.service.impl.BookServiceImpl;
import java.lang.reflect.Proxy;
/**
* @Author: ChenShiQi
* @Date: 2020/7/16
*/
public class TestProxy {
public static void main(String[] args) {
/**
* 目标对象就是bs
* 使用jdk中提供的Proxy类帮助我们产生一个ss的代理对象
*/
BookService bs = new BookServiceImpl();
BookService bookServiceProxy = (BookService) Proxy.newProxyInstance(
//1.第一个参数是类加载器,选择用哪个类加载器加载代理类。这里利用本类获取类加载器
TestProxy.class.getClassLoader(),
//2.第二个参数是告知代理类实现什么接口,是Class[]类型的,因为一个业务类可能会实现多个接口
new Class[]{BookService.class},
//3.第三个参数是个InvocationHandler接口实现类,用来封装额外功能,这里用的是lambda表达式
(proxy,method,params)->{
/**
* InvocationHandler ih=new InvocationHandler() {
* @Override
* //1.proxy代理对象,2.目标方法,3.args调用目标方法时所需要的参数
* //做额外功能,调用目标方法。
* public Object invoke(Object proxy, Method method, Object[] params) throws Throwable {
* System.out.println("11111111111");
* System.out.println(method);
* method.invoke(ss, params);
* return null;
* }
* };
*/
System.out.println("这是jdk代理类");
System.out.println("proxy.getClass() = " + proxy.getClass());
Object o = method.invoke(bs, params);
return o;
}
);
bookServiceProxy.delete(11);
}
}
打印结果为:
Proxy在产生代理对象时,必须要求目标类实现接口,否则就不能产生代理类。这种称之为静态代理。
spring的aop是动态代理
spring实际可以帮助没有接口的类产生代理对象,那么接下来看springaop底层实现
它使用了cglib这个工具帮助生成代理类。
代理类:
TestCglib
import com.baizhi.service.impl.BookServiceImpl;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* @Author: ChenShiQi
* @Date: 2020/7/16
*/
public class TestCglib {
public static void main(String[] args) {
//目标类
BookServiceImpl bs = new BookServiceImpl();
//初始化
Enhancer enhancer=new Enhancer();
//设置类加载器
enhancer.setClassLoader(TestCglib.class.getClassLoader());
//设置代理类继承哪个父类
enhancer.setSuperclass(BookServiceImpl.class);
//设置额外功能
enhancer.setCallback(
/**
*这里不能用lambda表达式,原因是MethodInterceptor这个方法是一个默认方法
* lambda表达式只能实现函数式接口并完成对象的创建,是匿名内部类的简化,
* 使用场景:当接口中只有一个抽象方法是(静态方法,默认方法不在其中)
*/
new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("额外功能.....");
Object result = method.invoke(bs, objects);
return result;
}
}
);
//创建代理类
BookServiceImpl bookServiceProxy = (BookServiceImpl) enhancer.create();
bookServiceProxy.delete(11);
}
}
打印结果:
cglib可以产生代理对象,它比jdk强大的地方是当目标类没有实现接口是,cglib也可以创建出代理对象。