最新公告
  • 欢迎您光临极客文库,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入我们
  • 代理分类

    1. 静态代理
    2. 动态搭理

    静态代理

    我们先说静态代理的实现方式,为什么不推荐使用静态代理?
    1.继承方式实现代理(静态代理中的继承代理)
    1. //目标对象
    2. publicclassUserImpl{
    3. publicvoid system(){
    4. System.out.println(“输出测试”);
    5. }
    6. }
    7. //代理对象
    8. publicclassProxyextendsUserImpl{
    9. @Override
    10. publicvoid system(){
    11. super.system();
    12. System.out.println(“增强之后的输出”);
    13. }
    14. }
    15. //测试类
    16. publicclassTestMain{
    17. publicstaticvoid main(String[] args){
    18. UserImpl user =newProxy();
    19. user.system();
    20. }
    21. }
    静态代理可以看出来一点问题吧?
    每次代理都要实现一个类,导致项目中代码很多;你每次想要代理,都要去实现一个类,代码就会成堆的增加,然后你就会发现项目的类就会越来越多,就会导致你们的项目显得很臃肿。而且代码的复用性太低了,并且耦合度非常高,这个我们所说的高内聚低耦合是相悖的。

    动态代理

    我们在看一下这个动态代理:
    1. //接口类
    2. publicinterfaceItalk{
    3. publicvoid talk(String msg);
    4. }
    5. //实现类
    6. publicclassPeopleimplementsItalk{
    7. publicString username;
    8. publicString age;
    9. publicString getName(){
    10. return username;
    11. }
    12. publicvoid setName(String name){
    13. this.username= name;
    14. }
    15. publicString getAge(){
    16. return age;
    17. }
    18. publicvoid setAge(String age){
    19. this.age = age;
    20. }
    21. publicPeople(String name1,String age1){
    22. this.username= name1;
    23. this.age = age1;
    24. }
    25. publicvoid talk(String msg){
    26. System.out.println(msg+”!你好,我是”+username+”,我年龄是”+age);
    27. }
    28. }
    29. //代理类
    30. publicclassTalkProxyimplementsItalk{
    31. Italk talker;
    32. publicTalkProxy(Italk talker){
    33. //super();
    34. this.talker=talker;
    35. }
    36. publicvoid talk(String msg){
    37. talker.talk(msg);
    38. }
    39. publicvoid talk(String msg,String singname){
    40. talker.talk(msg);
    41. sing(singname);
    42. }
    43. privatevoid sing(String singname){
    44. System.out.println(“唱歌:”+singname);
    45. }
    46. }
    47. //测试
    48. publicclassMyProxyTest{
    49. //代理模式
    50. publicstaticvoid main(String[] args){
    51. //不需要执行额外方法的
    52. Italk people1=newPeople(“湖海散人”,”18″);
    53. people1.talk(“No ProXY Test”);
    54. System.out.println(“—————————–“);
    55. //需要执行额外方法的
    56. TalkProxy talker=newTalkProxy(people1);
    57. talker.talk(“ProXY Test”,”七里香”);
    58. }
    59. }
    上面代码解析
    一个 Italk 接口,有空的方法 talk()(说话),所有的 people 对象都实现(implements)这个接口,实现 talk() 方法,前端有很多地方都将 people 实例化,执行 talk 方法,后来发现这些前端里有一些除了要说话以外还要唱歌(sing),那么我们既不能在 Italk 接口里增加 sing() 方法,又不能在每个前端都增加 sing 方法,我们只有增加一个代理类 talkProxy ,这个代理类里实现 talk 和 sing 方法,然后在需要 sing 方法的客户端调用代理类即可,
    这也是实现动态代理的方式,是通过实现(implements)的方式来实现的,这种方法的优点,在编码时,代理逻辑与业务逻辑互相独立,各不影响,没有侵入,没有耦合。

    cgLib代理

    还有一种是cgLib的代理,这种代理则是适合那些没有接口抽象的类代理,而Java 动态代理适合于那些有接口抽象的类代理。
    我们来通过代码了解一下他到底是怎么玩的。
    1. //我们实现一个业务类,不实现任何的接口
    2. /**
    3. * 业务类,
    4. */
    5. publicclassTestService{
    6. publicTestService(){
    7. System.out.println(“TestService的构造”);
    8. }
    9. /**
    10. * 该方法不能被子类覆盖,Cglib是无法代理final修饰的方法的
    11. */
    12. finalpublicString sayOthers(String name){
    13. System.out.println(“TestService:sayOthers>>”+name);
    14. returnnull;
    15. }
    16. publicvoid sayHello(){
    17. System.out.println(“TestService:sayHello”);
    18. }
    19. }
    20. /**
    21. * 自定义MethodInterceptor
    22. */
    23. publicclassMethodInterceptorTestimplementsMethodInterceptor{
    24. @Override
    25. publicObject intercept(Object o,Method method,Object[] objects,MethodProxy methodProxy)throwsThrowable{
    26. System.out.println(“======插入前置通知======”);
    27. Objectobject= methodProxy.invokeSuper(o, objects);
    28. System.out.println(“======插入后者通知======”);
    29. returnobject;
    30. }
    31. }
    32. /**
    33. * 测试
    34. */
    35. publicclassClient{
    36. publicstaticvoid main(String[] args){
    37. // 代理类class文件存入本地磁盘方便我们反编译查看源码
    38. System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY,”D:\code”);
    39. // 通过CGLIB动态代理获取代理对象的过程
    40. Enhancer enhancer =newEnhancer();
    41. // 设置enhancer对象的父类
    42. enhancer.setSuperclass(TestService.class);
    43. // 设置enhancer的回调对象
    44. MethodInterceptorTest t =newMethodInterceptorTest();
    45. enhancer.setCallback(t);
    46. // 创建代理对象
    47. TestService proxy=(TestService)enhancer.create();
    48. // 通过代理对象调用目标方法
    49. proxy.sayHello();
    50. }
    51. }
    52. 上面代码想要运行,需要cglib的jar和asm的jar不要忘记找
    运行结果
    1. CGLIB debugging enabled, writing to ‘D:code’
    2. TestService的构造
    3. ======插入前置通知======
    4. TestService:sayHello
    5. ======插入后者通知======
    实现CGLIB动态代理必须实现MethodInterceptor(方法拦截器)接口,
    这个接口只有一个intercept()方法,这个方法有4个参数:
    • obj表示增强的对象,即实现这个接口类的一个对象;
    • method表示要被拦截的方法;
    • args表示要被拦截方法的参数;
    • proxy表示要触发父类的方法对象;

    代理的使用

    那么什么时候使用静态态代理,什么时候使用动态代理和cgLib代理呢?
    一般情况静态代理是很少是用的,因为他对代码的复用性或者说是耦合度都非常不友好,不推荐使用。
    如果目标对象至少实现了一个接口,那么就用JDK动态代理,所有由目标对象实现的接口将全部都被代理。
    如果目标对象没有实现任何接口,就是个类,那么就用CGLIB代理。
    本站所有文章均由网友分享,仅用于参考学习用,请勿直接转载,如有侵权,请联系网站客服删除相关文章。若由于商用引起版权纠纷,一切责任均由使用者承担
    极客文库 » 代理到底是什么?

    常见问题FAQ

    如果资源链接失效了怎么办?
    本站用户分享的所有资源都有自动备份机制,如果资源链接失效,请联系本站客服QQ:2580505920更新资源地址。
    如果用户分享的资源与描述不符怎么办?
    可以联系客服QQ:2580505920,如果要求合理可以安排退款或者退赞助积分。
    如何分享个人资源获取赞助积分或其他奖励?
    本站用户可以分享自己的资源,但是必须保证资源没有侵权行为。点击个人中心,根据操作填写并上传即可。资源所获收益完全归属上传者,每周可申请提现一次。
    如果您发现了本资源有侵权行为怎么办?
    及时联系客服QQ:2580505920,核实予以删除。

    Leave a Reply

    Hi, 如果你对这款资源有疑问,可以跟我联系哦!

    联系发布者

    Leave a Reply

    Hi, 如果你对这款资源有疑问,可以跟我联系哦!

    联系发布者
    • 108会员总数(位)
    • 3695资源总数(个)
    • 3本周发布(个)
    • 0 今日发布(个)
    • 182稳定运行(天)

    欢迎加入「极客文库」,成为原创作者从这里开始!

    立即加入 了解更多
    成为赞助用户享有更多特权立即升级