Spring Framework:认识spring(一)

简介: spring

1.概述

spring官方介绍:

“The Spring Framework provides a comprehensive programming and configuration model for modern Java-based enterprise applications - on any kind of deployment platform.

A key element of Spring is infrastructural support at the application level: Spring focuses on the "plumbing" of enterprise applications so that teams can focus on application-level business logic, without unnecessary ties to specific deployment environments.”

基于配置模型的全面编程模式,企业开发团队可以专注于业务开发。

“Features:

  • Core technologies: dependency injection, events, resources, i18n, validation, data binding, type conversion, SpEL, AOP.
  • Testing: mock objects, TestContext framework, Spring MVC Test, WebTestClient.
  • Data Access: transactions, DAO support, JDBC, ORM, Marshalling XML.
  • Spring MVC and Spring WebFlux web frameworks.
  • Integration: remoting, JMS, JCA, JMX, email, tasks, scheduling, cache.
  • Languages: Kotlin, Groovy, dynamic languages.”

1.1 What is Spring ?

The Spring Framework is divided into modules. Applications can choose which modules they need. At the heart are the modules of the core container, including a configuration model and a dependency injection mechanism. Beyond that, the Spring Framework provides foundational support for different application architectures, including messaging, transactional data and persistence, and web. It also includes the Servlet-based Spring MVC web framework and, in parallel, the Spring WebFlux reactive web framework.

1.2 History of Spring and the Spring Framework

Spring came into being in 2003 as a response to the complexity of the early J2EE specifications. While some consider Java EE and Spring to be in competition, Spring is, in fact, complementary to Java EE. The Spring programming model does not embrace the Java EE platform specification; rather, it integrates with carefully selected individual specifications from the EE umbrella:

The Spring Framework also supports the Dependency Injection (JSR 330) and Common Annotations (JSR 250) specifications, which application developers may choose to use instead of the Spring-specific mechanisms provided by the Spring Framework.

Over time, the role of Java EE in application development has evolved. In the early days of Java EE and Spring, applications were created to be deployed to an application server. Today, with the help of Spring Boot, applications are created in a devops- and cloud-friendly way, with the Servlet container embedded and trivial to change. As of Spring Framework 5, a WebFlux application does not even use the Servlet API directly and can run on servers (such as Netty) that are not Servlet containers.

Spring continues to innovate and to evolve. Beyond the Spring Framework, there are other projects, such as Spring Boot, Spring Security, Spring Data, Spring Cloud, Spring Batch, among others. It’s important to remember that each project has its own source code repository, issue tracker, and release cadence. See spring.io/projects for the complete list of Spring projects.

1.3 Design Philosophy

When you learn about a framework, it’s important to know not only what it does but what principles it follows. Here are the guiding principles of the Spring Framework:

Provide choice at every level. Spring lets you defer design decisions as late as possible. For example, you can switch persistence providers through configuration without changing your code. The same is true for many other infrastructure concerns and integration with third-party APIs.

Accommodate diverse perspectives. Spring embraces flexibility and is not opinionated about how things should be done. It supports a wide range of application needs with different perspectives.

Maintain strong backward compatibility. Spring’s evolution has been carefully managed to force few breaking changes between versions. Spring supports a carefully chosen range of JDK versions and third-party libraries to facilitate maintenance of applications and libraries that depend on Spring.

Care about API design. The Spring team puts a lot of thought and time into making APIs that are intuitive and that hold up across many versions and many years.

Set high standards for code quality. The Spring Framework puts a strong emphasis on meaningful, current, and accurate javadoc. It is one of very few projects that can claim clean code structure with no circular dependencies between packages.

2.核心技术

IoC Container, Events, Resources, i18n, Validation, Data Binding, Type Conversion, SpEL, AOP.

2.1 The IoC Container

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.

The org.springframework.beans and org.springframework.context packages are the basis for Spring Framework’s IoC container. The BeanFactory interface provides an advanced configuration mechanism capable of managing any type of object. ApplicationContext is a sub-interface of BeanFactory. It adds:

  • Easier integration with Spring’s AOP features
  • Message resource handling (for use in internationalization)
  • Event publication
  • Application-layer specific contexts such as the WebApplicationContext for use in web applications.

