创建并运行一个 Spring项目(上)

简介: 创建并运行一个 Spring项目(上)

第一个 Spring 项目



步骤


aca5789823004a9eb72e74c0552caa0e.png


1. 创建一个 spring 项目


(1) 创建一个 maven 项目


spring 是基于 maven 项目的,所以我们首先就要选择 maven 项目。


9d8fc53cb7a04572827bb582276c10ea.png


(2) 添加 spring 框架支持 ( spring-context + spring-beans )


注意:

从 maven 仓库中找到这两个依赖,最好将两者的版本选择一样的。


540a6aa2da4042eaaa59258270bcabb8.png


<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.3.18</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
    <version>5.3.18</version>
</dependency>


(3) 配置国内源


我需要事先声明,配置国内源的时候,应在网络良好的情况下配置,否则在后续运行 spring 项目的过程中,可能会出现奇奇怪怪的异常。



settings.xml 文件中的内容:


<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at
    http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
-->
<!--
 | This is the configuration file for Maven. It can be specified at two levels:
 |
 |  1. User Level. This settings.xml file provides configuration for a single user,
 |                 and is normally provided in ${user.home}/.m2/settings.xml.
 |
 |                 NOTE: This location can be overridden with the CLI option:
 |
 |                 -s /path/to/user/settings.xml
 |
 |  2. Global Level. This settings.xml file provides configuration for all Maven
 |                 users on a machine (assuming they're all using the same Maven
 |                 installation). It's normally provided in
 |                 ${maven.conf}/settings.xml.
 |
 |                 NOTE: This location can be overridden with the CLI option:
 |
 |                 -gs /path/to/global/settings.xml
 |
 | The sections in this sample file are intended to give you a running start at
 | getting the most out of your Maven installation. Where appropriate, the default
 | values (values used when the setting is not specified) are provided.
 |
 |-->
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
  <!-- localRepository
   | The path to the local repository maven will use to store artifacts.
   |
   | Default: ${user.home}/.m2/repository
  <localRepository>/path/to/local/repo</localRepository>
  -->
  <!-- interactiveMode
   | This will determine whether maven prompts you when it needs input. If set to false,
   | maven will use a sensible default value, perhaps based on some other setting, for
   | the parameter in question.
   |
   | Default: true
  <interactiveMode>true</interactiveMode>
  -->
  <!-- offline
   | Determines whether maven should attempt to connect to the network when executing a build.
   | This will have an effect on artifact downloads, artifact deployment, and others.
   |
   | Default: false
  <offline>false</offline>
  -->
  <!-- pluginGroups
   | This is a list of additional group identifiers that will be searched when resolving plugins by their prefix, i.e.
   | when invoking a command line like "mvn prefix:goal". Maven will automatically add the group identifiers
   | "org.apache.maven.plugins" and "org.codehaus.mojo" if these are not already contained in the list.
   |-->
  <pluginGroups>
    <!-- pluginGroup
     | Specifies a further group identifier to use for plugin lookup.
    <pluginGroup>com.your.plugins</pluginGroup>
    -->
  </pluginGroups>
  <!-- proxies
   | This is a list of proxies which can be used on this machine to connect to the network.
   | Unless otherwise specified (by system property or command-line switch), the first proxy
   | specification in this list marked as active will be used.
   |-->
  <proxies>
    <!-- proxy
     | Specification for one proxy, to be used in connecting to the network.
     |
    <proxy>
      <id>optional</id>
      <active>true</active>
      <protocol>http</protocol>
      <username>proxyuser</username>
      <password>proxypass</password>
      <host>proxy.host.net</host>
      <port>80</port>
      <nonProxyHosts>local.net|some.host.com</nonProxyHosts>
    </proxy>
    -->
  </proxies>
  <!-- servers
   | This is a list of authentication profiles, keyed by the server-id used within the system.
   | Authentication profiles can be used whenever maven must make a connection to a remote server.
   |-->
  <servers>
    <!-- server
     | Specifies the authentication information to use when connecting to a particular server, identified by
     | a unique name within the system (referred to by the 'id' attribute below).
     |
     | NOTE: You should either specify username/password OR privateKey/passphrase, since these pairings are
     |       used together.
     |
    <server>
      <id>deploymentRepo</id>
      <username>repouser</username>
      <password>repopwd</password>
    </server>
    -->
    <!-- Another sample, using keys to authenticate.
    <server>
      <id>siteServer</id>
      <privateKey>/path/to/private/key</privateKey>
      <passphrase>optional; leave empty if not used.</passphrase>
    </server>
    -->
  </servers>
  <!-- mirrors
   | This is a list of mirrors to be used in downloading artifacts from remote repositories.
   |
   | It works like this: a POM may declare a repository to use in resolving certain artifacts.
   | However, this repository may have problems with heavy traffic at times, so people have mirrored
   | it to several places.
   |
   | That repository definition will have a unique id, so we can create a mirror reference for that
   | repository, to be used as an alternate download site. The mirror site will be the preferred
   | server for that repository.
   |-->
  <mirrors>
   <mirror>
        <id>alimaven</id>
        <name>aliyun maven</name>
        <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
        <mirrorOf>central</mirrorOf>        
      </mirror>
    <!-- mirror
     | Specifies a repository mirror site to use instead of a given repository. The repository that
     | this mirror serves has an ID that matches the mirrorOf element of this mirror. IDs are used
     | for inheritance and direct lookup purposes, and must be unique across the set of mirrors.
     |
    <mirror>
      <id>mirrorId</id>
      <mirrorOf>repositoryId</mirrorOf>
      <name>Human Readable Name for this Mirror.</name>
      <url>http://my.repository.com/repo/path</url>
    </mirror>
     -->
  </mirrors>
  <!-- profiles
   | This is a list of profiles which can be activated in a variety of ways, and which can modify
   | the build process. Profiles provided in the settings.xml are intended to provide local machine-
   | specific paths and repository locations which allow the build to work in the local environment.
   |
   | For example, if you have an integration testing plugin - like cactus - that needs to know where
   | your Tomcat instance is installed, you can provide a variable here such that the variable is
   | dereferenced during the build process to configure the cactus plugin.
   |
   | As noted above, profiles can be activated in a variety of ways. One way - the activeProfiles
   | section of this document (settings.xml) - will be discussed later. Another way essentially
   | relies on the detection of a system property, either matching a particular value for the property,
   | or merely testing its existence. Profiles can also be activated by JDK version prefix, where a
   | value of '1.4' might activate a profile when the build is executed on a JDK version of '1.4.2_07'.
   | Finally, the list of active profiles can be specified directly from the command line.
   |
   | NOTE: For profiles defined in the settings.xml, you are restricted to specifying only artifact
   |       repositories, plugin repositories, and free-form properties to be used as configuration
   |       variables for plugins in the POM.
   |
   |-->
  <profiles>
    <!-- profile
     | Specifies a set of introductions to the build process, to be activated using one or more of the
     | mechanisms described above. For inheritance purposes, and to activate profiles via <activatedProfiles/>
     | or the command line, profiles have to have an ID that is unique.
     |
     | An encouraged best practice for profile identification is to use a consistent naming convention
     | for profiles, such as 'env-dev', 'env-test', 'env-production', 'user-jdcasey', 'user-brett', etc.
     | This will make it more intuitive to understand what the set of introduced profiles is attempting
     | to accomplish, particularly when you only have a list of profile id's for debug.
     |
     | This profile example uses the JDK version to trigger activation, and provides a JDK-specific repo.
    <profile>
      <id>jdk-1.4</id>
      <activation>
        <jdk>1.4</jdk>
      </activation>
      <repositories>
        <repository>
          <id>jdk14</id>
          <name>Repository for JDK 1.4 builds</name>
          <url>http://www.myhost.com/maven/jdk14</url>
          <layout>default</layout>
          <snapshotPolicy>always</snapshotPolicy>
        </repository>
      </repositories>
    </profile>
    -->
    <!--
     | Here is another profile, activated by the system property 'target-env' with a value of 'dev',
     | which provides a specific path to the Tomcat instance. To use this, your plugin configuration
     | might hypothetically look like:
     |
     | ...
     | <plugin>
     |   <groupId>org.myco.myplugins</groupId>
     |   <artifactId>myplugin</artifactId>
     |
     |   <configuration>
     |     <tomcatLocation>${tomcatPath}</tomcatLocation>
     |   </configuration>
     | </plugin>
     | ...
     |
     | NOTE: If you just wanted to inject this configuration whenever someone set 'target-env' to
     |       anything, you could just leave off the <value/> inside the activation-property.
     |
    <profile>
      <id>env-dev</id>
      <activation>
        <property>
          <name>target-env</name>
          <value>dev</value>
        </property>
      </activation>
      <properties>
        <tomcatPath>/path/to/tomcat/instance</tomcatPath>
      </properties>
    </profile>
    -->
  </profiles>
  <!-- activeProfiles
   | List of profiles that are active for all builds.
   |
  <activeProfiles>
    <activeProfile>alwaysActiveProfile</activeProfile>
    <activeProfile>anotherAlwaysActiveProfile</activeProfile>
  </activeProfiles>
  -->
