编辑推荐: |
文章主要介绍展示了一个基于SSH,B/S结构的单体Java应用的搭建过程,一站式 Spring为企业级应用提供了一站式的解决方案,希望对您的学习有所帮助。 本文来自于csdn,由火龙果软件Delores编辑、推荐。 |
在学习Spring之前首先来看一张图,通过对于这张图的理解进入我们需要学习的Java框架Spring。
这张图上展示了一个基于SSH,B/S结构的单体Java应用的搭建过程,首先通过浏览器进入到Filter拦截器,进入到Structs2,通过Service层进入到Hibernate,从而进行数据库,经过而这整个过程都是由SpringIOC容器控制。这张图向我们展示了一个比较基础的JavaWeb的搭建过程。万变不离其宗,后来使用的SSM框架,现在比较火的微服务架构,都离不开这张图上展示的内容所提供给大家的思想。每个框架的实现宗旨都是一样的,只不过实现的方式不一样。其实在这个框架最初的时候应该是以JSP+Servlet比较常用,后来为了解决前后端分离的问题,降低耦合度。将这些功能结构按照MVC分层实现。个人的理解MVC为一种程序设计思想,可以很多场合使用到,从Web、后端、移动端在很多的场合下将MVC作为一种程序设计思想应该是比较恰当的,对于MVC的设计思想这里不做过多的说明。下面我们就来学习Spring框架的深入理解,既然说到要深入理解那么就应该先来个简单一点的为引导进入到深处。
先简单的解释一下Spring是什么东西。首先Spring是一个开源的框架,是由Apache公司开发的,Spring是为了简化企业级应用开发而生的(也就是上面那张图上所展示的内容),使用Spring可以使简单的JavaBean实现以前只有EJB(企业级JavaBean)才能实现的功能。Spring是一个IOC(DI)和AOP容器框架
IOC:控制反转(依赖注入)
AOP:面向切面编程
具体的说Spring的特点有以下几点
-轻量级:不是说Spring的代码少,而是Spring是非侵入式的,也就是说引入Spring框架并不会对原来的应用产生影响,也可以理解为基于Spring开发的应用中对象可以不依赖与Spring的API(应用程序接口)
-依赖注入(DI)Dependency Injection
-面向切面编程(AOP)Aspect oriented programming
-容器 从上面图中我们可以看出很多的框架,例如Struts2、hibernate、mybatis等框架都是可以被装入Spring的容器中。这个容器包含并且管理应用对象的生命周期。
-框架 Spring 实现了简单的组件的配合组成一个复杂的应用,在Spring中可以使用XML和Java注解组合这些对象。
-一站式 Spring为企业级应用提供了一站式的解决方案,在IOC和AOP基础上可以整合各种的企业应用的开源的框架和优秀的第三方类库(实际想Spring自身也是提供了SpringMVC展现层技术和SpringJDBC数据持久化技术)但是由于Spring提供了一站式的解决方案,才会有那么的开源技术通过Spring框架整合形成比Spring原生更加优秀的解决方案
例如图中Spring提供了Core Container核心容器、DataAccess/Integration数据持久化、Web等的支持。
介绍完Spring的主要内容之后,我们就来看看Spring的开发环境的搭建,下图中展示了Spring框架所需要的基本jar包。这里图中展示的是Spring4的Jar包,实际开发中可以更具实际情况选择自己的版本。
开发工具由自己选择这里我所用的开发工具是IntelliJ IDEA 开发工具,构建的Spring工程目录如下图所示
这里介绍一个Spring配置文件的位置,一个典型的Spring项目需要在创建一个或者多个Bean的配置文件,这些配置文件用于在SpringIOC容器里配置Bean,Beean的配置文件通常情况下放在classpath路径下,当然也可以放在其它目录下。在开中经常放置的位置就是类路径下,如上图中所示。
创建一个Spring项目
导入jar包
创建实例对象
package com.nihui.spring.bean; import java.util.ArrayList; public class World { private String name; public void hello(){ System.out.println ("hello world " +name ); } public String getName() { return name; } public void setName (String name) { this.name = name; } }
配置Spring配置文件
< xml version="1.0" encoding="UTF-8" > <beans xmlns= "http://www.springframework.org/schema/beans" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation= "http://www.springframework.org/schema/beans http://www.springframework.org /schema/beans/spring-beans.xsd"> <bean id="World" class="com.nihui.spring.bean.World"> <property name="name" value="Spring"> </property> </bean> </beans>
创建程序启动类
package com.nihui.spring.bean; import org.springframework. context.ApplicationContext; import org.springframework.context.support. ClassPathXmlApplicationContext; public class Main { public static void main (String[] args) { //使用Spring框架之后这些操作 都可以交给Spring来完成 //1.创建Spring的IOC容器 ApplicationContext context = new ClassPathXmlApplicationContext ("applicationContext.xml"); //2.从IOC容器中获取到Bean的示例 World helloWorld = (World) context.getBean("World"); //3.进行方法的调用
helloWorld.hello();
}
}
完成以上的操作就使用Spring创建一个简单的Spring的项目,同样也是Spring最简单的使用场景。在实际开发中Spring的应用还是比较复杂的,首先最简单的方式来学习。
接下来介绍的是Spring配置文件,我们都知道Spring框架在使用的时候并不是我们例子中所体现的那个样子,而是通过配置文件的方式将各种各样的资源整合在一起,这个概念在之前也有提到过,所以在Spring开发中配置文件的编写也是比较重要的。
IOC和DI
首先简单的说一下IOC(控制反转),IOC的基本思想就是反转资源获取的方向,传统的资源查找方式要求组件向容器发起请求,然后获取到所要请求的资源作为回应,应用了IOC之后,则是容器主动的将资源推送给它所管理的组件,组件只需要做的是选择一种合适的方式来接受资源,这种行为就被看做是组件被动的查找资源。DI(依赖注入),这个是对IOC的另一种表达方式,也就是组件以一些预先定义好的方式(例如setter方法)接受来自容器的资源注入,相对于IOC而言,这种表述更直接。
如图,传统情况下一个容器中有两个类A和B,要想把A类作为B类的属性需要先创建一个A类的对象,然后创建一个B类的对象,通过对象的setter方法将这个属性赋给B类。而使用IOC容器,则是容器就把这个注入关系给完成了,我们只需要通过B类的getter方法获取到对象的属性就可以了,达到了在代码上的解耦合。
在IOC之前需要解决的几个问题
-分离接口的实现
需求:生成HTML或PDF格式的不同类型报表
如图需要先定义一个ReportService类,而两种实现方式需要实现同一个接口,而且接口和两个类都需要继承ReportService类。并没有实现解耦合,组件类之间的耦合度还是很高。这个就引出了第二种方式
-采用工厂设计模式
这里看出,ReportService与功能类之间的耦合度降低了,但是与工厂类之间的耦合有所增加,也没有很好的解决组件之间的耦合问题。这种情况下,需要扩展新功能的时候需要改动的类还是比较多的,各个功能类之间的影响还是比较大的。
-采用控制反转
这里我们可以看出与工厂设计模式相比较,ReportService与功能类之间的耦合度有所降低,但是相比较之下,在实现不同的功能的时候只需要扩展ReportGenerator接口就可以以了。Container类直接作为一个“中间人”调和了组件之间的关系。
这里我们可以来了解一下Spring框架的底层实现原理,这里我们可以看到控制反转与工厂方法模式的最大的差异就是少了一个工厂类的集成,而是通过容器将这个依赖注入到了各个类中,不是通过工厂来获取。其实在Spring底层实现中就是通过工厂模式实现了功能类之间的解耦合。使用工厂模式获取到对应的配置文件中的内容,利用反射机制获取到配置文件中定义的类的实例对象,然后通过工厂类返回。这样看来Spring容器所做的事情就是将这些东西进行了一个简单的封装。主要使用到的原理就是Java提供的反射机制,当然了底层实现并不仅仅使用到的这个技术应该是多种技术的结合。才能诞生Spring这样一个优秀的框架。
那么简单的说完底层的原理我们就来了解一下这个配置文件到底应该该怎么使用。在Java中我们使用dom4j来解析XML配置文件,当然Spring还提供了注解方式,这里我们先介绍一下XML配置文件对于Bean对象的配置
Bean配置方式,通过全类名(主要用户反射可以找到对应的类)、通过工厂方法(静态工厂方法&实例工厂方法)、FactoryBean。在SpringIOC容器有两种,一种是BeanFactory一种是ApplicationContext,这里需要说明一下BeanFactory和FactoryBean并不是我写错了而是一个是面向开发者,一个面向Spring底层。那么,哪一个是面向开发者,哪一个是面向Spring底层呢?在上面我们说过Spring框架的底层是通过工厂模式实现的所以说FactoryBean是为了底层提供不同的“工厂”,而BeanFactory是面向开发者,但是这个我们并不会经常的使用,这个面向开发者应该定义为Spring开发者而不是应用开发者。作为应用开发者经常使用到的就是ApplicationContext。
依赖注入的方式有两种一种是属性注入,一种是构造器注入。
<bean id="World" class= "com.nihui.spring.bean.World"> <property name="name" value="Spring"></property> </bean>
在XML文件中通过Bean节点的方式,来配置Bean,而这个解析规则是由Spring规定好的。
id:Bean名字,唯一标识,若id没有指定Spring将自动将权限定性为类名作为Bean的名字,id可以指定多个名字,名字之间通过逗号、分号或者空格分隔。
Spring容器中读入Bean配置建立一个Bean之前,必须对它进行实例化,只有在容器实例化之后才可以从IOC容器中获取的Bean对象的实例并使用。这里就提到了之前的内容,这里我们对这里两个实例化IOC容器的方式做官方的理解
BeanFactory:IOC容器的基本实现,也就是之前提到的Spring底层实现,可以理解为Spring的“基础设施”,面向Spring本身;也就是之前提到的Spring的开发者,
ApplicationContext:提供了更多的高级特性,是BeanFactory的子接口,面向Spring应用开发者,但是几乎所有的应用场合都是直接使用ApplicationContext而不是使用底层的BeanFactory。但是无论哪一种实现方式,配置文件都是相同的。
这里详细介绍一下ApplicationContext
ApplicationContext有两个主要的实现类,ClassPathXmlApplicationContext:从类路径下加载配置文件;FileSystemXmlApplicationContext:从文件系统中加载配置文件。ConfigurationApplication扩展与ApplicationContext,新增加的两个主要方法,refresh()和close(),让ApplicationContext具有启动、刷新和关闭上下文的能力。
ApplicationContext在初始化上下文时就实例化所有的单例Bean。
WebApplicationContext是专门为WEB应用而准备,它允许从相对于WEB的根目录的路径中完成初始化工作。