代理模式
好处,可以在目标对象实现的基础上,增加额外的功能的操作,扩展目标对象的功能。
原来的代码---
现在想要扩展功能----
1.静态代理
保存数据到数据库
假如不用aop代理,就只有修改原来的UserDao,添加事务的代码。
Dao直接保存
添加事务
现在,添加代理类(静态代理),目标对象UserDao,所以代理类中有一个属性是目标对象UserDao userDao
代理对象要实现与目标对象一样的接口
使用
优点:可以不修改目标对象功能的前提下,对目标对象扩展
缺点:
因为代理对象需要实现与目标对象相同的接口,会有很多的代理类
如果接口增加新的方法,目标对象和代理对象都需要做更改
解决方式:
代理工厂
动态代理
2.动态代理
代理对象不需要实现接口,目标对象需要实现接口
代理对象生成,使用到JDKAPI,动态的在内存中创建代理对象
动态代理也叫JDK代理(接口代理)
API中
Proxy.class
public static Object newProxyInstance();
参数1:ClassLoader 指定当前目标对象的使用类的加载器
参数2:Class<?>[] interfaces,目标对象实现的接口类型(虽然不需要实现接口,但是在动态创建的时候还是需要知道你的接口类型,真正的代理对象实际上实现了这个接口)
参数3:InvocationHandler 事件处理器(调用某一个事件的时候,它会回调内部的方法,帮我们返回代理对象)
JDK的Proxy源代码粗略浏览
代理类 这儿的目标对象的类型声明为Object类型,按照本次需求按理说类型应该是IUserDao,但是以后如果有相应的其他接口,又必须重新实现。
使用
当接口新增方法使,目标对象需要做更改,代理对象不需要修改
接口新增update()方法
目标对象修改
代理对象不修改
使用
调用update()方法即可
3.CGLIB代理
解决目标对象没有实现接口的情况
子类代理,在内存中构建一个子类对象从而实现对哦目标对象的扩展
CGLIB许多AOP框架使用
步骤:
引用jar文件。--spring-core包已经使用了CGLIB的jar包
在内存中动态创建的子类
目标对象不可以是final
目标对象的方法使final、static,则不会拦截
在spring AOP编程中
如果加入容器中的目标对象有实现接口,用JDK代理
如果目标对象没有实现接口,用cglib代理
代理类ProxyFactory实现MethodInterceptor接口(拦截器)
使用
-----------------------------------------------------------------------------------------------------------------------------
目标类UserDao
关注点MyAop
目标类变为,去掉关注点代码(MyAop的方法),让代理类来实现
代理类
xml文件
使用