我:“基于JAVA的Spring为什么能这么火?” 大牛:“且看我一 一 道来!”

Spring 框架是一个为 Java 应用程序的开发提供了综合、广泛的基础性支持的 Java 平台。Spring 帮助开发者解决了开发中基础性的问题,使得开发人员可以专注于应用程序的开发。Spring 框架本身亦是按照设计模式精心打造,这使得我们可以在开发环境中安心的集成 Spring 框架,不必担心 Spring 是如何在后台进行工作的。Spring 框架至今已集成了 20 多个模块。这些模块主要被分如下图所示的核心容器、数据访问/集成,、Web、AOP(面向切面编程)、工具、消息和测试模块。
我:“基于JAVA的Spring为什么能这么火?” 大牛:“且看我一 一 道来!”

使用 Spring 框架能带来哪些好处?

使用Spring带来的好处是显而易见的

Dependency Injection(DI) 方法使得构造器和 JavaBean properties 文件中的依赖关系一目了然。

与 EJB 容器相比较,IoC 容器更加趋向于轻量级。这样一来 IoC 容器在有限的内存和 CPU 资源的情况下进行应用程序的开发和发布就变得十分有利。

Spring 并没有闭门造车,Spring 利用了已有的技术比如 ORM 框架、logging 框架、J2EE、Quartz 和 JDK Timer,以及其他视图技术。

Spring 框架是按照模块的形式来组织的。由包和类的编号就可以看出其所属的模块,开发者仅仅需要选用他们需要的模块即可。

要测试一项用 Spring 开发的应用程序十分简单,因为测试相关的环境代码都已经囊括在框架中了。更加简单的是,利用 JavaBean 形式的 POJO 类,可以很方便的利用依赖注入来写入测试数据。

Spring 的 Web 框架亦是一个精心设计的 Web MVC 框架,为开发者们在 web 框架的选择上提供了一个除了主流框架比如 Struts、过度设计的、不流行 web 框架的以外的有力选项。

Spring 提供了一个便捷的事务管理接口,适用于小型的本地事物处理(比如在单 DB 的环境下)和复杂的共同事物处理(比如利用 JTA 的复杂 DB 环境)。

本人在这里整理了20多家公司的面试题,以及各种关于Spring、Spring boot、Spring MVC、MyBatis、MySQL、JVM等知识点,如果有需要的小伙伴可以加群1149778920 暗号:qf
我:“基于JAVA的Spring为什么能这么火?” 大牛:“且看我一 一 道来!”

Spring 框架中的 IoC

Spring 中的 org.springframework.beans 包和 org.springframework.context 包构成了 Spring 框架 IoC 容器的基础。

BeanFactory 接口提供了一个先进的配置机制,使得任何类型的对象的配置成为可能。

ApplicationContex 接口对 BeanFactory (是一个子接口)进行了扩展,在 BeanFactory的基础上添加了其他功能,比如与 Spring 的 AOP 更容易集成,也提供了处理 message resource的机制(用于国际化)、事件传播以及应用层的特别配置,比如针对 Web 应用的WebApplicationContext。

org.springframework.beans.factory.BeanFactory 是 Spring IoC 容器的具体实现,用来包装和管理前面提到的各种 bean。BeanFactory 接口是 Spring IoC 容器的核心接口。

IOC:把对象的创建、初始化、销毁交给 spring 来管理,而不是由开发者控制,实现控制反转。

BeanFactory 和 和 ApplicationContext 有什么区别?

我:“基于JAVA的Spring为什么能这么火?” 大牛:“且看我一 一 道来!”

BeanFactory 可以理解为含有 bean 集合的工厂类。BeanFactory 包含了种 bean 的定义,以便在接收到客户端请求时将对应的 bean 实例化。

BeanFactory 还能在实例化对象的时生成协作类之间的关系。此举将 bean 自身与 bean 客户端的配置中解放出来。BeanFactory 还包含 了 bean 生命周期的控制,调用客户端的初始化方法(initialization methods)和销毁方法(destruction methods)。

从表面上看,application context 如同 bean factory 一样具有 bean 定义、bean 关联关系的设置,根据请求分发 bean 的功能。但 applicationcontext 在此基础上还提供了其他的功能。

提供了支持国际化的文本消息统一的资源文件读取方式已在监听器中注册的 bean 的事件

以下是三种较常见的 ApplicationContext 实现方式:
1、ClassPathXmlApplicationContext:从 classpath 的 XML 配置文件中读取上下文,并生成上下文定义。应用程序上下文从程序环境变量中

ApplicationContext context = new
ClassPathXmlApplicationContext(“bean.xml”);

2、FileSystemXmlApplicationContext :由文件系统中的 XML 配置文件读取上下文。

ApplicationContext context = new
FileSystemXmlApplicationContext(“bean.xml”);

3、XmlWebApplicationContext:由 Web 应用的 XML 文件读取上下文。

AnnotationConfigApplicationContext(基于 Java 配置启动容器)
我:“基于JAVA的Spring为什么能这么火?” 大牛:“且看我一 一 道来!”

Spring 有几种配置方式

将 Spring 配置到应用开发中有以下三种方式:

基于 XML 的配置

基于注解的配置

基于 Java 的配置

如何用基于 XML 配置的方式配置 Spring ?

在 Spring 框架中,依赖和服务需要在专门的配置文件来实现,我常用的 XML 格式的配置文件。这些配置文件的格式通常用 开头,然后一系列的 bean 定义和专门的应用配置选项组成。

