为了账号安全,请及时绑定邮箱和手机立即绑定

由Spring IOC容器来看Java中的反射

标签:
Java

只有自己亲身经历了、思考了,才能真正懂得。
这两天在学习Spring框架,在查阅IOC(控制反转)和DI(依赖注入)的资料时,阅读到一篇博客 关于Spring IOC (DI-依赖注入)你需要知道的一切,由最开始的问题产生来理解解耦合的需要、反射在解耦合中的应用以及Spring IOC的产生。之前也阅读过关于反射的文章,可是总感觉理解不到点上,而现在自己正在经历这个问题时,也就能更好地理解一些了。
为了方便阅读,以下是截取原文章的部分内容。同时建议参考慕课网上的一篇关于反射的手记:学习Java应该如何理解反射?


在我们的日常开发中,创建对象的操作随处可见以至于对其十分熟悉的同时又感觉十分繁琐,每次需要对象都需要亲手将其new出来,甚至某些情况下由于坏编程习惯还会造成对象无法被回收,这是相当糟糕的。但更为严重的是,我们一直倡导的松耦合,少入侵原则,这种情况下变得一无是处。于是前辈们开始谋求改变这种编程陋习,考虑如何使用编码更加解耦合,由此而来的解决方案是面向接口的编程,于是便有了如下写法:

/**
* Created by zejian on 2017/1/15.
* Blog : http://blog.csdn.net/javazejian [原文地址,请尊重原创]
*/
public class BookServiceImpl {

 //class
 private  BookDaoImpl bookDaoImpl;
 public void oldCode(){
     //原来的做法
     bookDaoImpl=new bookDaoImpl();
     bookDaoImpl.getAllCategories();
 }

 }
  //=================new====================

public class BookServiceImpl {

 //interface
 private BookDao bookDao;

 public void newCode(){
     //变为面向接口编程
     bookDao=new bookDaoImpl();
     bookDao.getAllCategories();
     }
}

BookServiceImpl类中由原来直接与BookDaoImp打交互变为BookDao,即使BookDao最终实现依然是BookDaoImp,这样的做的好处是显而易见的,所有调用都通过接口bookDao来完成,而接口的真正的实现者和最终的执行者就是bookDaoImpl,当替换bookDaoImpl类,也只需修改bookDao指向新的实现类。
图片描述
虽然上述的代码在很大程度上降低了代码的耦合度,但是代码依旧存在入侵性和一定程度的耦合性,比如在修改bookDao的实现类时,仍然需求修改BookServiceImpl的内部代码,当依赖的类多起来时,查找和修改的过程也会显得相当糟糕,因此我们仍需要寻找一种方式,它可以令开发者在无需触及BookServiceImpl内容代码的情况下实现修改bookDao的实现类,以便达到最低的耦合度和最少入侵的目的。实际上存在一种称为反射的编程技术可以协助解决上述问题,反射是一种根据给出的完整类名(字符串方式)来动态地生成对象,这种编程方式可以让对象在生成时才决定到底是哪一种对象,因此可以这样假设,在某个配置文件,该文件已写好bookDaoImpl类的完全限定名称,通过读取该文件而获取到bookDao的真正实现类完全限定名称,然后通过反射技术在运行时动态生成该类,最终赋值给bookDao接口,也就解决了刚才的存在问题,这里为简单演示,使用properties文件作为配置文件,className.properties如下:

bookDao.name=com.zejian.spring.dao.BookDaoImpl

获取该配置文件信息动态为bookDao生成实现类:

public class BookServiceImpl implements BookService
{
    //读取配置文件的工具类
    PropertiesUtil propertiesUtil=new PropertiesUtil("conf/className.properties");

    private BookDao bookDao;

    public void DaymicObject() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        //获取完全限定名称
        String className=propertiesUtil.get("bookDao.name");
        //通过反射
        Class c=Class.forName(className);
        //动态生成实例对象
        bookDao= (BookDao) c.newInstance();
    }
}

的确如我们所愿生成了bookDao的实例,这样做的好处是在替换bookDao实现类的情况只需修改配置文件的内容而无需触及BookServiceImpl的内部代码,从而把代码修改的过程转到配置文件中,相当于BookServiceImpl及其内部的bookDao通过配置文件与bookDao的实现类进行关联,这样BookServiceImpl与bookDao的实现类间也就实现了解耦合,当然BookServiceImpl类中存在着BookDao对象是无法避免的,毕竟这是协同工作的基础,我们只能最大程度去解耦合。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消