Spring是一个开源的,轻量级Java开发框架; 其核心特性是能够用于开发任何 Java 应用程序,Spring 框架的目标是使 JavaEE应用程序的开发变得更加容易,核心概念是IOC和AOP;这也是学习Spring的重点所在;java
Spring不是针对某个具体功能,具体层级的框架; 也就是说之前该有的系统分层,结构,设计模式都不须要改变,而是让Spring加入进来,让开发变得更简单; 记住Spring并不想取代某个已存在的框架,反而可让各个框架的配合使用难度下降,它就像502胶水,可快速的在系统中集成其余优秀的框架python
Spring也因其特性而得名,寓意为JavaEE开发的春天来了spring
咱们常常会看到Spring替代EJB,或Spring与EJB对比等等相关文章,那么二者之间到底有什么关系呢?express
以前的课程中咱们知道,EJB是JavaEE规范中的一个,主要用于开发分布式应用程序编程
从概念上来看:设计模式
因此这个问题实际上是在问Spring(框架)和JavaEE(规范)的对比,而由于二者不是同一种概念,因此没法直接对比,那到底在对比啥? 不能在卖关子了;服务器
问题应该是:使用Spring开发和彻底按照JavaEE规范开发应用程序的区别app
这个问题应该由Spring的做者Rod Johnson来回答:框架
#Rod Johnson在2002年编写的《Expert One-to-One J2EE Design and Development》一书,Rod 在本书中对J2EE正统框架臃肿、低效、脱离现实的种种学院派作法提出了质疑,并以此书为指导思想,编写了interface21框架,也就是后来的Spring。
的确推出Spring推出就是民间开发者对官方规范的中不足的地方提出的质疑以及作出的强力回应,在早期阶段,开发者们经历了拥抱到抛弃,从最先的JavaEE这一官方协议推出后,开发者们很是拥戴,毕竟是官方嘛,后来慢慢发现这堆复杂,晦涩,学习成本极高的规范是多么的臃肿不堪,就像你为了打一只小鸟而搬出了战斗机;就在这时候Spring框架应运而生,因其轻量级,使用简单很快受到了你们的喜好;分布式
好在官方也意识到了问题,因而在EJB3.0作出了大量的改进,并借鉴了Spring中一些很是优秀的特性,但如日中天的Spring好像并无受到太大的影响,你们一如既往的喜好Spring;
EJB容器IOC容器
另外一方面由于Spring具有ICO容器,能够帮助咱们管理Bean,而EJB的须要放在EJB容器中才能使用其提供的功能; EJB主要用于提供分布式能力,而IOC容器是帮助咱们更好的解耦
控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,能够用来减低计算机代码之间的耦合度。
将本来由程序实现的一部分逻辑反过来交给系统来完成就称之为控制反转
其中最多见的方式叫作依赖注入(Dependency Injection,简称DI)经过控制反转,能够说,依赖被注入到对象中。
依赖注入是实现控制反转的一种手段;
举个例子:本身搭配组装机,须要考虑各类部件的兼容性,和本身的性能的要求,如CPU,内存,显卡等等;但有了专门的组装机服务器商(IOC容器),你只要告诉他你的基本需求,好比,要一台吃鸡电脑,剩下的就交给服务商去作了;
大多数应用程序,都是有不少不一样对象彼此合做来完成业务逻辑,这致使在获取一个合做对象时,必须显示的去new一个对象,这将就致使代码高度耦合而且难以维护和调试。像下面这样
public class Controller { @Test public void doGet() throws Exception { //这里须要依赖Service层 UserService service = new UserService("参数1","参数2"); }
当须要更换其余业务逻辑实现类时就不得不修改源代码,而且若Service的实例化须要参数时,Controller层就不得不为其提供必要的参数,这反映了Controller与Service的耦合度是较高的
core,提供了框架基础组成部分,包括IoC和DI;
beans,提供了BeanFactory,是工厂模式的实现,提供普通对象和单例对象的获取
context,创建在core和bean的基础上,可将其余库集成到Spring中
SpEL(spring-expression Language)提供了表达式语言支持,其对JSP中的EL进行了扩展
AOP,提供了面向切面编程实现
Aspects 模块提供了与 AspectJ 的集成,是一个功能强大且成熟的AOP框架
Instrumentation 用于代理监控JVM运行的JAVA程序,对字节码修改以实现AOP
Messaging 模块为 STOMP 提供了支持,主要处理来自 WebSocket 客户端的 STOMP 信息
强调:
Spring是模块化的,彻底能够根据须要来导入所需模块
先来看一个不使用Spring时,控制和业务逻辑层交互的案例,控制器:
public class Controller { @Test public void doGet() throws Exception { //这里须要依赖Service层 //v1 直接写 //UserService service = new UserService(); //v2 面向接口 某个实现类 //UserService service = new UserServiceImpl(); //要跟换其余实现类时 违反了OCP(开放封闭)原则 //UserService service = new UserServiceImpl2(); //v3 为避免修改源代码扩展 加入工厂 ServiceFactory factory = new ServiceFactory(); UserService service = factory.getService(); //调用业务方法 service.userLogin("jerry","admin"); } }
工厂:
public class ServiceFactory { public UserService getService() throws Exception { //此处id应配置在xml中 String id = "UserServiceImpl"; if (id.equals("UserServiceImpl")){ return new UserServiceImpl(); }else if(id.equals("UserServiceImpl2")){ return new UserServiceImpl2(); } throw new Exception("id:"+id + "not register"); } }
使用工厂模式能够进一步下降组件间的耦合度,但在完整的系统中有不少组件,须要不少个工厂,使程序变得复杂,臃肿;
Spring将自身设计为一个大型对象工厂,负责管理系统中设计到的全部对象,并利用DI处理对象的依赖关系,当对象A须要对象B时再也不本身建立而是从Spring中获取
叫作开放封闭原则,是应用程序开发中应该遵循的一个原则
open:对扩展开放
close:对修改源代码封闭
其目的是要在不修改源代码的状况下对已有功能进行扩展
1.建立Maven项目
2.添加依赖
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.2.RELEASE</version> </dependency> <!-- Maven会自动下载全部Spring核心容器和aop的依赖-->
3.建立配置文件
一般名为:applicationContext.xml
固然你也能够修改放在resources
下
<?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 https://www.springframework.org/schema/beans/spring-beans.xsd"> <!--使用bean标签,建立Service对象,并交给容器来管理--> <bean id="UserService1" class="com.yyh.serviceimpl.UserServiceImpl"/> <bean id="UserService2" class="com.yyh.serviceimpl.UserServiceImpl2"/> </beans>
名称空间声明可到官网查找,或是直接在jar中查找,如:
4.从Spring中获取须要的对象
@Test public void doGetUseSpring() throws Exception { //建立应用上下文 指定配置文件 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); //从Spring中获取所需对象 UserService userService = (UserService)context.getBean("UserService2"); //调用业务逻辑方法 userService.userLogin("jerry","admin"); }
不难看出此时的Spring就是一个对象工厂,但这仅仅Spring的基础功能
容器能够理解为存放对象的地方,固然不只仅是存储,还有对象的管理,包括-建立-销毁-装配; 这样本来程序要作的事情交给了Spring,因此这属于IOC,称之为IOC容器;
Spring有两个接口ApplicationContext是BeanFactory的子接口。它们均可以做为Spring的容器;
BeanFactory做为顶级接口主要面向于Spring框架自己,仅提供了基础基本的容器功能如DI
ApplicationContext,是BeanFactory的子接口,意味着功能比BeanFactory更多,诸如国际化,注解配置,XML配置等等
BeanFactory采起的懒加载的方式,在获取对象时才会实例化
ApplicationContext会在工厂初始化时当即实例化对象
ApplicationContext的两个实现类区别:
ClassPath表示从类路径中获取配置文件
FileSystem表示从文件系统获取配置文件