DynamicProxy
为什么使用动态代理?
-
当接口中的实现方法发生改变的时候,那么实现接口的实现类也会随之而改变
-
代理对象发生改变,测试程序也要发生改变,一切都要随之发生改变
-
可以使用动态代理解决这个问题
-
代理对象在程序运行的过程中动态在内存中构建,可以灵活的进行业务功能的切换
JDK动态代理
-
目标对象必须实现业务接口
-
JDK代理对象不需要实现业务接口
-
JDK动态代理的对象在程序运行前不存在,在程序运行是动态的在内存中构建
-
JDK动态代理灵活的进行业务功能的切换
-
本类中的方法(非接口中的方法不能被代理)
JDK动态代理用到的类和接口(两个类一个接口)
-
它是使用现在的工具类完成JDK动态实现
-
Proxy
-
他是java.lang.reflect.Proxy包下的类
-
public static Object newProxyInstance(ClassLoader loader,//类加载器 Class<?>[] interfaces,//目标对象实现的所有接口 InvocationHandler h //它就类似于Agent的功能,代理的功能和目标对象的业务功能调用在这.这是个接口 ){...}
-
-
method类
反射用的类,用来进行目标对象的方法的反射调用。
-
(外面调用什么方法,method就可以反射代理什么方法,可以指代那个方法)
method对象借助正在调用的sing(),show() . method==sing();method==show()
method.invoke;//===>手动调用目标方法 sing(),show()
-
InvocationHandler接口
-
它是用来实现代理和业务功能的,在调用时使用匿名内部实现。
-
-
CGLib
-
又称为子类代理,通过动态的在内存中构建子类对象,重写父类的方法进行代理功能的增强。
-
存在意义
-
如果目标对象没有是心啊接口,则只能通过CGLib子类带了来进行功能增强。
-
-
子类代理是通过对象字节码框架ASM来实现的。在Sprint框架里面配置比较简单,Mybatis主要还是使用JDK代理
代理模式
-
代理模式:
-
无法访问目标对象,通过代理对象进行访问,而且增强式的访问。适合进行业务的扩展
-
-
代理模式的功能
-
增强功能
-
限制目标对象的访问
-
-
分类
-
静态代理
-
目标对象和代理对象实现同一个业务接口
-
代理对象实现功能时必须依靠目标对象自己实现
-
当业务发生变化是,要进行大量的代码改动,实现复杂
-
代理类是以.java的文件形式存在,在调用前就已经存在,所以比较死板
-
实现
-
-
动态代理
动态代理代码的梳理
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
SqlSession sqlSession = factory.openSession();
-
JDK动态代理
-
代理对象不需要实现业务接口
-
代理对象是在程序运行时动态的在内存中够时间的
-
目标对象不许要实现接口,才可以使用JDK的动态代理
-
-
CGLib动态代理
-
(子类代理【简易版本】)
-
完整版本要等到Spring框架之后
-
-
通过流的方式获得资源,使用文件流读取核心配置文件(config文件)
-
通过建造者模式创建了SqlSessionFacroty工厂
-
从工厂中取出代理对象,代理对象有着目标对象的所有方法和属性,客户端对象就可以直接访问代理对象来达到和目标对象交流的目的
-
-
UserMapper uMapper = sqlSession.getMapper(UserMapper.class);
* 这是一个映射器,代码的作用是将UserMapper接口中的方法和属性全部一一检索到uMapper映射器里面,就可以通过这个映射器取代理目标接口
-