Spring IOC 慢慢总结中。。

来源:互联网 发布:java将图片转成base64 编辑:程序博客网 时间:2024/05/23 18:41


1.依赖反转


依赖反转原则:要依赖于抽象,不要依赖于具体。要针对接口编程,不要针对实现编程.
  抽象层次包含的是应用系统的业务逻辑和对整个系统来说重要的战略性决定,是必然性的体现,是相对稳定的。
  而具体层次则含有一些次要的与实现有关的算法和逻辑,以及战术性的决定,带有相当大的偶然性选择。具体层次的代码是会经常有变动的.
  具体层次应该依赖于抽象层次,使得具体层次实现的相关算法和逻辑是服务于抽象层次的。抽象层次决定如何以及何时调用具体层次.即好莱坞法则,不要找我,我会找你.
  从抽象层次依赖具体层次反转为具体层次依赖抽象层次是依赖反转的一中表现.

  模板方法是依赖反转原则的最典型的例子,在模板方法模式中,抽象类定义了业务逻辑的骨架,而将一些算法步骤延迟到子类中,使得子类可以在不改变业务逻辑骨架的情况下,重新定义算法中的某些步骤.

  要针对接口编程,不要针对实现编程:

  应当使用接口或抽象类进行变量类型的声明 参数类型的声明 方法返回类型的声明以及数据类型的转换等.不应当使用具体类.

  例如:List list = new ArrayList(); 使用接口List进行变量的声明,而不是ArrayList arrayList = new ArrayList();使用具体的ArrayList来声明.使用接口List声明可以轻易的改变成LinkedList作为链表形式的集合管理.而使用具体的ArrayList声明,则需要修改很多代码.

  在使用new ArrayList();也违背了依赖反转原则,它是对具体的编程,所以才出现了工厂模式来创建对象.spring的IOC容器能够帮助你完成对象的创建.

  要实现依赖反转原则会造成创建的类较多,比如工厂模式创建对象.另外,对于不使用具体类而是使用接口和抽象类来编程有时候是不合适的,比如该具体类不会在未来变化,就没有必要实现接口和抽象类来编程了.

2. Spring IOC容器

  在复杂的应用中,若干个类通过彼此的合作来实现业务逻辑,这使得每个对象都需要其他对象的引用。如果其他对象的引用由具体对象来完成,会导致代码的高度耦合。

  在面向对象系统中,对象封装了数据和对数据的处理方法,对象的依赖关系常常体现在对数据和方法的依赖上。这些依赖关系可以交给IOC容器来管理,并有IOC容器实现对依赖对象的注入,这样就从具体对象手中交出控制权,达到代码解耦的目的。依赖对象被反转给IOC容器控制,把控制权从具体业务对象转交给IOC容器,形成了依赖反转。

  在spring中,IOC容器是实现依赖反转的载体,它可以在对象生成或初始化时直接将数据注入到对象中,也可以通过将对象引用注入到对象数据域中或方法参数中。这种依赖注入是可以递归的,对象被一层层注入。并且它把对象的依赖关系有序地建立起来,简化了对象依赖关系地管理。

3.Spring IOC能帮助我们做什么?

 *.帮助创建对象和维护对象的依赖关系
 *.支持全方位的资源访问
 *.管理配置的系统环境及属性资源
 *.提供了属性的验证,数据绑定,属性编辑,类型转换等好用的功能。
 *.强大的Spring的EL表达式
 *.多种方式(如xml 注解 Groovy等)来配置bean定义
 *.如你精通springIOC你完全可以围绕着bean工厂开发属于自己的业务功能。

4.spring是如何管理bean的?

  开发者定义的bean信息比如xml,会被读取到中容器中的BeanDefition注册表中,这些BeanDefinition只是一些简单描述了bean的数据结构,在使用bean对象时,会先使用BeanDefinition创建bean对象,对于定义的单例则放入单例缓存中,对于原型bean每次都会创建,不会保存bean.工厂方法的bean对象,也是保存在另外的单例表中.

5.spring是如何管理bean依赖的?

 spring使用了几张hash表来管理依赖关系,比如一个bean名称对应多个依赖bean的名称,一个被依赖的bean名称对应多个依赖bean名称.用这些表来建立并缓存对象与对象的依赖关系.

