文章目录
-
- 概述
- [Spring 能帮我们做什么](#Spring 能帮我们做什么)
- 为什么要使用Spring框架
- 谈谈你对Spring框架的理解
- Spring中用到的设计模式
- 全局异常处理如何实现
- SpringDI概述
- spring主要的包
- Spring在业务中常见的使用方式
- [在Spring中如何使用Spring Event做事件驱动](#在Spring中如何使用Spring Event做事件驱动)
- SpringBoot是如何实现main方法启动Web项目的
- Spring中实现异步调用的方式
概述
Spring 是一个用于构建企业级应用程序的开源框架,它提供了丰富的功能和模块化的设计,使得开发者可以更轻松地构建可扩展、可维护的应用程序。Spring 框架由多个模块组成,主要包括:
- Spring Core Container(Spring核心容器):提供了核心功能,包括依赖注入(Dependency Injection)和面向切面编程(Aspect-Oriented Programming)等。主要模块包括:
○ Spring Beans:用于管理应用程序中的对象(Beans)和它们的依赖关系。
○ Spring Core:提供了核心功能,例如依赖注入和类型转换等。 - Spring AOP(Spring面向切面编程):提供了对切面编程的支持,允许开发者实现横切关注点(cross-cutting concerns)的功能,例如事务管理和日志记录等。
- Spring Data Access/Integration(Spring数据访问/集成):提供了对不同数据访问技术和集成的支持,包括 JDBC、ORM(如Hibernate)、JMS、JTA 等。
- Spring Web(Spring Web开发):提供了用于构建 Web 应用程序的功能,包括 Spring MVC 和 WebSocket 等。
- Spring Test(Spring测试):提供了对单元测试和集成测试的支持,包括对 Spring 应用程序的测试。
除了以上核心模块外,Spring 还包括了大量的扩展模块和项目,如 Spring Security(安全框架)、Spring Batch(批处理框架)、Spring Cloud(微服务框架)等,可以根据具体需求选择使用。整个 Spring 框架的设计目标是促进应用程序的松耦合、灵活性和可测试性。
Spring 能帮我们做什么
1.Spring 能帮我们根据配置文件创建及组装对象之间的依赖关系
Spring 根据配置文件来进行创建及组装对象间依赖关系,只需要改配置文件即可
2.Spring 面向切面编程能帮助我们无耦合的实现日志记录,性能统计,安全控制 Spring 面向切面编程能提供一种更好的方式来完成,一般通过配置方式,而且不需要在现有代码中添加任何额外代码,现有代码专注业务逻辑
-
Spring 能非常简单的帮我们管理数据库事务,采用 Spring,我们只需获取连接,执行 SQL,其他事务相关的都交给 Spring 来管理了。
-
Spring 还能与第三方数据库访问框架(如 Hibernate、JPA)无缝集成,而且自己也提供了一套 JDBC
访问模板,来方便数据库访问。
- Spring 还能与第三方 Web(如 Struts、JSF)框架无缝集成,而且自己也提供了一套 Spring MVC
框架,来方便 web 层搭建。
- Spring 能方便的与 Java EE(如 Java Mail、任务调度)整合,与更多技术整合(比如缓存框架)
为什么要使用Spring框架
Spring是一个轻量级应用框架,它提供了IoC和AOP这两个核心的功能。
它的核心目的是为了简化企业级应用程序的开发,使得开发者只需要关心业务需求,不需要关心Bean的管理,以及通过切面增强功能减少代码的侵入性。
1.轻量:Spring是轻量的,基本的版本大约2MB。
2.IOC/DI:Spring通过IOC容器实现了Bean的生命周期的管理,以及通过DI实现依赖注入,从而实现了对象依赖的松耦合管理。
3.面向切面的编程(AOP):Spring支持面向切面的编程,从而把应用业务逻辑和系统服务分开。
4.MVC框架:Spring MVC提供了功能更加强大且更加灵活的Web框架支持
5.事务管理:Spring通过AOP实现了事务的统一管理,对应用开发中的事务处理提供了非常
6.集成测试:Spring为测试提供支持,在开发环境即可生成测试
7.支持数据访问:Spring集成对主流ORM框架的支持,比如JPA、MyBatis等等。
灵活的支持,最后,Spring从第一个版本发布到现在,它的生态已经非常庞大了。在业务开发领域,
Spring生态几乎提供了非常完善的支持,更重要的是社区的活跃度和技术的成熟度都非常高,以上就是我对这个
问题的理解。
总结一句话:Spring就是一个轻量级的控制反转(IOC)和面向切面编程(AOP)的框架
● Spring是一个开源的免费的框架(框架)
● Spring是一个轻量级的,非入侵式的框架
● 控制反转(IOC),面向切面编程(AOP)
● 支持事务的处理,对框架整合的支持
谈谈你对Spring框架的理解
Spring 是一个开源的应用程序框架,它起源于 Rod Johnson 在其著名的 Spring Framework 专著中提出的一个轻量级框架的观念。下面是 Spring 的发展历史:
2002 年,Rod Johnson 发表了他的专著 "Expert One-On-One J2EE Design and Development",提出了 Spring 框架的思想。
2003 年,Johnson 和一些开发者创建了 Spring Framework 项目,并在 SourceForge 上发布了第一个版本。
2004 年,Spring Framework 1.0 版本发布,包括核心容器、AOP 模块、DAO 模块、JDBC 模块和 Web 模块等组成部分。
2006 年,Spring Framework 2.0 版本发布,增加了对注解的支持、Web Services 支持、异步执行能力等新特性。
2009 年,Spring Framework 3.0 版本发布,引入了对 Java 5、Java 6 特性的支持,包括泛型、注解、并发等。
2013 年,Spring Framework 4.0 版本发布,提供对 Java 8 的支持,包括 lambda 表达式、Stream API 等。
2015 年,Spring Framework 4.2 版本发布,增加了对 WebSocket 和 STOMP 协议的支持。
2017 年,Spring Framework 5.0 版本发布,对响应式编程提供了支持,并对代码库进行了大规模升级和剪裁,去掉了过时和不必要的模块和类。
自从 2003 年发布以来,Spring Framework 在 Java 开发社区中变得越来越流行,并成为了多个企业级应用开发的首选框架之一。
Spring 框架是一个用于构建企业级应用程序的开源框架,它提供了丰富的功能和大量的模块,可以简化 Java 开发过程。每个 Spring 版本都引入了新的功能和改进,以下是一些主要版本的区别:
- Spring 1.x:最早的版本,引入了核心的 IoC(Inversion of Control)和 AOP(Aspect-Oriented Programming)功能,为开发者提供了轻量级的容器。
- Spring 2.x:引入了全面的支持注解的能力,并提供了更多的集成技术,例如与 ORM(对象关系映射)框架的整合、Web 框架的支持等。
- Spring 3.x:引入了对 Java 5 特性的支持,例如泛型、注解驱动开发等。还包括了对 RESTful Web 服务的支持、Spring MVC 的重大改进和更好的缓存支持。
- Spring 4.x:引入了对 Java 8 的支持,并加强了对 RESTful Web 服务和 HTML5 的支持。还提供了对 WebSocket 和 JSON 支持的增强功能。
- Spring 5.x:完全支持 Java 8,移除了对旧版 Java 版本的支持。引入了响应式编程模型,提供了对 WebFlux 的支持,让开发者可以开发高度并发和高性能的应用程序。
Spring中用到的设计模式
单例模式:bean默认都是单例的
原型模式:指定作用域为prototype
工厂模式:BeanFactory
模板方法:postProcessBeanFactory,onRefresh,initpropertyValue
策略模式:XmlAppilcationDefinitionReader,PropertiesBeanDefinitionReader
观察者模式:listener,event,multicast
适配器模式:Adapter
装饰者模式:BeanWrapper
责任链模式:使用app的时候会先生成一个拦截器链
代理模式:动态代理
委托者模式:delegate
全局异常处理如何实现
为了区别不同的异常通常根据异常类型自定义异常类,这里我们创建一个自定义系统异常,如果controller、service、dao抛出此类异常说明是系统预期处理的异常信息。
自定义异常处理器实现HandlerExceptionResolver接口,在实现方法内做判断是否为自定义异常
系统的dao、service、controller出现都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理
自定义一个异常类,实现handlerExceptionResolve并实现resolvelException方法
在springmvc.xml中配置这个异常bean对象
SpringDI概述
依赖注入:Dependency Injection。
是指在spring框架负责创建Bean对象时,动态将依赖对象注入到Bean中。
之前我们都需要自己通过getBean
方法获取到对象,使用DI之后就可以让Spring框架帮我们把对象注入到bean中
依赖注入能注入的数据类型:
-
基本类型和string
-
其他Bean类型(在配置文件中或注解配置过的bean)
-
复杂类型/集合类型
依赖注入的方式:
-
通过构造函数
-
使用set方法
-
使用注解
spring主要的包
Spring 框架是一个非常广泛使用的 Java 开发框架,提供了许多功能强大且灵活的模块,涵盖了从基本的核心容器到企业级的开发、Web 开发、数据访问、集成等各个领域。以下是 Spring 主要的一些核心包和模块:
- spring-core:Spring 核心容器,包括 IoC(控制反转)和 DI(依赖注入)的功能实现。
- spring-beans:Spring Bean 相关的功能,包括 Bean 的定义、创建和管理。
- spring-context:提供了 Spring 上下文的功能,包括对企业服务、国际化、事件传播等的支持。
- spring-aop:面向切面编程(AOP)的支持,包括动态代理和 AspectJ 集成。
- spring-expression:Spring 表达式语言(SpEL)的支持,用于在运行时进行查询和操作对象图。
- spring-jdbc:Spring 对 JDBC 的封装和支持,简化了数据库访问的操作。
- spring-tx:Spring 事务管理的支持,提供了对声明式和编程式事务管理的实现。
- spring-orm:Spring 对对象关系映射(ORM)的支持,包括对 JPA、Hibernate、MyBatis 等框架的集成。
- spring-web:Spring Web 开发的支持,包括对 MVC、WebSocket、Web 服务等的实现。
- spring-webmvc:Spring MVC 的实现,用于构建 Web 应用程序的控制器和视图。
- spring-webflux:Spring 对响应式编程的支持,提供了基于 Reactor 的响应式编程模型。
- spring-data:Spring Data 抽象和支持,用于简化对各种数据存储的访问,如关系型数据库、NoSQL 数据库、Redis 等。
- spring-security:Spring Security 的实现,用于身份验证、授权、攻击防护等安全功能。
- spring-cloud:Spring Cloud 框架,用于构建分布式系统中的微服务架构。
这些是 Spring 框架中一些核心的包和模块,每个模块都提供了特定领域的功能支持,开发者可以根据自己的需求选择相应的模块进行使用。
为什么不建议直接使用Spring的@Async
虽然 Spring 的 @Async 注解可以方便地实现异步执行,但是直接使用它也存在一些风险和限制,因此不建议直接使用 @Async。
以下是使用 @Async 的一些风险和限制: - 线程池配置过于简单:如果直接使用 Spring 的默认线程池,可能会导致线程数不足或者线程数过多的问题。建议根据实际情况调整线程池的配置,以满足应用的需求。
- 无法对任务进行管理和监控:使用 @Async 注解会将任务提交到线程池中执行,但是无法对任务进行管理和监控。如果任务执行出现异常,也无法及时进行处理和重试。
- 无法控制任务执行的顺序:使用 @Async 注解提交的任务是异步执行的,无法保证任务执行的顺序。如果有多个任务之间有先后顺序的要求,会导致程序逻辑出现问题。
- 无法对任务进行协作:使用 @Async 注解提交的任务是独立执行的,无法对任务之间进行协作和通信。如果任务之间有共享的数据或资源,可能会导致数据不一致或资源竞争等问题。
针对以上问题,可以考虑使用 Spring 提供的 TaskExecutor 接口进行任务管理和监控,或者使用 Spring Integration、Spring Batch 等框架来实现任务的协作和通信。
此外,还可以使用 Java 原生的线程池、并发包等工具来实现异步执行。这些工具灵活性更高,可以根据实际需求进行配置和使用,但使用起来可能会比较复杂。
Spring在业务中常见的使用方式
Spring 在业务中有多种常见的使用方式,包括但不限于以下几个方面:
- 依赖注入:Spring 的核心特性之一就是依赖注入(DI),它可以通过配置或者注解的方式管理对象之间的依赖关系,从而简化了组件之间的耦合性。在业务中,通常会使用 Spring 的依赖注入来管理各种服务、数据访问对象和其他组件之间的依赖关系。
- AOP(面向切面编程):Spring 提供了强大的 AOP 支持,可以帮助在业务逻辑中实现横切关注点的功能,比如日志记录、事务管理等。在业务中,AOP 可以用来统一处理日志、权限控制、性能监控等横切关注点。
- 事务管理:Spring 的事务管理框架提供了对声明式事务的支持,能够简化事务管理的配置和使用。在业务中,可以使用 Spring 的事务管理来确保数据库操作的原子性、一致性、隔离性和持久性。
- Web 开发:Spring 提供了丰富的 Web 开发支持,包括 Spring MVC、REST 框架、WebSocket 支持等,可以用于构建各种类型的 Web 应用程序。在业务中,Spring 可以用来开发和管理 Web 服务、RESTful API 等。
- 集成各种数据访问技术:Spring 对数据访问提供了良好的支持,包括对 JDBC、ORM 框架(如 Hibernate、MyBatis)、NoSQL 数据库等的集成。在业务中,Spring 可以用来管理和简化数据访问层的开发和集成。
- 消息队列和调度任务:Spring 提供了对消息队列(如 RabbitMQ、Kafka)和调度任务的支持,可以用于异步消息处理和定时任务调度。
以上是 Spring 在业务中常见的使用方式,Spring 框架提供了丰富的功能和组件,能够帮助开发者快速构建可靠、高效、可扩展的企业级应用程序。
在Spring中如何使用Spring Event做事件驱动
在 Spring 中使用 Spring Event 实现事件驱动的方式如下:
-
定义事件:首先,需要定义自己的事件类,该类要继承 ApplicationEvent 或其子类。例如,可以创建一个名为 MyCustomEvent 的事件类。
public class MyCustomEvent extends ApplicationEvent {
// 事件相关的数据和方法
// ...
} -
发布事件:要发布事件,需要注入一个 ApplicationEventPublisher 对象,并调用其 publishEvent() 方法来发布事件。通常情况下,可以在某个方法中调用该方法来触发事件的发布。
@Service
public class MyService {private final ApplicationEventPublisher eventPublisher; public MyService(ApplicationEventPublisher eventPublisher) { this.eventPublisher = eventPublisher; } public void doSomethingAndPublishEvent() { // 执行某些操作 // 发布事件 MyCustomEvent event = new MyCustomEvent(this, eventData); eventPublisher.publishEvent(event); }
}
-
订阅事件:要订阅事件,需要创建一个监听器(Listener)来处理事件。监听器需要实现 ApplicationListener 接口,并指定监听的事件类型。当事件被发布时,监听器中的 onApplicationEvent() 方法将会被调用。
@Component
public class MyEventListener implements ApplicationListener<MyCustomEvent> {@Override public void onApplicationEvent(MyCustomEvent event) { // 处理事件 // ... }
}
通过上述步骤,就可以在 Spring 中实现事件驱动的方式。当调用 MyService 中的方法 doSomethingAndPublishEvent() 时,会触发 MyCustomEvent 的发布,并且被 MyEventListener 监听器接收并处理。
需要注意的是,Spring Event 是同步的,即事件发布和监听是在同一个线程中执行的。如果需要异步处理事件,可以使用 @Async 注解配合线程池来实现异步执行。
另外,还可以通过自定义事件的层次结构、条件过滤器等方式进行更灵活的事件处理。
SpringBoot是如何实现main方法启动Web项目的
Spring Boot 能够通过 main 方法启动 Web 项目的原理其实很简单,主要是借助了 Spring Boot Starter 和 Spring Boot AutoConfigure 两个机制。
- Spring Boot Starter:它是 Spring Boot 的一个约定,定义了一系列的依赖包和配置文件,以简化应用程序的开发和部署。在启动 Web 项目时,Spring Boot Starter 会自动加载并配置一些必要的依赖,如 Spring MVC、Servlet 容器(如 Tomcat、Jetty 等)等。
- Spring Boot AutoConfigure:它是 Spring Boot 的另一个重要机制,能够根据类路径上的依赖自动配置 Spring 应用程序。在启动 Web 项目时,Spring Boot AutoConfigure 会根据项目中的依赖和配置文件,自动配置各个组件,如数据库连接池、事务管理、消息队列、缓存等。
在具体实现上,Spring Boot 通过 SpringApplication 类来启动 Web 项目,其中 SpringApplication 类提供了多个 run() 方法,能够启动一个 Spring 应用程序,并自动配置项目所需的依赖和组件。在这个过程中,Spring Boot 会扫描项目中所有的 @Component、@Controller 等注解标记的类,并将它们作为 Bean 注册到 Spring 的 ApplicationContext 中。
同时,Spring Boot 还提供了一些配置类,如 application.properties、application.yml 等,能够用于配置项目的一些基本信息,如端口号、数据库连接等。这些配置类会被 Spring Boot AutoConfigure 自动加载,并根据其内容自动配置应用程序。
综上所述,Spring Boot 之所以能够通过 main 方法启动 Web 项目,主要是通过约定大于配置的方式,自动加载和配置了项目中所需的依赖和组件,以及提供了方便的配置文件,使得开发者可以更加专注于业务逻辑的开发。
在springboot中,通过springapplication类的静态方法run来启动web项目。当我们在main方法中调用
run方法时,springboot使用一个内嵌的tomcat服务器,并将其配置为处理web请求。
当应用程序启动时,springboot会自动扫描应用程序中所有的spring组件,并使用默认的配置来启动内嵌
的tomcat报务器,在默认情况下,springboot会自动配置大部分的web开发所需的配置,包括请求处
理,视图解析,静态资源处理等。
这样,在应用程序启动后,我们就可以通过web浏览器访问应用程序了。例如,在默认情况下,可以通过
访问http://localhost:8080来访问应用程序的首页。
除了默认的tomcat之外,springboot还支持内嵌jetty和undertow服务器。
我们可以通过修改pomxm文件中的依赖项来切换到其他的内嵌web服务器。例如,如果我们想使用
undertow作为内嵌服务器,我们可以将以下依赖项添加到pomxml文件中:
Spring中实现异步调用的方式
在Spring中,实现异步调用主要有三种方式,分别是
注解方式、
内置线程池方式
和自定义线程池方式。
1、注解方式
可以在配置类和方法上加特定注解。首先,在配置类加上@EnableAsync来启用异步注解,
使用@Async标记的异步方法可以带参数,也可以带有返回值。返回值类型必须是
java.util.concurrent.Future或其子类,可以是以下3种类型:
1)由Java原生API提供的Future。
2)由Spring提供的ListenableFuture后者AsyncResult。
3)Java 8提供的CompletableFuture。
需要说明的是,@Async默认会使用SimpleAsyncTaskExecutor来执行,而这个线程池不会复用线程。所以,
通常要使用异步处理,我们都会自定义线程池。
2、内置线程池方式
可以使用Spring内置的线程池来实现异步调用,比如ThreadPoolTaskExecutor 和SimpleAsyncTaskExecutor。
Spring提供了许多TaskExecutor的内置实现。下面简单介绍5种内置的线程池。
1)SimpleAsyncTaskExecutor:它不会复用线程,每次调用都是启动一个新线程。
2)ConcurrentTaskExecutor:它是Java API中Executor实例的适配器。
3)ThreadPoolTaskExecutor:这个线程池是最常用的。它公开了用于配置的bean属性,并将它包装在
TaskExecutor中。
4)WorkManagerTaskExecutor:它基于CommonJ WorkManager来实现的,并且是在Spring上下文中的
WebLogic或WebSphere中设置CommonJ线程池的工具类。
5)DefaultManagedTaskExecutor:主要用于支持JSR-236兼容的运行时环境,它是使用JNDI获得
ManagedExecutorService,作为CommonJ WorkManager的替代方案。
通常情况下,ThreadPoolTaskExecuto最为常用,只要当ThreadPoolTaskExecutor不能满足需求时,可
以使用ConcurrentTaskExecutor。如果在代码中声明了多个线程池,Spring会默认按照以下搜索顺序来调用线
程池:
第一步,检查上下文中的唯一TaskExecutor Bean。
第二步,检查名为" taskExecutor"的Executor Bean。
第三步,以上都无法无法处理,就会使用SimpleAsyncTaskExecutor来执行。
3、自定义线程池方式
可以通过实现AsyncConfigurer接口或者直接继承AsyncConfigurerSupport类来自定义线程池。但是非完全托
管的Bean和完全托管的Bean实现方式有点小差异。