# Spring ## 什么是Spring Spring是一款开源的轻量级Java开发框架,旨在提高开发人员的开发效率以及系统的可维护性 一般说的Spring框架指的是SpringFrameword,是很多模块的集合,使用这些模块可以很方便的协助我们进行开发,核心思想就是不重新造轮子,开箱即用 ## 重要的Spring模块  上图对应4.x的版本,5.x中web模块Portlet已废弃,同步增加了用于异步响应式的WebFlux组件 - Spring Data Access/Integration:其中五个模块组成 - spring-jdbc:提供了对数据库访问的抽象JDBC,不同的数据库都有字节独立的API用于操作本数据库,而Java程序只需要和JDBC API交互,就完成了对数据库的操作,屏蔽了不同数据库的影响 - spring-transactions(又名spring-tx):提供对事务的支持 - spring-orm:提供对ORM框架的支持:在关系型数据库和对象之间 做一个映射 - spring-oxm:提供对OXM框架的支持:将java对象和XML数据之间转换 - spring-jms:Java消息服务 - Spring Web:由四模块组成 - spring-web:对web功能的实现提供一些最基础的支持 - spring-webmvc:提供对Spring MVC的实现 - spring-websocket:提供了对webSocket的支持,可以让客户端与服务端双向通信 - spring-webflux:提供对WebFlux的支持,与SpringMVC不同,它不需要Servlet API,是完全异步的 - Spring Core:核心模块,所有的功能基本都依赖于该类库,主要提供IoC依赖注入功能的支持 - Spring Aspects:为AspectJ的集成提供支持 - Spring AOP:提供了面向切面的编程实现 - Spring Test:对常用测试框架的支持 ## Spring IOC & DI ### IOC IoC,即 “控制反转”,是一种思想,是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。在开发中, IoC 意味着你设计好的对象交给容器控制,而不是使用传统的方式,在对象内部直接控制。 - 控制:指的是**对象创建(实例化、管理)的权利**,在传统设计中,通常直接在对象内部通过new的方式创建对象,是主动创建依赖对象;而io是指使用一个专门的容器来创建这些对象,即由IoC容器控制对象创建。即ioc容器控制了对象,控制了外部资源的获取 - 反转:指的是**控制权交给外部环境(Spring框架,Ioc容器)**,正转是由我们自己在程序中主动控制去获取依赖对象;反转是由容器来帮忙创建及注入依赖对象。因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖,所以反转。依赖对象的获取被反转了。 传统应用程序都是由我们在类内部主动创建依赖对象,从而导致类与类之间高耦合,难于测试; **有了 IoC 容器后,把创建和查找依赖对象的控制权交给了容器,由容器注入组合对象,所以对象之间是松散耦合。** 这样也便于测试,利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。被动的等待 IoC 容器来创建并注入它所需的资源了。 在Spring中,IoC容器是Spring用来实现IoC的载体,实际上是个Map(key,value),Map中存放各种对象 ### DI 即依赖注入,是组件之间依赖关系由容器在运行期决定,形象来说,即由容器动态的将某个依赖关系注入组件之中。依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统搭建一个灵活,可扩展的平台。 DI的关键是:"谁依赖谁,为什么需要依赖;谁注入谁,注入的什么" - 谁依赖谁:应用程序依赖于IOC容器 - 为什么依赖:应用程序需要IOC容器来提供对象需要的外部资源; - 谁注入谁:IOC容器注入应用程序某个对象,应用程序依赖的对象 - 注入了什么:就是注入某个对象所需要的外部资源(包括对象,资源,常量数据) ## Spring AOP AOP(Aspect Oriented Programming),即面向切面编程,可以说是OOP(Object Oriented Programming,面向对象编程)的补充和完善。OOP引入封装、继承、多态等概念来建立一种对象层次结构,用于模拟公共行为的一个集合。不过OOP允许开发者定义纵向的关系,但并不适合定义横向的关系,例如**日志功能**。日志代码往往横向地散布在所有对象层次中,而与它对应的对象的核心功能毫无关系对于其他类型的代码,如安全性、异常处理和透明的持续性也都是如此,这种散布在各处的无关的代码被称为**横切**(cross cutting),在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。 - 切:横切逻辑,原有业务逻辑代码不动,只能操作横切逻辑的代码 - 面:横切逻辑往往需要影响多个方法,每个方法如果一个点,很多个方法点构成了面 使用"横切"技术,AOP把软件系统分为两个部分:**核心关注点**和**横切关注点**。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处基本相似,比如权限认证、日志、事物。AOP的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。 实现 AOP 的技术的实现主要采用**动态代理技术**,利用截取消息的方式,在不改变原有业务逻辑的情况下,增强横切逻辑代码,根本上解耦合,避免横切逻辑代码重复。 ## Spring Bean ### 什么是bean bean代指**被IoC容器所管理的对象**,我们需要通过配置元数据来告诉容器帮助我们管理哪些对象,这个元数据可以是xml文件、注解或者java配置类 ### bean的作用域有哪些 - singleton:唯一bean实例,Spring中的bean默认都是单例的,对单例设计模式的应用 - prototype:每次请求都会创建一个新的bean实例 - request:每一次http请求都会产生一个新的bean,该bean仅在当前http request内有效 - session:每一次来自新session的http请求都会产生一个新的bean,该bean仅在当前http session内有效 - global-session:全局session作用域,仅仅在基于portlet的web应用中才有意义,spring5取消。portlet是能够生成语义代码片段的小型web插件,基于portlet容器,可以像servlet一样处理http请求,但是每个portlet都有不同的会话 ### 如果配置bean作用域 ~~~java //xml方式 <bean id="..." class="..." scope="singleton"></bean> //注解方式 @Bean @Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE) public Person personPrototype(){ return new Person; } ~~~ ### 单例bean的线程安全问题 当多线程操作同一个对象的时候存在资源竞争,不过大部分bean实际都是无实例变量的如Dao,Service,常见解决办法有两种 1. 在bean中尽量避免定义可变的成员变量 2. 在类中定义一个ThreadLocal成员变量,将需要的可变遍历保存在ThreadLocal中 ### 将一个类声明为bean的注解有哪些 我们一般使用`@Autowired`注解自动装配的bean,要想把类标识成可用于`@Autowired`注解自动装配的bean类,可以用以下注解实现 - `@component`:通用的注解,可标注任意类为Spring组件。 - `@Repository`:对应持久层即Dao层,主要用于数据库相关操作 - `@Service`:对应服务层,主要涉及一些复杂的逻辑,需要用到Dao层 - `@Controller`:对应SpringMvc控制层,接受用户请求并调用Service层返回数据给前端页面 ### `@Component`和``@Bean`的区别是什么 - `@Component`注解作用于类,而`@bean`作用于方法 - `@Component`通常是通过类路径扫描来自动装配到容器中,`@Bean`通常是我们在标有该注解的方法中定义产生这个bean,`@bean`告诉Spring这是某个类的实例,当我需要的时候取拿取 - `@bean`的自定义性更强,很多地方只能通过`@bean`注解来注册bean,比如引用第三方库中的类需要装配时,只能通过`@bean`实现 ### bean的生命周期 - Bean容器找到配置文件中的SpringBean的定义,利用JavaReflection Api 创建一个Bean的实例 - 如果有一些属性值的话,调用set()方法设置一些属性值 - 如果实现了其他*.Aware接口,就调用对应的方法,(让bean获取自己在容器中的名字等) - 如果实现了一些接口或加载了一些对象,执行相关的方法 - 当要销毁Bean时,如果实现了destroy方法,或配置文件中定义了destroy-method属性,执行指定的方法  ## Spring实例化对象的方式 - 无参构造方法实例化 - 根据id获取配置文件中的bean对象,必须存在空的构造方法 - 当各个bean的业务逻辑相互比较独立时,或者与外界关联较少时使用 - 工厂静态方法实例化 - 通过反射调用工厂类的静态工厂方法,将其返回值作为Bean实例,在工厂中实例化其中bean对象 - 可以统一管理各个bean的创建,各个bean在创建之前需要统一的初始化处理时使用 - 实例化工厂实现 - 实例化工厂后实例化工厂中指定方法 - 工厂方法也可以作为bean的控制,集成其他框架bean时的管理方法,能够使bean和工厂的角色互换 一般用第一种 ## Spring MVC ### MVC是什么 mvc是模型(model),视图(view),控制器(controller)的简写,核心思想是通过将业务逻辑,数据,显示分离来组织代码 springMVC框架将后台分为Service层(处理业务)、Dao(数据库操作)、Entity(实体类)、Controller(控制层,返回数据给前台页面) ### SpringMVC工作原理  流程说明: 1. 客户端发送请求,请求到DispatcherServlet(前端控制器) 2. 前端控制器根据请求信息调用HandLerMapping(映射处理器),解析请求对应的Handler(处理器) 3. 解析到对应的Handler后,开始由HandlerAdapter适配器处理请求 4. 这一步会根据第三步找到的Handler来调用真正的处理器开始处理请求,并处理相应的业务逻辑。这层是Controller控制器 5. 处理器处理完后,会返回一个ModelAndView对象,Model是返回的数据对象,view是逻辑上的view 6. ViewResolver会根据逻辑View找到实际的view 7. 前端控制器把返回的Model传给View(视图渲染) 8. 把View返回给请求者 ## Spring框架中的设计模式 - 工厂模式:通过BeanFactory、ApplicationContext创建bean对象 - 代理模式:AOP功能的实现 - 单例模式:Bean默认是单例 - 模板方法模式:JdbcTemplate、hibernateTemplate等以Template结尾的数据库操作的类,就用到了模板模式 - 包装器设计模式:不同客户在访问中根据需要会去访问不同的数据库,可以根据需求动态切换不同的数据源 - 观察者模式:事件驱动模式就是经典的观察者模式的应用 - 适配器模式:AOP的增强或通知(advice)用到了适配器模式,SpringMVC也是用到了适配器模式适配Controller ## Spring常用注解 ### 核心 - @SpringBootApplication:创建SpringBoot项目后会默认加在主类上,是项目的基石,可以看作下面三个注解的集合 - @EnableAutoConfiguration:启动SpringBoot的自动配置机制 - @ComponentScan:扫描被@Component(@Service,@Controller)注解的bean,会默认扫描该类所在包下所有类 - @Configuration:允许在Spring上下文中注册额外的bean或导入其他配置类 ### Spring Bean相关 - @Autowired:自动导入对象到类中,被注入的类同样要被Spring容器管理, - @Component:通用的注解,可标注任意类为Spring组件。 - @Repository:对应持久层即Dao层,主要用于数据库相关操作 - @Service:对应服务层,主要涉及一些复杂的逻辑,需要用到Dao层 - @Controller:对应SpringMVC控制层,主要用于接受用户请求并调用Service层返回数据给前端页面 - **@RestController**:将函数的返回值直接填入http响应体,返回Json或xml形式的数据,是Rest风格的控制器 - @Scope:声明SpringBoot作用域,参数可以有以下四种 1. singleton:唯一bean实例,Spring中的bean默认是单例的 2. prototype:每次请求都会创建一个新的bean实例 3. request:每次http请求都会产生新的bean,只在当前http请求内有效 4. session:每次http请求都会产生新的bean,只在当前http session内有效 ### 处理HTTP相关 ## Spring事务 ## MyBatis 中使用 # {}和 $ {}书写占位符有什么区别 ? ①#将传入的数据都当成一个字符串,会对传入的数据自动加上引号 ② $将传入的数据直接显示生成在 SQL 中。 注意:使用 $ 占位符可能会导致 SQL 注射攻击,能用#的地方就不要使用 $ ,写 order by 子句的时候应该用$而不是#。 ## Mybatis的好处 ? ①把Sql语句从Java中独立出来。 ②封装了底层的JDBC,API的调用,并且能够将结果集自动转换成JavaBean对象,简化了Java数据库编程的重复工作。 ③自己编写Sql语句,更加的灵活。 ④入参无需用对象封装(或者map封装),使用@Param注解。 ## SpringBoot ### 什么是 Spring Boot? Spring Boot 是 Spring 开源组织下的子项目,是 Spring 组件一站式解决方案,主要是简化了使用 Spring 的难度,简省了繁重的配置,提供了各种启动器,开发者能快速上手。 ### Spring Boot 有哪些优点? Spring Boot 主要有如下优点: 容易上手,提升开发效率,为 Spring 开发提供一个更快、更广泛的入门体验。 开箱即用,远离繁琐的配置。 提供了一系列大型项目通用的非业务性功能,例如:内嵌服务器、安全管理、运行数据监控、运行状况检查和外部化配置等。 没有代码生成,也不需要XML配置。 避免大量的 Maven 导入和各种版本冲突。 ### 自动装配是怎么实现的 通过注解来实现,配置了`@EnableAutoConfiguration`后,内部通过加载jar包下`META-INF/spring.factories`文件的信息,将其文件包装成Properties对象,筛选对象key值为EnableAutoConfiguration的数据,用improt将.class文件加载到ioc容器中,即实现自动装配
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up