</settings>


里面最重要的就是设置国内镜像,我当前设置的是 " 阿里云 "。


078066b008b64b02845bea8a39d00e70.png


(4) 创一个启动类并添加 main 方法


0f93cbf512bc44c490596b47d0e8f647.png


2. 将 bean 对象存储到 spring 容器中


(1) 在 spring 项目中添加配置文件


在 【 resources 】目录下创建【 spring-config.xml 】文件,并往里面放入代码。


注意:

这里的【 resources 】目录不能选错,而 " xml 文件 " 的名字可以自定义,但是最好和我一样,顾名思义,它代表 " spring 配置文件 ",这是一种规范。


882c1df57e0a4e97b344fbb0032ee94f.png


【 spring-config.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 http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>



(2) 创建一个 bean 对象


假设我们创建一个 User 类,并计划外面往里面传入一个 name 参数。


a644fcbe9ffb48e2b0611c7b8c9824c0.png


(3) 将 bean 对象通过配置文件注册到 spring 中


<?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 http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="user" class="beans.User"> </bean>
</beans>


将 bean 标签中的," id " 和 " class " 想象成一种 Map 键值对结构,后续通过 " id ",就可以得到 " class " 类种的一些信息。


注意:


" class " 的写法是固定的,精确到哪个包下的哪个类。

