注:本文来自于网络或者老师的总结资料,本人仅为摘录,想了解更多相关资料,可以关注:
http://blog.csdn.net/pu_xubo565599455
什么是spring框架?
Spring 是一个开源框架,是一种整合性的框架,是为了解决企业应用程序开发复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许您选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架。至03年spring框架发布以来到现在pring框架已经发展成JavaEE开发中的非常重要的一个框架。虽然还是有公司采用自己的方式来处理代码间的耦合问题,但是他们采用的方式依旧是Spring框架的基础,即:工厂模式与服务定位器模式等。
Spring是为企业应用开发提供的一个轻量级解决方案,包括:基于依赖注入的核心机制,基于AOP的声明式事务(联想下编程式事务),整合多种持久层技术的整合,整合很多优秀的WEB MVC框架等。Spring是致力于JavaEE应用各层的解决方案,而不是单单针对某一层。Spring贯穿表现层,业务层,持久层,但是Spring并不想取代那些已有的框架,而是以高度的开发性与它们无缝整合。
spring框架优点?
1、 低侵入式设计,代码的污染极低。
2、 Spring容器降低了业务对象替换的复杂性,提高了组件之间的解耦。
3、 Spring的AOP支持允许将一些通用任务如:安全,事务,日志等进行集中式处理,从而提供了更好的复用。
4、 Spring的ORM和DAO提供了与第三方持久化框架的良好整合,并简化了底层的数据库访问。
5、 Spring的高度开发性,并不强制应用完全依赖于Spring,开发者可自由选择Spring框架的部分或全部。
spring--IOC
IOC 即 Inversion Of Control,控制反转或者称之为依赖注入。IoC 不是一种技术,只是一种思想,一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合、更优良的程序。在工作中, JAVA实例的调用者通过new关键字来创建被调用者的JAVA实例,程序高度耦合,效率低下,真实的应用极少使用这种方式,一般是初学者最喜欢。有了IoC容器后,把创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,所以对象与对象之间是 松散耦合,这样也方便测试,利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。依赖注入是目前最优秀的解耦方式,依赖注入让Spring的Bean以配置文件组织在一起,而不是以硬编码的方式耦合在一起。
依赖注入通常有如下两种方式:
设值注入:IOC容器使用属性的Setter方法来注入被依赖的实例。
构造注入:IOC容器使用构造器来注入被依赖的实例。
设值注入:
设值注入是指IOC容器使用属性的Setter方法来注入被依赖的实例。这种注入方式简单、直观,因而在Spring的依赖注入里大量使用。
例外:
注意:Spring推荐面向接口编程,可以更好的让规范和实现分离,从而提供更好的解耦,对于一个JAVAEE应用,不管是DAO组件,还是业务逻辑组件,都应该先定义一个接口,该接口定义组件应该实现的功能,但是功能的实现则由其实现类提供。
我们先定义2个接口,如:
然后,分别实现其实现类,如:
最后,我们在applicationContext.xml的<beans></beans>中分别配置2个JAVABEAN实例,并配置其关系管理。如:
在配置文件中,Spring配置Bean实例通常会指定2个属性:
Id:指定该Bean的唯一标识,程序通过ID属性值来访问该BEAN实例。
Class:指定该BEAN的实现类,此处不可再用接口,必须使用实现类,Spring容器会使用XML解析器读取该属性值,并利用反射来创建该实现类的实例。
从上面的示例中,可以分析出,依赖注入以配置文件管理BEAN实例之间的耦合,让BEAN实例之间的耦合从代码层次分离出来,依赖注入是一种优秀的解耦方式。
分析得到SpringIOC容器的3个基本要点:
1、 应用程序的各组件面向接口编程。面向接口编程可以将各组件之间的耦合提示到接口层次,从而有利于项目后期的发展。
2、 应用程序的各组件不再由程序主动产生,而是由Spring容器来负责产生、并初始化。
3、 Spring采用配置文件、或Annotation来管理Bean的实现类、依赖关系,Spring容器则根据配置文件、利用反射来创建实例,并为之注入依赖关系。
构造注入:
前面我们介绍,通过setter方法为目标Bean注入依赖关系的方式,被称为设值注入:另外还有一种注入方式,这种方式在构造实例时,已经为其完成了依赖关系的初始化。这种利用构造器来设置依赖关系的方式,被称之为构造注入。
import com.lovo.beans.CardInfoT;
import com.lovo.dao.ICardDao;
import com.lovo.service.ICardService;
public class CardServiceImpl implements ICardService {
private ICardDao cardDaoImpl;
//默认的构造器,如果要设置有参构造,需要先显示执行无参构造
public CardServiceImpl(){
}
/**
* 构造注入所需的带参数的构造器
* @param cardDao
*/
public CardServiceImpl(ICardDao cardDao){
this.cardDaoImpl = cardDao;
}
public void saveCard(CardInfoT card) {
// TODO Auto-generated method stub
cardDaoImpl.saveCard(card);
}
}
applicationContext.xml中添加配置为:
<!-- 由spring容器创建实例化对象,并管理对象之间的关系 -->
<bean id="cardDaoImpl" class="com.lovo.dao.impl.CardDaoImpl"></bean>
<!-- spring构造注入-->
<bean id="cardServiceImpl" class="com.lovo.service.impl.CardServiceImpl">
<!-- 使用构造注入,为 cardServiceImpl实例注入cardDaoImpl实例-->
<constructor-arg ref="cardDaoImpl"></constructor-arg>
</bean>
两种注入方式的对比:
Spring同时支持两种依赖注入方式:设置注入和构造注入。两种注入方式,并没有绝对的好坏之分,只是适应的场景有所不同。
相比之下,设置注入具有如下优点:
1、 与传统的JavaBean的写法更相识,程序开发人员更容易理解、接受、通过setter方式设定依赖关系显得更加直观、自然。
2、 对于复杂的依赖关系,如果采用构造注入,会导致构造器过于臃肿,难以阅读。Spring在创建Bean实例时,需要同时实例化其依赖的全部实例,因而导致性能下降。而使用设置注入,则可以避免。
3、 尤其是在某些属性可选的情况下,多参数的构造器更加笨重。
当然,构造注入也不是绝对不如设值注入,某些特定的场合,构造更适合。构造也有如下优点:
1、 构造注入可以在构造器中决定依赖关系的注入顺序,优先依赖的优先注入,常常需要依赖于Datasource的注入。采用构造注入,可以在代码中清晰地决定注入顺序。
2、 对于依赖关系无须变化的Bean,构造注入更有用处。因为没有setter方法,所有的依赖关系全部在构造器中设定,因此,无须担心后续的代码对依赖关系产生破坏。
3、 依赖关系只能在构造器中设定,则只有组件的创建者才能改变组件的依赖关系。对组件的调用者而言,组件内部的依赖关系完全透明,更符合高内聚的原则。
建议采用以设值注入为主,构造注入为辅的注入策略。对于依赖关系无须变化的注入,尽量采用构造注入;而其他的依赖关系的注入,则考虑采用设值注入。
Spring 容器
Spring提供了两个核心接口:BeanFactory和ApplicationContext,其中applicationContext是BeanFactory的子接口。他们都可代表Spring容器,Spring容器是生成Bean实例的工厂,并管理容器中的Bean。Bean是Spring管理的基本单位,在基于Spring的JavaEE应用中,所有的组件都被当成Bean处理,包括数据源、Hibernate的SessionFactory、事务管理器等。
BeanFactory:
Spring容器最基本的接口就是BeanFactory,该接口负责配置、创建,管理Bean,它有一个子接口;AppcationContext,也被称为Spring上下文。Spring容器还负责管理Bean与Bean之间的依赖关系。
调用者只需使用getBean()方法即可获得指定Bean的引用,无须关心Bean的实例化过程。
BeanFactory有一个常见的实现类:org.springframework.beans.factory.xml.XmlBeanFactory类。
ApplicationContext是BeanFactory的子接口,对于大部分JavaEE应用而言,使用它作为Spring容器更方便。其常见实现类是:FileSystemXmlApplicationContext、ClassPathXmlApplicationContext和AnnotataionConfigApplicationContext。如果在web应用中使用Spring容器,通常有XmlWebApplicationContext、AnnotatioinConfigWebApplicationContext两个实现类。
大部分的JavaEE应用,可以在启动WEB应用时自动加载ApplicationContext实例,接受Spring管理的Bean无须知道ApplicationContext的存在,一样可以利用ApplicationContext的管理。对于独立的应用程序,也可通过如下方法来实例化BeanFactory。
1、
//搜索当前文件路径下的beans.xml文件创建Resource对象
InputStreamResource isr = new FileSystemResource(“beans.xml”);
//以Resource对象作为参数,创建BeanFactory对象
XmlBeanFactory factory = new XmlBeanFactory(isr);
或者采用:
2、
//搜索类加载路径,以类加载路径下的beans.xml文件创建Resource对象
ClassPathResource res = new ClassPathResource(“beans.xml”);
//以Resource对象作为参数,创建BeanFactory对象
XmlBeanFactory factory = new XmlBeanFactory(res);
如果需要同时加载多个XML配置文件,则可以采用如下方式:
//搜索CLASSPATH路径,以CLASSPATH路径下的applicationContext.xml、Bean.xml、Service.xml文件创建ApplicationContext
ApplicationContext appContext = new ClassPathXmlApplicaation(new String[“beans.xml”,”service.xml”]);
ApplicationContext:
大部分时候,我们都不会使用BeanFactory实例作为Spring 容器,而是使用ApplicationContext实例作为容器,因此我们也把Spring容器称为Spring上下文。ApplicationContext是BeanFactory接口的子接口,它增强了BeanFactory的功能。
ApplicationContext允许以声明式方式操作容器,无须手动创建它。可利用如ContextLoader的支持类,在WEB应用启动时自动创建ApplicationContext。当前,也可以采用编程方式创建ApplicationContext.
BeanFactory与ApplicationContext实例化容器中Bean的时机不同,前者等到程序需要Bean实例时才创建,而后者在容器创建ApplicationContext实例时,会预初始化容器中的全部Bean。
因为采用ApplicationContext作为Spring容器,创建容器时会同时创建容器中所有singleton作用域Bean,因此可能需要更多的系统开销。但一旦创建成功,应用后面的响应速度就会更快,因此,对于普通的JavaEE应用,推荐使用ApplicationContext作为Spring容器。
实际上Spring允许singleton作用的Bean指定lazy-init=”true”,该属性将改变singleton Bean实例的默认行为,强制取消该Bean实例预初始化,则该Bean将不会随着ApplicationContext启动而预实例化。