In short, the BeanFactory provides the configuration framework and basic functionality, and the ApplicationContext adds more enterprise-specific functionality. The ApplicationContext is a complete superset of the BeanFactory.

In Spring, the objects that form the backbone of your application and that are managed by the Spring IoC container are called beans. A bean is an object that is instantiated, assembled, and otherwise managed by a Spring IoC container. Otherwise, a bean is simply one of many objects in your application. Beans, and the dependencies among them, are reflected in the configuration metadata used by a container.

The org.springframework.context.ApplicationContext interface represents the Spring IoC container and is responsible for instantiating, configuring, and assembling the beans. The container gets its instructions on what objects to instantiate, configure, and assemble by reading configuration metadata. The configuration metadata is represented in XML, Java annotations, or Java code. It lets you express the objects that compose your application and the rich interdependencies between those objects.

翻译和理解:可以使用XML配置,Java注解和Java代码来建立配置元数据,(XML是定义配置元数据的传统格式),配置元数据表示应用程序开发人员告诉Spring容器实例化、配置和组装应用程序中的对象。基于XML的配置元数据将这些bean配置为顶层元素中的<bean/>元素。Java配置通常在@configuration类中使用@Bean注释的方法。这些bean定义对应于构成应用程序的实际对象。通常,不会在容器中配置细粒度的域对象,因为创建和加载域对象通常是dao和业务逻辑的责任。

以下示例为基于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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="..." class="...">  
        <!-- collaborators and configuration for this bean go here -->
    </bean>

    <bean id="..." class="...">
        <!-- collaborators and configuration for this bean go here -->
    </bean>

    <!-- more bean definitions go here -->

</beans>

介绍:

  • id属性是标识单个bean定义的字符串。id属性的值也可以是引用对象的bean id
  • class属性定义bean的类型,并使用完全限定的类名。

Instantiating a Container

The location path or paths supplied to an ApplicationContext constructor are resource strings that let the container load configuration metadata from a variety of external resources, such as the local file system, the Java CLASSPATH, and so on.

ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");

services.xml和daos.xml就是基于XML配置的元数据
编写基于XML的配置元数据
通常XML文件有多个,每个单独的XML配置文件都表示体系结构中的逻辑层或模块。

Using the Container

The ApplicationContext is the interface for an advanced factory capable of maintaining a registry of different beans and their dependencies. By using the method T getBean(String name, Class requiredType), you can retrieve instances of your beans.
The ApplicationContext lets you read bean definitions and access them, as the following example shows:

// create and configure beans
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");

// retrieve configured instance
PetStoreService service = context.getBean("petStore", PetStoreService.class);

// use configured instance
List<String> userList = service.getUsernameList();

Beans

A Spring IoC container manages one or more beans. These beans are created with the configuration metadata that you supply to the container (for example, in the form of XML <bean/> definitions).

在容器本身中,这些bean定义表示为BeanDefinition对象,其中包含(除其他信息外)以下元数据:

  • 包限定类名:通常是被定义的bean的实际实现类。
  • Bean行为配置元素,用于说明Bean在容器中的行为(范围、生命周期回调等)。
  • 对bean执行其工作所需的其他bean的引用。这些引用也称为协作者或依赖项。
  • 要在新创建的对象 - 中设置的其他配置设置,例如池的大小限制或要在管理连接池的bean中使用的连接数。
    此元数据转换为组成每个bean定义的一组属性。

这些属性有:

  • Class
  • Name
  • Scope
  • Constructor arguments
  • Properties
  • Autowiring mode
  • Lazy initialization mode
  • Initialization metho
  • Destruction method

Naming Beans
Every bean has one or more identifiers. These identifiers must be unique within the container that hosts the bean. A bean usually has only one identifier. However, if it requires more than one, the extra ones can be considered aliases.

