Spring的工作原理
有时候面试的时候,面试官:会用Spring么?答:会,我们公司就用的Spring。面试官:Spring怎么进行控制反转的?切面怎么实现的?切面回用于哪一些场景?用到了哪一些设计模式?答:我知道怎么配,这个没研究过呀。面试官:...
知其然的人很多,但知其所以然,才能得心应手。让我们来研究一下Spring的原理:
一、Spring能用来做什么的?
简单来说:
第一,IOC控制反转。Spring就是一个容器,用来封装JavaBean的。
第二,AOP切面。切面利用动态代理实现面向切面编程。
二、解释一下这两个功能
2.1 图解一下IOC-网上搜刮
原来我们都是这么干的:
现在利用Spring的IOC可以这么来干:
Spring就是一个容器,用来封装JavaBean的。原来JavaBean都是自己new出来的,现在都交给Spring来进行管理。为什么需要交给Spring来管理,有什么好处么?这是因为随着业务量的增加,类也越来越多,代码之间的关联性也就是耦合性也越来越强,依赖和引用越来越多,维护起来就会相当困难。而Spring就可以充当这个中间人,你不需要关心其他对象是怎么创建的,只需要关心你自己的业务逻辑代码就可以了。你要对象,我就可以给你。这里就有了一个Spring的核心机制:IOC(Inversion of control)控制反转,就是用来干这个的。
2.2 图解一下AOP-网上搜刮
原来我们都是这么干的:
现在我们都是这么干的:
通过Spring来统一管理JavaBean可以说大大的解耦。同样,它还有另外一个功能,就是AOP(Aspect-OrientedProgramming)面向切面编程。简单来说:就是原来的业务在进行之前或者之后,都需要进行一些公共方法的调用或者处理,而这些代码都属于非业务层面的,比如:日志,性能监控,事务。将这些重复性的非业务逻辑代码抽取出来,使用动态代理技术将这些重复性代码织入到目标对象方法中,实现和原来一样的功能。这就是面向切面编程。
三、Spring预备知识
3.1 Spring体系结构
Spring框架提供了大约20个模块,可以根据应用程序要求来使用。
第一部分:核心容器:spring-core,spring-beans,spring-context,spring-context-support和spring-expression。
- Spring-core模块:提供了框架的基本组成部分,包括控制反转(Inversion of Control,IOC)和依赖注入(Dependency Injection,DI)功能。
- Spring-beans模块:提供了BeanFactory,是工厂模式的一个经典实现,Spring将管理对象称为Bean。
- Spring-context模块:建立在Core和Beans模块的基础之上,提供一个框架式的对象访问方式,是访问定义和配置的任何对象的媒介。ApplicationContext接口是Context模块的焦点。
- Spring-context-support模块:支持整合第三方库到Spring应用程序上下文,特别是用于高速缓存(EhCache、JCache)和任务调度(CommonJ、Quartz)的支持。
- Spring-expression模块:提供了强大的表达式语言去支持运行时查询和操作对象图。这是对JSP2.1规范中规定的统一表达式语言(Unified EL)的扩展。该语言支持设置和获取属性值、属性分配、方法调用、访问数组、集合和索引器的内容、逻辑和算术运算、变量命名以及从Spring的IOC容器中以名称检索对象。它还支持列表投影、选择以及常用的列表聚合。
第二部分:数据访问/集成
数据访问/集成层由JDBC、ORM、OXM、JMS和事务模块组成
- Spring-jdbc模块:提供了一个JDBC的抽象层,消除了烦琐的JDBC编码和数据库厂商特有的错误代码解析。
- Spring-orm模块:为流行的对象关系映射(Object-Relational Mapping)API提供集成层,包括JPA和Hibernate。使用Spring-orm模块可以将这些O/R映射框架与Spring提供的所有其他功能结合使用,例如声明式事务管理功能。
- Spring-oxm模块:提供了一个支持对象/XML映射的抽象层实现,例如JAXB、Castor、JiBX和XStream。
- Spring-jms模块(Java Messaging Service):指Java消息传递服务,包含用于生产和使用消息的功能。自Spring4.1以后,提供了与Spring-messaging模块的集成。
- Spring-tx模块(事务模块):支持用于实现特殊接口和所有POJO(普通Java对象)类的编程和声明式事务管理。
第三部分:web层
Web层由Spring-web、Spring-webmvc、Spring-websocket和Portlet模块组成。
- Spring-web模块:提供了基本的Web开发集成功能,例如多文件上传功能、使用Servlet监听器初始化一个IOC容器以及Web应用上下文。
- Spring-webmvc模块:也称为Web-Servlet模块,包含用于web应用程序的Spring MVC和REST Web Services实现。Spring MVC框架提供了领域模型代码和Web表单之间的清晰分离,并与Spring Framework的所有其他功能集成。
- Spring-websocket模块:Spring4.0以后新增的模块,它提供了WebSocket和SocketJS的实现。
- Portlet模块:类似于Servlet模块的功能,提供了Portlet环境下的MVC实现。
四、Spring Hello World实例
让我们编写一个HelloWorld案例,进入Spring的开始....
4.1 新建一个Maven工程--目录结构如下
4.2 引入Spring相关Jar包--pom文件
<?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.mcb.spring</groupId> <artifactId>Spring-HelloWorld</artifactId> <version>1.0-SNAPSHOT</version> <properties> <!--版本控制--> <spring-version>5.1.5.RELEASE</spring-version> </properties> <dependencies> <!--Spring相关Jar包--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring-version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${spring-version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring-version}</version> </dependency> <!--测试类Jar包--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies> </project>
4.3 编写Bean类
package com.mcb.spring.vo; public class HelloWorld { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public void sayHello(){ System.out.println(name+"说: Hello World"); } }
4.4 建立Beans.xml,将Bean类统一放在该文件中,供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="hello" class="com.mcb.spring.vo.HelloWorld"> <property name="name" value="Sum"/> </bean> </beans>
4.5 编写测试类TestSpring.java
import com.mcb.spring.vo.HelloWorld; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestSpring { @Test public void sayHello(){ ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml"); HelloWorld hello = (HelloWorld)context.getBean("hello"); hello.sayHello(); } }
4.6 打印结果
4.7 总结
这其实就是一个IOC控制反转的过程,将自己的类(HelloWorld.java)交个Spring进行管理,需要生成自己的对象的时候,就去Spring里面获取一个。对应代码:
HelloWorld hello = (HelloWorld)context.getBean("hello");
这就达到了控制反转的目的。
接下来会详细的介绍关于IOC和Aop等方面的知识!