6.spring是如何查询bean对象的?

   查询bean对象分为了使用类型和bean的名称查询,首先使用bean的名称查询,从别名系统中查询到转换后真实bean名称,通过真实的bean名称查询BeanDefinition注册表中的BeanDefinition,如果该BeanDefinition不存在,父工厂存在就去父工厂去查询.存在BeanDefinition则合并该BeanDefinition为一个RootBeanDefinition,查找该bean定义的依赖关系并递归的getBean创建bean依赖对象,然后缓存对应的依赖关系.当然这里找不到也会询问父工厂.处理完依赖关系就开始创建bean了,使用不同的作用域,创建bean的方式环境也不同,比如单例和原型创建.创建的过程是基本一样的.如果容器中存在缓存的单例bean,则直接取出,进行后续的初始化.否则,开始对bean实例化,实例化分三种,工厂bean的实例化,构造器实例化及自动构造器实例化.实例化后的对象使用BeanWapper进行包装.这时候如果bean是单例的,如果允许则可以提前暴露单例引用.开发者设置了自动注入方式(类型注入或name注入),则根据自动注入方法对依赖的bean属性自动注入到BeanWapper中。主动注入完成后,开始填充未注入的属性,将RootBeanDefinition中包含未注入的属性转换或编辑为bean对应的属性,最后填充BeanWapper对象的所有属性值.自此bean的实例化完成。进入初始化.在初始化的前会调用Aware接口及BeanPostProcessor接口的实现,你可以实现这些接口来扩展自己的功能.调用bean定义的初始化方法,及注册bean的销毁方法.最后判断是否是工厂方法实例,如果是则使用getObject返回对象的实例。否则则直接返回bean实例。当然getBean的过程是复杂的,我只是说了个大概。

7.Spring如何加载成BeanDefinition?

我们不说XML直接说注解的方式。
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
首先使用反射的方式读取AppConfig.class类上的注解,并把该类上的基本注解属性值放入到BeanDefinition中,作为bean的定义。当容器刷新时,会调用ConfigurationClassPostProcessor后置处理器,判断该AppConfig.class是否由@Configuration注解,如果有就把所有依赖的包含的bean定义注册到BeanDefinition中,
如果有@ComponentScan @Import @ImportResource等标签会加载Resource资源器进行资源加载,扫描出@Component组件定义的所有bean,并解析BeanDefition进行注册。定义了@Configuration的类是全模式的加载,它使用CBLIB的动态代理加载该类。注册完beanDefinition就可以放入工厂中供访问了。

8.spring中scope的作用域

  singleton: 当一个bean的作用域设置为singleton, 那么Spring IOC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例。
  prototype: 当一个bean的作用域设置为prototype,每一次请求(将其注入到另一个bean中,或者以程序的方式调用容器的 getBean()方法)都会产生一个新的bean实例,相当与一个new的操作,对于prototype作用域的bean,有一点非常重要,那就是Spring不能对一个prototype bean的整个生命周期负责,容器在初始化、配置、装饰或者是装配完一个prototype实例后,将它交给客户端,随后就对该prototype实例不闻不问了。
  request: 表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP request内有效。
  session作用域表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP session内有效.
  global session作用域类似于标准的HTTP Session作用域,不过它仅仅在基于portlet的web应用中才有意义。Portlet规范定义了全局Session的概念,它被所有构成某个 portlet web应用的各种不同的portlet所共享。在global session作用域中定义的bean被限定于全局portlet Session的生命周期范围内。如果你在web中使用global session作用域来标识bean,那么web会自动当成session类型来使用。

9.spring中使用的设计模式

 

所知道的:

  策略模式:定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
  模板方法:在一个方法中定义了一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
  工厂方法模式:定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。
  装饰器模式:动态的将责任附加到对象上。想要扩展功能,装饰者提供有别于继承的另一种选择。
 适配器模式:将一个类的接口,转换成客户期望的另一个接口。适配器让原有接口不兼容的类可以合作无间。
 观察者模式:定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
 代理模式:为另一个对象提供了一个替身或占位符以控制对这个对象的访问。
  原型模式:当创建给定的类的实例的过程很昂贵或很复杂时,就是用原型模式。
  迭代器模式:提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。
  访问者模式:当你想要为一个对象的组合增加新的能力,且封装并不重要时,就使用访问者模式。
 
0 0
原创粉丝点击