简单来说就是当自己需要一个对象的时候不需要自己手动去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文件中配置一下<property,ref="xxbean"),那么这个时候你什么都不用做了,仓库(容器)会自动派人帮你将你所需的调味料(bean)放入到瓶子中 ;当你想换另一种调味料的时候只要将瓶子上的标签改成其他比如胡椒粉(这时要在xml文件中更改一下ref的bean就行了),依赖注入提高了代码的灵活性,你需要替换类的实现的时候,不需要去修改只要在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”);
<beans> <bean/> <bean> <property ref="i"></property> </bean> </beans>
六.编写工厂接口.
//模拟ClassPathXmlApplicationContext实现的一个接口BeanFactory public interface BeanFactory { public Object getBean(String beanName); }
七.编写ClassPathXmlApplicationContext去读取配置文件,并且根据bean.xml里的配置对象去生成各种bean,完成其中的注入工作.(最重要的部分Ioc的实现原理),一字一句都有注释
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。