java 的春天_什么是春天? Java的基于组件的开发

java 的春天

在21世纪初出现的基于组件的框架中,Spring也许是最好的。 它极大地改善了开发人员在基于Java的应用程序中编写和交付基础结构代码的方式。 自成立以来,Spring被公认为企业Java开发的领先框架。 作为端到端的应用程序框架,Spring反映了Java EE的某些功能,但是它提供了功能和编程约定的组合,这些在其他地方是找不到的。

本文介绍了Spring及其核心编程哲学和方法:控制反转和依赖注入。 您还将开始使用Spring注释和一些动手的编码示例。

依赖注入和控制反转

Spring的核心思想是,您不必自己管理对象关系,而是将它们卸载到框架中。 控制反转(IOC)是用于管理对象关系的方法。 依赖注入是实现IOC的机制。 由于这两个概念相关但不同,因此让我们更仔细地考虑它们:

  • 控制反转 (IOC)的作用恰如其名:将传统的控制层次结构反转以实现对象关系。 关系不是由应用程序代码定义对象之间如何关联的,而是由框架定义的。 作为一种方法,IOC为对象关系引入了一致性和可预测性,但是它确实要求您(作为开发人员)放弃一些细粒度的控制。
  • 依赖项注入 (DI)是一种机制,框架可以将依赖项“注入”到您的应用程序中。 这是IOC的实际实施。 从某种意义上说,依赖注入取决于多态性 ,它允许引用类型的实现根据框架中的配置而改变。 该框架注入变量引用,而不是在应用程序代码中手动实现它们。

JSR-330

像Java世界中的许多地方一样,Spring作为一种狂野的创新而开始,在某种程度上已经被标准规范所吸收。 在这种情况下,JSR-330是Java标准。 关于JSR-330规范的好处是,您可以在其他地方使用它,并将在Spring之外的其他地方看到它的使用。 您可以不使用Spring而使用它。 但是,Spring给桌面带来了更多的好处。

例子1:Spring依赖注入

通过使用它们可以最好地理解控制反转和依赖注入,因此我们将以一个快速的编程示例开始。

假设您正在为汽车建模。 如果使用普通的旧Java建模,那么Car类上可能有一个接口成员来引用Engine接口,如清单1所示。

清单1.普通的旧Java中的对象关系

public Interface Engine() { ... }

public class Car {
  private Engine engine;
  public Engine getEngine() { ... }
  public void setEngine(Engine engine) { ... }
}

清单1包含一个Engine类型的接口,以及一个具体的Car类型的类,该类引用了Engine 。 (请注意,在实际的编程场景中,这些文件将放在单独的文件中。)现在,当您创建Car实例时,您将设置关联,如清单2所示。

清单2.使用Engine界面创建汽车

// ...
Car newCar = new Car();
Engine sixCylEngine = new InlineSixCylinderEngine();
newCar.setEngine(sixCylEngine );
// Do stuff with the car

请注意,您首先创建了Car对象。 然后,您创建一个满足Engine接口的新对象,并将其手动分配给Car对象。 这就是对象关联在普通的旧Java中的工作方式。

在Spring中建模类和对象

现在让我们看一下Spring中的相同示例。 在这里,您可以执行清单3中所示的操作。从Car类开始,但是在这种情况下,向它添加一个注释: @Inject

清单3.在Spring中使用@Inject批注的示例

public class Car {
  @Inject
  private Engine engine;
  // ...
}

使用@Inject批注(或使用@Autowired ,如果您愿意的话)告诉Spring根据一组规则搜索上下文并将对象自动注入到引用中。

接下来,考虑@Component批注,如清单4所示。

清单4. @Component批注

@Component
public class InlineSixCylinderEngine implements Engine{
  //...
}

@Component注释一个类告诉Spring它可用于完成注入。 在这种情况下,将InlineSixCylEngine ,因为它可用并且满足关联的接口要求。 在Spring,这称为“自动接线”注射。 (有关Spring的@Autowired注释的更多信息,请参见下文。)

解耦作为设计原则

带有依赖项注入的控件倒置从代码中删除了具体的依赖项源。 程序中没有任何地方对Engine实现进行过硬编码的引用。 这是将解耦作为软件设计原理的一个示例。 将应用程序代码与实现分离开来可使您的代码更易于管理和维护。 该应用程序不太了解其各部分如何装配在一起,但是在应用程序生命周期的任何时候进行更改都容易得多。

@Autowired与@Inject

@Autowired@Inject做同样的事情。 但是,@ @Inject是Java标准注释,而@Autowired特定于Spring。 它们都具有相同的目的,即告诉DI引擎使用匹配的对象注入字段或方法。 您可以在Spring中使用任何一个。

Spring框架概述

现在您已经看到了一些Spring代码,让我们来概述一下框架及其组件。 如您所见,该框架包含四个主要模块,这些模块分为多个包。 Spring将为您使用的模块提供相当大的灵活性。

  • 核心容器
    • 核心
    • 语境
    • 表达语言
  • 面向方面的编程(AOP)
    • 行动计划
    • 方面
    • 仪器仪表
  • 资料存取与整合
    • JDBC
    • JPA / ORM
    • JMS
    • 交易次数
  • 网页
    • 网络/ REST
    • Servlet
    • Struts

让我们开始使用两个更常用的Spring功能,而不是在这里介绍所有内容。

启动一个新项目:Spring Boot

