springIOC

IOC概念

在网上搜IOC,一定会找到DI的概念,其实IOC与DI讲的是一个意思,他们只是从两个角度描述了Spring IOC容器管理对象依赖关系。

IOC控制反转:说的是创建对象实例的控制权从代码空值剥离到IOC容器控制,实际就是你的xml文件控制,侧重于原理;

DI依赖注入:说的是创建对象实例时,为这个对象注入属性值或其它对象实例,侧重实现。

本来是由应用程序管理的对象之间的依赖关系,现在交给容器管理,这就叫组控制反转。即交给了IOC容器。Spring的IOC容器主要使用DI方式实现的,不需要主动查找。对象的查找、定位和创建全部交给容器管理。

IOC的优点

1、大量减少了Factory和Singleton的数量,使代码层次更加清晰,主要原因是我们不再查找、定位、创建和管理对象之间的依赖关系了,都交给IOC容器管理了。

2、Spring的IOC容器是一个轻量级的容器,没有侵入性,不需要依赖http://write.blog.csdn.net/postedit容器的API,也不需要实现一些特殊接口;

3、更好的管理管理java对象,更好的面向接口编程;

4、解耦合,将耦合推迟到配置文件中,发生变化也更加容器控制。

总之,就是一句话:类之间的依赖关系,不再由类自己去负责,而是由容器根据配置文件去创建实例,并维护各个实例之间的依赖关系。

依赖注入概念:

DI依赖注入是一个很大的概念,它有两种类型依赖注入(Dependency Injection)和依赖查找(Dependency Lookup)。

依赖注入:Spring就是采用的依赖注入。组件不做定位查询,只是提供普通的Java方法,让容器去读取配置文件,决定依赖关系。容器全全负责组件的装配,它把符合依赖关系的对象通过JavaBean属性或者构造子传递给需要的对象。通过JavaBean属性注入依赖关系的做法叫做设置方法注入(Setter Inection);将依赖关系作为构造子参数传入的做法叫做构造子注入(Constructor Inection)。

所说的也就是Spring中的两种依赖注入的方式:setter方法注入、构造方法注入。

依赖查找:容器给组件提供回调接口和上下文环境。Ejb和Spring都可以使用这种方式获取Bean。

那么Spring是怎样实现控制反转、依赖注入的呢?

无非就是工厂模式+反射的综合运用。之前,我写过一篇文章:Java中通过dom4j读取配置文件实现抽象工厂+反射,简答模拟了Spring IOC的内部实现。基本思路实现:

1、将类之间的依赖关系配置在配置文件中,并遵循一定的约定,如:每一个bean标签中id为接口,class为对象实现;

2、然后使用dom4j读取该配置文件,并利用反射,得到相应的对象;

3、然后将得到的对象以键值对的形式保存在Map中,key为接口,value为该接口的实现类的相应对象。

这样,就通过工厂,完成了轻量级的对象创建,模拟了Spring IOC容器对Bean的创建过程。

当然,在Spring 的IOC的实现中,提供了要比这个更加复杂的实现。Spring IOC中,提供了两种实现方式:配置文件和注解。

拿Spring的setter方式注入举例,Spring通过约定大于配置,截取set方法名称,进行匹配注入,也就是Bean的定位查找,然后采用工厂的方式创建bean。

Spring通过ApplicationContext装在Bean的定义,并把它们组装起来。

模式实现的代码:

思路:其实就是把需要注入的类 通过注解或者配置xml的形式先配置好,key是接口 value是实现类。然后通过工厂模式把所有的bean放到容器中(通过classForName反射的形式找到bean)。当代码中需要的注入的时候 拿到该工厂实例,然后通过className,也是就容器的key,就可以找到容器的value,即实现类。

public class BeanFactory {
   
private static BeanFactory instance = new BeanFactory();

   
//系统缺省配置文件名称
   
private final String beansConfigFile = "beanConfiguration.xml";

   
//保存Dao相关对象
   
private Document doc;

   
private Map serviceMap = new HashMap();
   
private Map daoMap = new HashMap();

   
private BeanFactory() {
       
try {
           
//doc=new SAXReader().read(Thread.currentThread().getContextClassLoader().getResourceAsStream(beansConfigFile));
           
doc = new SAXReader().read(new File("src/main/resources/bean/beanConfiguration.xml"));
        }
catch (DocumentException e) {
            e.printStackTrace();
           
throw new RuntimeException();
        }
    }

   
public static BeanFactory getInstance() {
       
return instance;
    }

   
public synchronized Object getServiceObject(Class c) {
       
//如果存在相关对象实例,返回
       
if (serviceMap.containsKey(c.getName())) {
           
return serviceMap.get(c.getName());
        }
      
/* String xxx = "beans/service-class/service[@id="+c.getName()+"]";
            System.out.println(xxx);
            Element beanElt = (Element) doc.selectSingleNode(xxx);*/
       
Element beanElt = (Element) doc.selectSingleNode("//service[@id='"+c.getName()+"']");
        String className = beanElt.attributeValue(
"class");
        Object service =
null;

       
try {
            service = Class.forName(className).newInstance();

           
//将创建好的对象放到map中
           
serviceMap.put(c.getName(), service);
        }
catch (Exception e) {
           
throw new RuntimeException();
        }
       
return service;
    }

   
public static void main(String[] args) {
        ItemService itemService = (ItemService) BeanFactory.getInstance().getServiceObject(ItemService.
class);
        System.
out.println("itemService" + itemService);
    }
}

总结

本文没有讲解Spring在项目中的应用,也没有讲Spring的配置方式。本文围绕Spring IOC,谈了谈自己对IOC的理解,以及对IOC实现方式的梳理。帮助理解。

备注

本文大部分内容源于 https://blog.csdn.net/liu765023051/article/details/40260893

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值