在Bean Definition之外给Bean加别名

<alias name="fromName" alias="toName"/>

If you use Javaconfiguration, the @Bean annotation can be used to provide aliases

Instantiating Beans

Dependency Injection

Dependency injection (DI) is a process whereby objects define their dependencies (that is, the other objects with which they work) 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 on its own by using direct construction of classes or the Service Locator pattern.

依赖注入是个过程,对象仅通过构造函数参数、工厂方法的参数或从工厂方法构造或返回对象实例后在对象实例上设置的属性来定义其依赖项(即它们使用的其他对象)。

Code is cleaner with the DI principle, and decoupling is more effective when objects are provided with their dependencies. The object does not look up its dependencies and does not know the location or class of the dependencies.

使用DI原则,代码更干净,当对象具有其依赖关系时,解耦更有效。对象不查找其依赖项,也不知道依赖项的位置或类。
DI exists in two major variants: Constructor-based dependency injection and Setter-based dependency injection.
Constructor-based Dependency Injection

Constructor-based DI is accomplished by the container invoking a constructor with a number of arguments, each representing a dependency. Calling a static factory method with specific arguments to construct the bean is nearly equivalent

基于构造函数的DI是通过容器调用具有多个参数的构造函数来实现的,每个参数代表一个依赖项。调用带有特定参数的静态工厂方法来构造bean几乎是等价的.
Constructor Argument Resolution
引用注入

<beans>
    <bean id="beanOne" class="x.y.ThingOne">
        <constructor-arg ref="beanTwo"/>
        <constructor-arg ref="beanThree"/>
    </bean>

    <bean id="beanTwo" class="x.y.ThingTwo"/>

    <bean id="beanThree" class="x.y.ThingThree"/>
</beans>

类型注入(type matching)

<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg type="int" value="7500000"/>
    <constructor-arg type="java.lang.String" value="42"/>
</bean>

索引(index)

<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg index="0" value="7500000"/>
    <constructor-arg index="1" value="42"/>
</bean>

名称(name)

<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg name="years" value="7500000"/>
    <constructor-arg name="ultimateAnswer" value="42"/>
</bean>

Setter-based Dependency Injection

public class SimpleMovieLister {

    // the SimpleMovieLister has a dependency on the MovieFinder
    private MovieFinder movieFinder;

    // a setter method so that the Spring container can inject a MovieFinder
    public void setMovieFinder(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }

    // business logic that actually uses the injected MovieFinder is omitted...
}

Constructor-based or setter-based DI?

Since you can mix constructor-based and setter-based DI, it is a good rule of thumb to use constructors for mandatory dependencies and setter methods or configuration methods for optional dependencies. Note that use of the @Required annotation on a setter method can be used to make the property be a required dependency; however, constructor injection with programmatic validation of arguments is preferable.

The Spring team generally advocates constructor injection, as it lets you implement application components as immutable objects and ensures that required dependencies are not null. Furthermore, constructor-injected components are always returned to the client (calling) code in a fully initialized state. As a side note, a large number of constructor arguments is a bad code smell, implying that the class likely has too many responsibilities and should be refactored to better address proper separation of concerns.

Setter injection should primarily only be used for optional dependencies that can be assigned reasonable default values within the class. Otherwise, not-null checks must be performed everywhere the code uses the dependency. One benefit of setter injection is that setter methods make objects of that class amenable to reconfiguration or re-injection later. Management through JMX MBeans is therefore a compelling use case for setter injection.

Use the DI style that makes the most sense for a particular class. Sometimes, when dealing with third-party classes for which you do not have the source, the choice is made for you. For example, if a third-party class does not expose any setter methods, then constructor injection may be the only available form of DI.

  • 对于强制依赖项使用构造函数
  • 对于可选依赖项使用setter方法或配置方法
  • Spring团队通常支持构造函数注入,因为它允许您将应用程序组件实现为不可变对象,并确保所需的依赖项不为空。
  • setter注入的一个好处是setter方法使该类的对象能够在以后重新配置或重新注入。
  • 在处理没有源代码的第三方类时,会为您做出选择。例如,如果第三方类没有公开任何setter方法,那么构造函数注入可能是DI的唯一可用形式。