我们将使用Spring Boot创建一个示例项目,用于演示Spring功能。 Spring Boot使启动新项目变得更加容易,您将自己看到。 首先,请看下面显示的主类。 在Spring Boot中,我们可以使用main()方法获取一个主类,然后选择独立运行它,或者选择打包运行在Tomcat之类的容器中。

清单5列出了我们的主类的大纲,这些大纲位于标准的src/main/java/hello位置。

清单5. Spring Boot的主类

package hello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

请注意上述代码的两件事:首先,所有工作都抽象到框架中。 主类会启动应用程序,但对应用程序的工作方式或交付功能一无所知。 其次, SpringApplication.run()完成启动应用程序并传递Application类本身的实际工作。 同样,应用程序所做的工作在这里并不明显。

@SpringBootApplication批注包装了一些标准批注,并告诉Spring查看组件主类所在的包。 在我们之前的示例中,对于汽车和引擎,这将允许Spring查找所有带有@Component@Inject注释的@Component 。 该过程本身称为组件扫描 ,可以高度自定义。

您可以使用标准的mvn clean install构建该应用程序,并可以使用Spring Boot目标( mvn spring-boot:runmvn spring-boot:run该应用程序。 在此之前,让我们看一下该应用程序的pom.xml文件。

清单6.入门pom.xml

<groupId>com.javaworld</groupId>
    <artifactId>what-is-spring</artifactId>
    <version>1.0.0</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.3.RELEASE</version>
    </parent>

    <dependencies>
    </dependencies>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

请注意上述代码中的两个重要功能:

  1. parent元素依赖于spring-boot-starter-parent项目。 该父项目定义了许多有用的默认值,例如JDK 1.8的默认编译器级别。 在大多数情况下,您可以相信它知道自己在做什么。 例如,您可以忽略许多常见依赖项的版本号, SpringBootParent会将版本设置为兼容。 当增加父级的版本号时,依赖项版本和默认值也会更改。
  2. spring-boot-maven-plugin允许可执行的JAR / WAR打包和就地run (通过mvn spring-boot:run命令)。

将Spring Web添加为依赖项

到目前为止,我们已经能够使用spring-boot来限制spring-boot和运行应用程序而进行的工作量。 现在,让我们添加一个依赖项,看看在浏览器中获取内容有多快。

清单7.将Spring Web添加到项目

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>

注意

Spring将自动检测哪些文件已更改并相应地进行编译。 您只需执行mvn spring-boot:run即可进行更改。

既然我们已经完成了基本的项目设置,就可以为两个示例做好准备了。

示例2:使用Spring Web构建RESTful端点

我们已经使用spring-boot-starter-web引入了一些对构建Web应用程序有用的依赖项。 接下来,我们将为URL路径创建路由处理程序。 Spring的Web支持是Spring MVC (模型-视图-控制器)模块的一部分,但是请不要担心:Spring Web也为构建RESTful端点提供了全面而有效的支持。

用来处理URL请求的类称为控制器 ,如清单8所示。

清单8. Spring MVC REST控制器

package hello;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class GreetingController {

    @RequestMapping(value = "/hi", method = RequestMethod.GET)
    public String hi(@RequestParam(name="name", required=false, defaultValue="JavaWorld") String name, Model model) {
        return "Hello " + name;
    }

}

@Controller批注

@Controller批注将一个类标识为控制器。 标记为控制器的类也将自动识别为组件类,这使其成为自动装配的候选对象。 无论何时需要此控制器,都将其插入框架。 在这种情况下,我们将其插入MVC系统以处理请求。

控制器是一种特殊的组件。 它支持您在hi()方法上看到的@RequestMapping@ResponseBody批注。 这些注释告诉框架如何将URL请求映射到应用程序。

此时,您可以使用mvn spring-boot:run运行该应用程序。 当您打入/hi URL时,您将收到类似“ Hello,JavaWorld”的响应。

请注意,Spring是如何利用自动装配组件的基础,并交付了整个Web框架的。 使用Spring,您不必显式地将任何东西连接在一起!

@Request批注

@RequestMapping允许您定义URL路径的处理程序。 选项包括定义所需的HTTP方法,这是我们在本例中所做的。 离开RequestMethod将指示程序处理所有HTTP方法类型。

@RequestParam参数批注允许我们将请求参数直接映射到方法签名中,包括要求某些参数和定义默认值(如此处所做的那样)。 我们甚至可以使用@RequestBody参数注释将请求主体映射到类。

REST和JSON响应

如果要创建REST端点,并且想从该方法返回JSON,则可以使用@ResponseBody对该方法进行@ResponseBody 。 然后,响应将自动打包为JSON。 在这种情况下,您将从方法中返回一个对象。

在Spring Web上使用MVC

与Struts相似,Spring Web模块可以轻松地用于真正的模型-视图-控制器设置。 在这种情况下,您将以给定的模板语言(如Thymeleaf )返回映射,而Spring将解析该映射,提供传递给它的模型并呈现响应。

例3:使用JDBC的Spring

现在,让我们对请求处理程序做一些更有趣的事情:让我们从数据库中返回一些数据。 就本示例而言,我们将使用H2数据库 。 幸运的是,Spring Boot开箱即用地支持内存中的H2 DB。

翻译自: https://www.infoworld.com/article/3444936/what-is-spring-component-based-development-for-java.html

java 的春天

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值