文章目录
动态代理以及.Cglib动态代理通过动态代理和cglib来理解spring的AOP(Aspect Orient Programing)动态
动态代理以及.Cglib动态代理
通过动态代理和cglib来理解spring的AOP(Aspect Orient Programing)动态代理是通过JDK实现了反射是
–出现的
1). 代理设计模式:为其他对象提供一种代理以控制对这个对象的访问。
类加载器
- 概述
- JDK 提供的代码.
- 运行时代码. 引导类加载器
- 扩展代码. 扩展类加载器
- 自己编写的代码.(以及第三方包) 应用类加载器
- 运行时代码. 引导类加载器
- 三种类加载器
- 引导类加载器(Bootstrap ClassLoader)
- 负责加载$JAVA_HOME中jre/lib/rt.jar里所有的class,由C++实现,不是ClassLoader子类
- 扩展类加载器(Extension ClassLoader)
- 负责加载java平台中扩展功能的一些jar包,包括$JAVA_HOME中jre/lib/*.jar(jre/lib/ext)
- 应用类加载器:(Application ClassLoader)
- 加载编写的代码
- 引导类加载器(Bootstrap ClassLoader)
- 继承关系
- 引导类加载器由C++实现,不是ClassLoader子类(属于JVM的一部分)
- 扩展类加载器是引导类加载器子类
- 应用类加载器是扩展类加载器子类
- 双亲委托机制: 一个class文件只会加载一次,在内存有且只有一个Class对象
- 如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的加载器都是如此,因此所有的类加载请求都会传给顶层的启动类加载器
- 只有当父加载器反馈自己无法完成该加载请求(该加载器的搜索范围中没有找到对应的类)时,子加载器才会尝试自己去加载。
- JDK 提供的代码.
- 概述
动态代理
- 在运行时动态的创建代理类对象(无需定义一个代理类)
- java动态代理机制以巧妙的方式实现了代理模式的设计理念
- 作用:在被调用方法时,对委托者(被代理对象)进行 拦截和控制
- 在运行时动态的创建代理类对象(无需定义一个代理类)
结构
- 代理类对象 proxy (本质是一个匿名类对象)
- 委托类对象(被代理的对象)
- 接口(必须要有),被拦截的是接口中的方法
代码含义
- Proxy.newProxyInstance(loader, interfaces, new InvocationHandler(){});
- 参数loader:代理类对象是运行时动态创建的,因为代理类在代码中并没有定义,需要在运行时动态加载,故需要类加载器(和被代理类加载器一样即可)
- 参数interfaces:接口用来动态的创建代理类,本质上这个代理类(匿名类)是接口的实现类,拥有接口中的所有方法(这个参数是复数,一般将委托类实现的所有接口传入)
- InvocationHandler:调用处理器,本质是接口回调
2.重写 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - proxy:代理类对象本身(几乎没作用)
- method:当前代理类对象执行的方法(拦截)
- args:当前方法所需要的参数
- 返回值:当前方法的返回值
final CustomerDao customerDao= new CustomerDaoImpl();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21ClassLoader classLoader = customerDao.getClass().getClassLoader();
Class<?>[] interfaces = customerDao.getClass().getInterfaces();
InvocationHandler h =new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.print(method.getName()+" ");
if(args==null){
System.out.println("没有参数不增强");
}else {
Object invoke = method.invoke(customerDao, args);
System.out.println("方法增强");
}
return null;
}
};
CustomerDao case =(CustomerDao) Proxy.newProxyInstance(classLoader, interfaces,h);
case.update();- Proxy.newProxyInstance(loader, interfaces, new InvocationHandler(){});
2).Cglib动态代理
本质是生成这个目标类的子类实现功能
final CustomerDao customerDao=new CustomerDaoImpl();
1 | ClassLoader classLoader = customerDao.getClass().getClassLoader(); |