Circular dependencies
循环依赖
一种可能的解决方案是编辑一些类的源代码,这些类由setter而不是构造函数配置。或者,避免构造函数注入,只使用setter注入。换句话说,虽然不建议这样做,但是可以使用setter注入配置循环依赖项。

Lazy-initialized Beans

By default, ApplicationContext implementations eagerly create and configure all singleton beans as part of the initialization process. Generally, this pre-instantiation is desirable, because errors in the configuration or surrounding environment are discovered immediately, as opposed to hours or even days later. When this behavior is not desirable, you can prevent pre-instantiation of a singleton bean by marking the bean definition as being lazy-initialized. A lazy-initialized bean tells the IoC container to create a bean instance when it is first requested, rather than at startup.

容器默认是立即创建类的单例实例,可以通过将bean定义标记为延迟初始化来防止单例bean的预实例化。延迟初始化的bean告诉IoC容器在第一次请求时创建bean实例,而不是在启动时创建。

in XML, this behavior is controlled by the lazy-init attribute on the element, as the following example shows:

<bean id="lazy" class="com.something.ExpensiveToCreateBean" lazy-init="true"/>
<bean name="not.lazy" class="com.something.AnotherBean"/>

You can also control lazy-initialization at the container level by using the default-lazy-init attribute on the element, a the following example shows:

<beans default-lazy-init="true">
    <!-- no beans will be pre-instantiated... -->
</beans>

Autowiring Collaborators

目录
相关文章
|
6月前
|
Java 开发者 Spring
Spring Framework 中的 @Autowired 注解:概念与使用方法
【4月更文挑战第20天】在Spring Framework中,@Autowired 注解是实现依赖注入(Dependency Injection, DI)的一种非常强大的工具。通过使用 @Autowired,开发者可以减少代码中的引用绑定,提高模块间的解耦能力
634 6
|
3月前
|
安全 Java 网络安全
Spring Framework JDK >= 9 远程代码执行(CVE-2022-22965)
Spring Framework JDK >= 9 远程代码执行(CVE-2022-22965)
|
5月前
|
前端开发 Java 调度
Spring Webflux 是 Spring Framework 提供的响应式编程支持
Spring Webflux 是 Spring Framework 提供的响应式编程支持
77 2
|
4月前
|
Cloud Native Java 开发者
深入解析Spring Framework的核心设计原理
深入解析Spring Framework的核心设计原理
|
4月前
|
安全 Java Apache
如何安装与使用Spring Boot 2.2.x、Spring Framework 5.2.x与Apache Shiro 1.7进行高效开发
【7月更文第1天】在现代Java Web开发领域,Spring Boot以其简化配置、快速开发的特点备受青睐。结合Spring Framework的成熟与Apache Shiro的强大权限控制能力,我们可以轻松构建安全且高效的Web应用。本篇文章将指导你如何安装并使用Spring Boot 2.2.x、Spring Framework 5.2.x以及Apache Shiro 1.7来构建一个具备基础权限管理功能的项目。
77 0
|
6月前
|
设计模式 Java 数据库连接
Spring Framework 6 中的设计模式
Spring Framework 6 中的设计模式
43 1
|
6月前
|
前端开发 Java Spring
Spring Framework五大功能模块
Spring Framework五大功能模块
|
开发框架 安全 Java
Spring Framework远程代码执行漏洞复现(CVE-2022-22965)
Spring Framework存在远程代码执行漏洞,攻击者可通过该漏洞执行系统命令。
398 1
Spring Framework远程代码执行漏洞复现(CVE-2022-22965)
|
前端开发 Java 数据库连接
【面试题精讲】Spring Framework有哪些模块?
【面试题精讲】Spring Framework有哪些模块?
|
安全 Java 测试技术
Spring Framework中的Bean生命周期2
Spring Framework中的Bean生命周期2
74 0