" id " 的写法是非固定的,但是最好写成小驼峰,并与类的名字联系起来。这样有两点好处,一是对外规范;二是下次利用 " id " 从 spring 容器中取对象的时候,可以很好地记忆。


251adca9afaa4c3a9baea8cc63a7e26d.png


3. 将 bean 对象从 spring 中取出来


(1) 在启动类中,先得到 spring 上下文对象

(2) 通过上下文对象提供的方法,获取我们自己需要使用的 bean 对象

(3) 使用 bean 对象


public class Run {
    public static void main(String[] args) {
        // 1. 得到 spring 上下文对象
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        // 2. 根据上下文对象提供的方法获取到 bean
        User user = (User) context.getBean("user");
        // User user1 = new User(); // 传统写法
        // 3. 使用
        user.hello("李明");
    }
}


展示结果:


eb17727c1a5d4fde9d1026dfbf44941b.png


注意


注意1


1. 在上面的代码中,我们和以往的做法不同,以往是通过 new 一个 User 类,来创建一个 user 对象。而当前的做法是,我们先往 spring 容器中放对象,然后再将对象取出来。


至于为什么要这么做,我的上一篇博客就介绍到了它的关键之处:解耦。


我们平时利用 new 的方式创建一个对象,当我们对于类的构造方法进行改变时 ( 比方说临时加一个参数 ),那么,一个项目中所有用到 User 类的其他类,就统统需要修改。然而,利用 spring 容器作为中间介质,情况就不同了,从 spring 取出来的对象,是不依赖原始类的,也就是说,当我们之前的 User 类发生了改变,与 spring 中的对象毫无关联。


