热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

Spring的Ioc模拟实现详细介绍

这篇文章主要介绍了Spring的Ioc模拟实现详细介绍,具有一定参考价值,需要的朋友可以了解下。

简单来说就是当自己需要一个对象的时候不需要自己手动去new一个,而是由其他容器来帮你提供;Spring里面就是IOC容器。

例如:

在Spring里面经常需要在Service这个装配一个Dao,一般是使用@Autowired注解:类似如下

public Class ServiceImpl{
  @Autowired
   Dao dao;
   
  public void getData(){
    dao.getData();
  }

在这里未初始化Dao直接使用是会报出空指针异常的,那么在Spring里面的做法就是通过反射来将需要的类帮你加载进来。

关于IOC:我们讲个故事吧!

有一个厨师,他在做一道菜的时候需要某种调味料(bean),可是他正好没有那瓶调味料(bean),这个时候他就必须去制作一瓶调味料(bean)出来。(这就像我们平时需要对象的时候一样:UserDao  userdao=new UserDaoImpl)这个时候厨师的工作就不得不跟制作调味料联系起来,这就是所谓的“耦合”。(耦合程度高通说来说就是,我没了你我活不了了。);

这个时候IOC里的控制反转出来了,它提出,开辟一个仓库(容器),里面放着各种各样的调味料(bean),当你需要某种调味料(bean)的时候只要给出调味料的名字(beanName)就可以直接去拿取,代码类似这样:(UserDao user=仓库.get("调味料名字"));这样你就可以直接拿到了调味料 (bean)而不用等到你没有的时候再去制作一瓶出来。这就是所谓的将控制权转移出来,它将生产调味料(bean)的工作直接让仓库(容器)来制作(生产);

接下来依赖注入出来了,它就更加地强大的了,它提出厨师只要有一个瓶子(private UserDao userdao),并且将瓶子盖打开(方法:setUserDao( UserDao userdao){this.userdao=userdao}即提供对于的set方法 )再给瓶子贴上一个标签注明要放什么材料(在xml文件中配置一下

总结一下我的总结:IOC的主要目的就是实现解耦!解耦!解耦!重要的事情说三遍.由厨师的列子来说就是.我是一个厨师我只做菜,我不做调味料~~我不是一个做调味料的,我不跟制作调味料有那么大的关系.   IOC的出现,厨师只要安心做好自己的事情(做菜),需要调味料直接去仓库拿取就行了!那么这样厨师跟调味料的制作之间的关系就分离开来了,这就是解耦!解耦!解耦!使两个东西的关系没那么紧密.

模拟IOC的实现,主要使用的技术是java的反射机制(模拟使用的是架构分为dao层,service层,controller层):

注:欢迎各位大佬的指点,小弟也在学习,说得不好多多包涵~

一.编写dao类,用于测试:

public interface IocDao {
  public void sayhello(); //一个用来测试的接口
}

二.编写dao的实现类:

public class IocDaoImpl implements IocDao {
  @Override
  public void sayhello() {
    // TODO Auto-generated method stub
    System.out.println("hello word");//实现我们的dao接口里的方法
  }
}

三.编写service类:

public interface IocDaoService {
  public void sayhello();//业务类接口,这里就跟dao一样
}

四.编写service的实现类:

public class IocDaoServiceImpl implements IocDaoService {
  private IocDao iocDao;  //创建一个接口.
  public IocDao getIocDao() {
    return iocDao;
  }
  //编写IocDao接口对应的set方法用于依赖注入
  //依赖注入的方式有三种:接口注入,构造方法注入,set注入;
  //此处为set注入
  public void setIocDao(IocDao iocDao) {
    this.iocDao = iocDao;
  }
  @Override
  public void sayhello() {
    // TODO Auto-generated method stub
    iocDao.sayhello();//调用接口方法
  }
}

五.编写bean.xml配置文件.(这里的i你可以看成是IocDaoImpl类,iocService看成IocDaoServiceImpl,iocDao这是IocDaoServiceImpl里的一个属性,这个属性传入的参数值为“i”);


  
 
   
  

六.编写工厂接口.

//模拟ClassPathXmlApplicationContext实现的一个接口BeanFactory
public interface BeanFactory {
  public Object getBean(String beanName);
}

七.编写ClassPathXmlApplicationContext去读取配置文件,并且根据bean.xml里的配置对象去生成各种bean,完成其中的注入工作.(最重要的部分Ioc的实现原理),一字一句都有注释

//模拟ClassPathXmlApplicationContext去读取配置文件
public class ClassPathXmlApplicationContext implements BeanFactory {
  //定义map集合来存放bean.xml里的bean的id跟其对应的实例化对象
  // 
  //那么类似的存放bean.put("i",new IocDaoImpl());这样子.
  Map beans=new HashMap();
  public ClassPathXmlApplicationContext(String xmlPath){
      try {
        //创建SAXBuilder对象解析文档
        SAXBuilder saxBuilder = new SAXBuilder();
        //解析build里的参数是一个文件路径.
        Document document = saxBuilder.build(xmlPath);
        //document.getRootElement().getChildren("bean")获取所有标签内容
        List elements = document.getRootElement().getChildren("bean");
        //遍历对象
        for (int i = 0; i 标签elements.get(0);
          Element element = (Element) elements.get(i);
          //获取标签里的属性,
          // 
          //即String beanName="i";
          String beanName = element.getAttributeValue("id");
          //同上String clazz="com.hck.dao.impl.IocDaoImpl";
          String clazz = element.getAttributeValue("class");
          //加载类对象并且实例化.Object object=new IocDaoImpl();
          Object object = Class.forName(clazz).newInstance();//object是IocDaoServiceImpl
          //将他们添加在map集合里,后面可以根据beanName直接获取到实例化对象.
          beans.put(beanName, object);
          //遍历标签下的字标签.
          //第一个标签没有字标签所以直接跳过.已第二个为例子
          //
          //
          List elements2 = element.getChildren("property");
          for (int j = 0; j 
            Element element2 = (Element) elements2.get(j);
            //相当于String propertyName="iocDao";
            String propertyName = element2.getAttributeValue("name");
            //相当于String refBean="i";
            String refBean = element2.getAttributeValue("ref");
            //相当于String propertyName="IocDao";
            //目的是为了得到一个方法的名字setIocDao,用于反射调用
            propertyName = propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
            //这里的methodName="setIocDao";
            String methodName = "set" + propertyName;
            //获取Map集合里Key="i"的值;i对应的是IocDaoImpl的实例化对象
            //相当于 Object object2 =IocDaoImpl;
            Object object2 = beans.get(refBean);
            //获取IocDaoServiceImpl方法里的setIocDao方法.
            //第一个方法是方法名,第二个参数是方法的参数类型.
            Method method = object.getClass().getDeclaredMethod(methodName,
                object2.getClass().getInterfaces());
            //调用方法,并传入参数,完成依赖注入.
            method.invoke(object, object2);
          }
        }
        //      String beanName=document.getElementById(id).attributes().get("class");
        //      Object object=Class.forName(beanName).newInstance();
        //      return object;
      } catch (Exception e) {
        e.printStackTrace();
        // TODO: handle exception
      }
  }
/* (non-Javadoc)
 * @see com.hck.ioc.BeanFactory#getBean()
 */
@Override
public Object getBean(String beanName) {
  // TODO Auto-generated method stub
  return beans.get(beanName);
}  
}

八.编写测试类

public class Ioc {
  public static void main(String[] args) {
  ClassPathXmlApplicationContext applicatiOnContext=new ClassPathXmlApplicationContext("src/bean.xml");
  IocDaoService ids=(IocDaoService)applicationContext.getBean("iocService");
  ids.sayhello();
}
}

九.显示结果:

hello word

总结

以上就是本文关于Spring的Ioc模拟实现详细介绍的全部内容,希望对大家有所帮助。欢迎参阅:spring的IoC和DI详解、spring配置扫描多个包问题解析、SpringJDBC批量处理数据代码示例等,有什么问题可以随时留言,欢迎大家交流讨论。


推荐阅读
  • Spring常用注解(绝对经典),全靠这份Java知识点PDF大全
    本文介绍了Spring常用注解和注入bean的注解,包括@Bean、@Autowired、@Inject等,同时提供了一个Java知识点PDF大全的资源链接。其中详细介绍了ColorFactoryBean的使用,以及@Autowired和@Inject的区别和用法。此外,还提到了@Required属性的配置和使用。 ... [详细]
  • Spring框架《一》简介
    Spring框架《一》1.Spring概述1.1简介1.2Spring模板二、IOC容器和Bean1.IOC和DI简介2.三种通过类型获取bean3.给bean的属性赋值3.1依赖 ... [详细]
  • r2dbc配置多数据源
    R2dbc配置多数据源问题根据官网配置r2dbc连接mysql多数据源所遇到的问题pom配置可以参考官网,不过我这样配置会报错我并没有这样配置将以下内容添加到pom.xml文件d ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • Servlet多用户登录时HttpSession会话信息覆盖问题的解决方案
    本文讨论了在Servlet多用户登录时可能出现的HttpSession会话信息覆盖问题,并提供了解决方案。通过分析JSESSIONID的作用机制和编码方式,我们可以得出每个HttpSession对象都是通过客户端发送的唯一JSESSIONID来识别的,因此无需担心会话信息被覆盖的问题。需要注意的是,本文讨论的是多个客户端级别上的多用户登录,而非同一个浏览器级别上的多用户登录。 ... [详细]
  • 浅解XXE与Portswigger Web Sec
    XXE与PortswiggerWebSec​相关链接:​博客园​安全脉搏​FreeBuf​XML的全称为XML外部实体注入,在学习的过程中发现有回显的XXE并不多,而 ... [详细]
  • 本文讲述了如何通过代码在Android中更改Recycler视图项的背景颜色。通过在onBindViewHolder方法中设置条件判断,可以实现根据条件改变背景颜色的效果。同时,还介绍了如何修改底部边框颜色以及提供了RecyclerView Fragment layout.xml和项目布局文件的示例代码。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
  • 本文讨论了在Spring 3.1中,数据源未能自动连接到@Configuration类的错误原因,并提供了解决方法。作者发现了错误的原因,并在代码中手动定义了PersistenceAnnotationBeanPostProcessor。作者删除了该定义后,问题得到解决。此外,作者还指出了默认的PersistenceAnnotationBeanPostProcessor的注册方式,并提供了自定义该bean定义的方法。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • ZSI.generate.Wsdl2PythonError: unsupported local simpleType restriction ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 电脑吃鸡按键详细_北通J1手游按键评测:一秒15发的“吃鸡”神器
    近年来,随着战术竞技手游的崛起,在大地图中搜集物资、模拟特种兵对抗等玩法深受玩家喜爱。然而受限于“吃鸡”对移动、视角与射击协同操作的较高要求࿰ ... [详细]
  • PreparedStatement防止SQL注入
    添加数据:packagecom.hyc.study03;importcom.hyc.study02.utils.JDBCUtils;importjava.sql ... [详细]
author-avatar
ze602
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有