随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算计算架构势在必行,需要一个治理系统确保架构有条不紊的演进
Spring makes it easy to create Java enterprise applications. It provides everything you need to embrace the Java language in an enterprise environment, with support for Groovy and Kotlin as alternative languages on the JVM, and with the flexibility to create many kinds of architectures depending on an application’s needs. As of Spring Framework 5.1, Spring requires JDK 8+ (Java SE 8+) and provides out-of-the-box support for JDK 11 LTS. Java SE 8 update 60 is suggested as the minimum patch release for Java 8, but it is generally recommended to use a recent patch release. Spring supports a wide range of application scenarios. In a large enterprise, applications often exist for a long time and have to run on a JDK and application server whose upgrade cycle is beyond developer control. Others may run as a single jar with the server embedded, possibly in a cloud environment. Yet others may be standalone applications (such as batch or integration workloads) that do not need a server. 翻译: Spring Framework 是一个轻量级的解决方案,可以一站式构建企业级应用。然而,Spring 是模块化的,允许你使用的你需要的部分,而不必把其余带进来。你可以在任何框架之上去使用IOC容器,但你也可以只使用 Hibernate 集成代码 或 JDBC 抽象层。Spring Framework 支持声明式事务管理,通过 RMI 或 Web 服务远程访问你的逻辑,并支持多种选择持久化你的数据。它提供了一个全功能的 MVC 框架,使您能够将 AOP 透明地集成到您的软件。 Spring 的设计是非侵入性的,也就是说你的领域逻辑代码一般对框架本身无依赖性。在你的集成层(如数据访问层),在数据访问技术和 Spring 的库一些依赖将存在。然而,它应该很容易从你的剩余代码中q分离这些依赖。 通俗的说: Spring是一个轻量级Java开发框架,最早有Rod Johnson创建,目的是为了解决企业级应用开发的业务逻辑层和其他各层的耦合问题。它是一个分层的JavaSE/JavaEE full-stack(一站式)轻量级开源框架,为开发Java应用程序提供全面的基础架构支持。Spring负责基础架构,因此Java开发者可以专注于应用程序的开发。 Spring最根本的使命是解决企业级应用开发的复杂性,即简化Java开发。 Spring可以做很多事情,它为企业级开发提供给了丰富的功能,但是这些功能的底层都依赖于它的两个核心特性,也就是依赖注入(dependency injection,DI)和面向切面编程(aspect-oriented programming,AOP)。
模块解释:
IoC is also known as dependency injection (DI). It is a process whereby objects define their dependencies (that is, the other objects they work with) only through constructor arguments, arguments to a factory method, or properties that are set on the object instance after it is constructed or returned from a factory method. The container then injects those dependencies when it creates the bean. This process is fundamentally the inverse (hence the name, Inversion of Control) of the bean itself controlling the instantiation or location of its dependencies by using direct construction of classes or a mechanism such as the Service Locator pattern. 翻译: IOC与大家熟知的依赖注入同理,. 这是一个通过依赖注入对象的过程 也就是说,它们所使用的对象,是通过构造函数参数,工厂方法的参数或这是从工厂方法的构造函数或返回值的对象实例设置的属性,然后容器在创建bean时注入这些需要的依赖。 这个过程相对普通创建对象的过程是反向的(因此称之为IoC),bean本身通过直接构造类来控制依赖关系的实例化或位置,或提供诸如服务定位器模式之类的机制。 通俗的说: IOC是一种设计思想,在Java开发中,将你设计好的对象交给容器控制,而不是显示地用代码进行对象的创建。 把创建和查找依赖对象的控制权交给 IoC 容器,由 IoC 容器进行注入、组合对象之间的关系。这样对象与对象之间是松耦合、功能可复用(减少对象的创建和内存消耗),使得程序的整个体系结构可维护性、灵活性、扩展性变高。 所谓IOC ,就简短一句话:对象由spring来创建、管理,装配!
你可以想象一下,假如当年设计鼠标键盘的人直接焊在电脑主板芯片上,没有鼠标就没有主板就废了启动不了了,鼠标出现问题导致主板出现问题,外设坏了想要拆开重新焊一个上去,这样的扩展性,可维护性多差!所以设计者提供一个接口出现可以接受不同的外设,并且让外设变成可插拔式的
每次鼠标坏了需要拆开电脑,重新焊一个鼠标上去,导致代码的变动更大,任何的变更都会造成系统的 BUG 的可能性
UserDaoImpl dao=new UserDaoImpl();
模块间要通过抽象接口隔离开,而不是通过具体的类强耦合起来
不要将鼠标(具体实现)直接焊在主板上,使用插口(抽象)连接;
现在接口有了,但是无法热插拔。 每次鼠标坏了需要关掉电脑才能更换(实现类换了还是需要去变更代码)
IUserDao dao=new UserDaoImpl();
具体实现依赖抽象,下层依赖上层。 分离
依赖倒置原则使鼠标、键盘和电脑成为独立的的互不相干的对象,当电脑(上层)没有鼠标可以正常启动但是鼠标(下层)没有电脑则一无是处 ,控制权就被反转了(IOC)。所以鼠标需要依赖USB(DI)才能使用。
之前——正转: 主板---焊接--->鼠标 电脑没有鼠标则无法启动
现在——反转: 电脑<---依赖---鼠标 引入DI可以实现IOC
IOC是DIP的设计原理,DI是IOC的具体实现
鼠标坏了很快就可以换一个,虽然会涉及短暂无法使用, 但是产生的变更极少。
IUserDao dao=从ioc种获取 涉及到的代码变更极少。
最 low 的方式:导入jar包 -- 配置xml
访问spring仓库 下载任意版本的 spring,只需要下载 dist.zip(包含了 docs schema)
一般的方式:maven + 注解 + xml
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.ydj</groupId> <artifactId>tuling-spring01</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.6.RELEASE</version> </dependency> </dependencies> </project>
package com.ydj.spring.hello; public class Hello { public void hello() { System.out.println("hello spring~"); } }
xml配置(hello.xml)
<?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 class="com.ydj.spring.hello.Hello" id="hello"> </bean> </beans>
测试类
public class TestHello { public static void main(String[] args) { ApplicationContext ioc = new ClassPathXmlApplicationContext("hello.xml"); Hello hello = ioc.getBean(Hello.class); hello.hello(); } }
结果输出
很多人把IOC和DI说成一个东西,笼统来说的话是没有问题的,但是本质上还是有所区别的,希望大家能够严谨一点,IOC和DI是从不同的角度描述的同一件事,IOC是从容器的角度描述,而DI是从应用程序的角度来描述,也可以这样说,IOC是依赖倒置原则的设计思想,而DI是具体的实现方式