注意2


2. 在 main 方法中,一些关于 spring 配置文件的参数,在传入方法的时候,不能出错,否则就会出现这样那样的异常。所以,在我们之前配置 " xml " 文件的时候,就需要保持规范。


如果修改之后,编译过程的代码没问题,但依旧出现了异常,这可能就是缓存的问题。这时候,我们就需要手动删除 【target】目录下的所有文件,再次编译。因为 JVM 实际上最终运行的是 " .class " 文件,我们只需要把之前缓存的 " .class " 文件清空,再次利用 IDEA 编译的时候,就会重新生成 " .class " 文件,这样就可能有效果。


5b32d46f56e44a61a8512d534b939790.png


注意3 ( 经典面试题 )


3. 在上面的例子中,我们获取 spring 上下文对象,是通过 ApplicationContext 这个类来完成的,实际上,我们也可以通过 BeanFactory 这个类 来作为 spring 的上下文对象。

public class Run {
    public static void main(String[] args) {
        // 1. 得到 spring 上下文对象
        BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("spring-config.xml"));
        // 2. 根据上下文对象提供的方法获取到 bean
        User user = (User) beanFactory.getBean("user");
        // 3. 使用
        user.hello("杰克");
    }
}


展示结果:


6e237de1205b424cb4199bf8b1d2fefb.png


就因为上面的两个不同的获取对象方法,所以引入了一个经典面试题:


谈谈 ApplicationContext 和 BeanFactory 之间的区别和联系。

(1) 相同点:都可以利用 " getBean 方法 ",从容器中获取 bean 对象。


(2) 不同点:


① ApplicationContext 属于 BeanFactory 的子类,BeanFactory 只提供了基础访问Bean 的方法,而 ApplicationContext 除了拥有 BeanFactory 的所有功能之外,还拥有一些独立的特性,比如对国际化的支持、资源访问的支持、以及事件和传播等方面的支持。


因为在 Java 中,一般来说,子类继承父类,那么子类直接就会拥有父类的功能,然而,对于父类来说,子类拥有的独立特性,父类很多是没有的。因为这些独立的特性,就是子类衍生出来的,也是作为区分父类的一种表现形式。


② 从性能方面来说二者是不同的,BeanFactory 是按需加载,它很像单例模式中的懒懒汉模式,当我们需要用到了某个 bean 对象,它才会临时加载。

然而,ApplicationContext 是饿汉模式,在我们创建此类的时候,它会一次性地将所有的 bean 对象都加载起来,以备后续使用。


怎么验证呢?我们可以再创建一个 " Admin " 类,然后在 " Admin " 和 " User " 的构造方法中,做一些打印处理,然后在启动类的 main 方法中,看看两个类的加载的现象即可。结果就是,ApplicationContext 直接加载了 " Admin " 和 " User " ,而 BeanFactory 什么也没做。


③ 二者并无好坏,只能说根据场景自由选择吧,但是,ApplicationContext 确实是我们日常开发中,用的最多的情况。


注意4


4. 上述的 " getBean 方法 " 有很多重载,传入的参数可以由我们自己控制。


// 1
User user = (User) context.getBean("user");
// 2
User user = context.getBean(User.class);
// 3
User user = context.getBean("user", User.class);