SpringXML 配置的主要目的时候是使所有的 Spring 组件都可以用 xml 文件的形式来进行配置。这意味着不会出现其他的 Spring 配置类型(比如声明的方式或基于 Java Class 的配置方式)Spring 的 XML 配置方式是使用被 Spring 命名空间的所支持的一系列的 XML 标签来实现的。

Spring 有以下主要的命名空间:context、beans、jdbc、tx、aop、mvc 和 aso。
如:

<beans>
<!-- JSON Support -->
<bean name="viewResolver"
class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
<bean name="jsonTemplate"
class="org.springframework.web.servlet.view.json.MappingJackson2JsonV
iew"/>
<bean id="restTemplate"
class="org.springframework.web.client.RestTemplate"/>
</beans>

下面这个 web.xml 仅仅配置了 DispatcherServlet,这件最简单的配置便能满足应用程序配置运行时组件的需求。

<web-app>
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-
class>org.springframework.web.servlet.DispatcherServlet</servlet-
class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>

如何用基于 Java 配置的方式配置 Spring ?

Spring 对 Java 配置的支持是由@Configuration 注解和@Bean 注解来实现的。由@Bean 注解
的方法将会实例化、配置和初始化一个 新对象,这个对象将由 Spring 的 IoC 容器来管理。
@Bean 声明所起到的作用与 元素类似。被 @Configuration 所注解的类则表示这个类
的主要目的是作为 bean 定义的资源。被@Configuration 声明的类可以通过在同一个类的 内部调
用@bean 方法来设置嵌入 bean 的依赖关系。
最简单的@Configuration 声明类请参考下面的代码:

@Configuration
public class AppConfig{
@Bean
public MyService myService() {
return new MyServiceImpl();
}
}

对于上面的@Beans 配置文件相同的 XML 配置文件如下:

<beans>
<bean id="myService" class="com.somnus.services.MyServiceImpl"/>
</beans>

上述配置方式的实例化方式如下:利用 AnnotationConfigApplicationContext 类进行实例化

public static void main(String[] args) {
ApplicationContext ctx = new
AnnotationConfigApplicationContext(AppConfig.class);
MyService myService = ctx.getBean(MyService.class);
myService.doStuff();
}

要使用组件组建扫描,仅需用@Configuration 进行注解即可:

@Configuration
@ComponentScan(basePackages = "com.somnus")
public class AppConfig {
...
}

在上面的例子中,com.acme 包首先会被扫到,然后再容器内查找被@Component 声明的类,找到后将这些类按照 Sring bean 定义进行注册。

如果你要在你的 web 应用开发中选用上述的配置的方式的话,需要用AnnotationConfigWebApplicationContext 类来读 取配置文件,可以用来配置 Spring 的Servlet 监听器 ContextLoaderListener 或者 Spring MVC 的 DispatcherServlet。

<web-app>
<!-- Configure ContextLoaderListener to use
AnnotationConfigWebApplicationContext
instead of the default XmlWebApplicationContext -->
<context-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicatio
nContext
</param-value>
</context-param>
<!-- Configuration locations must consist of one or more comma- or
space-delimited
fully-qualified @Configuration classes. Fully-qualified
packages may also be
specified for component-scanning -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.howtodoinjava.AppConfig</param-value>
</context-param>
<!-- Bootstrap the root application context as usual using
ContextLoaderListener -->
<listener>
<listener-
class>org.springframework.web.context.ContextLoaderListener</listener
-class>
</listener>
<!-- Declare a Spring MVC DispatcherServlet as usual -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-
class>org.springframework.web.servlet.DispatcherServlet</servlet-
class>
<!-- Configure DispatcherServlet to use
AnnotationConfigWebApplicationContext
instead of the default XmlWebApplicationContext -->
<init-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicatio
nContext
</param-value>
</init-param>
<!-- Again, config locations must consist of one or more comma-
or space-delimited
and fully-qualified @Configuration classes -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.howtodoinjava.web.MvcConfig</param-
value>
</init-param>
</servlet>
<!-- map all requests for /app/* to the dispatcher servlet -->
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
</web-app

解释 Spring Bean 的生命周期

Spring Bean 的生命周期简单易懂。在一个 bean 实例被初始化时,需要执行一系列的初始化操作
以达到可用的状态。同样的,当一个 bean 不在被调用时需要进行相关的析构操作,并从 bean 容
器中移除。
Spring bean factory 负责管理在 spring 容器中被创建的 bean 的生命周期。Bean 的生命周期
由两组回调(call back)方法组成。

    初始化之后调用的回调方法。销毁之前调用的回调方法。
    Spring 框架提供了以下四种方式来管理 bean 的生命周期事件:

InitializingBean 和 DisposableBean 回调接口针对特殊行为的其他 Aware 接口Bean 配置文件中的 Custom init()方法和 destroy()方法@PostConstruct 和@PreDestroy 注解方式
使用 customInit() 和 customDestroy()方法管理 bean 生命周期的代码样例如
下:

<beans>
<bean id="demoBean" class="com.somnus.task.DemoBean" init-
method="customInit" destroy-method="customDestroy"></bean>
</beans>

最后

针对最近很多人都在面试,我这边也整理了相当多的面试专题资料,也有其他大厂的面经。希望可以帮助到大家。
有需要的小伙伴可以加群1149778920 暗号:qf
我:“基于JAVA的Spring为什么能这么火?” 大牛:“且看我一 一 道来!”

我:“基于JAVA的Spring为什么能这么火?” 大牛:“且看我一 一 道来!”

匿名

发表评论

匿名网友

    • bronya0 bronya0

      {{tiaopi}}