第二种不建议使用,虽然写法简单,但容易出问题。当同一个类多次被注入到 spring 中的时候,就会出现异常。


第三种建议使用,因为它指明了当前需要找寻的是哪个类,所以就避免了强制转换这样的麻烦事。

目录
相关文章
|
4月前
|
Java 关系型数据库 数据库连接
Spring Boot项目集成MyBatis Plus操作PostgreSQL全解析
集成 Spring Boot、PostgreSQL 和 MyBatis Plus 的步骤与 MyBatis 类似,只不过在 MyBatis Plus 中提供了更多的便利功能,如自动生成 SQL、分页查询、Wrapper 查询等。
394 3
|
4月前
|
Java 测试技术 Spring
简单学Spring Boot | 博客项目的测试
本内容介绍了基于Spring Boot的博客项目测试实践,重点在于通过测试驱动开发(TDD)优化服务层代码,提升代码质量和功能可靠性。案例详细展示了如何为PostService类编写测试用例、运行测试并根据反馈优化功能代码,包括两次优化过程。通过TDD流程,确保每项功能经过严格验证,增强代码可维护性与系统稳定性。
230 0
|
4月前
|
存储 Java 数据库连接
简单学Spring Boot | 博客项目的三层架构重构
本案例通过采用三层架构(数据访问层、业务逻辑层、表现层)重构项目,解决了集中式开发导致的代码臃肿问题。各层职责清晰,结合依赖注入实现解耦,提升了系统的可维护性、可测试性和可扩展性,为后续接入真实数据库奠定基础。
403 0
|
4月前
|
前端开发 Java API
酒店管理系统基于 JavaFX Spring Boot 和 React 经典项目重构实操
本文介绍了基于现代技术栈的酒店管理系统开发方案,整合了JavaFX、Spring Boot和React三大技术框架。系统采用前后端分离架构,JavaFX构建桌面客户端,React开发Web管理界面,Spring Boot提供RESTful API后端服务。核心功能模块包括客房管理和客户预订流程,文中提供了JavaFX实现的客房管理界面代码示例和React开发的预订组件代码,展示了如何实现客房信息展示、添加修改操作以及在线预订功能。
296 1
|
4月前
|
Java 应用服务中间件 Maven
第01课:Spring Boot开发环境搭建和项目启动
第01课:Spring Boot开发环境搭建和项目启动
647 0
|
7月前
|
SQL 前端开发 Java
深入理解 Spring Boot 项目中的分页与排序功能
本文深入讲解了在Spring Boot项目中实现分页与排序功能的完整流程。通过实际案例,从Service层接口设计到Mapper层SQL动态生成,再到Controller层参数传递及前端页面交互,逐一剖析每个环节的核心逻辑与实现细节。重点包括分页计算、排序参数校验、动态SQL处理以及前后端联动,确保数据展示高效且安全。适合希望掌握分页排序实现原理的开发者参考学习。
477 4
|
Java 程序员 索引
Spring的三种创建方式和各种属性的注入(二)
Spring的三种创建方式和各种属性的注入(二)
161 0
Spring的三种创建方式和各种属性的注入(二)
|
4月前
|
Java Spring 容器
SpringBoot自动配置的原理是什么?
Spring Boot自动配置核心在于@EnableAutoConfiguration注解,它通过@Import导入配置选择器,加载META-INF/spring.factories中定义的自动配置类。这些类根据@Conditional系列注解判断是否生效。但Spring Boot 3.0后已弃用spring.factories,改用新格式的.imports文件进行配置。
866 0
|
1月前
|
JavaScript Java Maven
【SpringBoot(二)】带你认识Yaml配置文件类型、SpringMVC的资源访问路径 和 静态资源配置的原理!
SpringBoot专栏第二章,从本章开始正式进入SpringBoot的WEB阶段开发,本章先带你认识yaml配置文件和资源的路径配置原理,以方便在后面的文章中打下基础
266 3