创建并运行一个 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 中的时候,就会出现异常。


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

目录
相关文章
|
30天前
|
XML JSON Java
使用IDEA+Maven搭建整合一个Struts2+Spring4+Hibernate4项目,混合使用传统Xml与@注解,返回JSP视图或JSON数据,快来给你的SSH老项目翻新一下吧
本文介绍了如何使用IntelliJ IDEA和Maven搭建一个整合了Struts2、Spring4、Hibernate4的J2EE项目,并配置了项目目录结构、web.xml、welcome.jsp以及多个JSP页面,用于刷新和学习传统的SSH框架。
30 0
使用IDEA+Maven搭建整合一个Struts2+Spring4+Hibernate4项目,混合使用传统Xml与@注解,返回JSP视图或JSON数据,快来给你的SSH老项目翻新一下吧
|
30天前
|
前端开发 JavaScript Java
spring boot+vue前后端项目的分离(我的第一个前后端分离项目)
该博客文章介绍了作者构建的第一个前后端分离项目,使用Spring Boot和Vue技术栈,详细说明了前端Vue项目的搭建、后端Spring Boot项目的构建过程,包括依赖配置、数据库连接、服务层、数据访问层以及解决跨域问题的配置,并展示了项目的测试结果。
spring boot+vue前后端项目的分离(我的第一个前后端分离项目)
|
1月前
|
IDE Java Shell
如何快速搭建一个 Spring Boot 项目?
本指南介绍如何通过Spring Initializr创建一个基本的Spring Boot Web项目。首先访问`start.spring.io`,选择Maven项目、Java语言、Spring Boot版本3.1.0、Java 17,并勾选Spring Web依赖。点击“Generate”下载项目模板。解压后,IDE打开项目并修改`DemoApplication.java`,添加REST控制器以实现一个简单的“Hello World!”服务。通过`@RestController`和`@GetMapping`注解定义Web端点,使用`@RequestParam`获取URL参数。
|
1月前
|
IDE Java Shell
如何快速搭建一个 Spring Boot 项目?
Spring Boot 可以用最少的配置来快速创建一个独立的、生产级的 Spring 应用程序。 本文介绍如何快速搭建一个 Spring Boot「Hello World!」项目。
|
30天前
|
前端开发 Java 测试技术
单元测试问题之在Spring MVC项目中添加JUnit的Maven依赖,如何操作
单元测试问题之在Spring MVC项目中添加JUnit的Maven依赖,如何操作
|
30天前
|
Dubbo Java Nacos
【实战攻略】破解Dubbo+Nacos+Spring Boot 3 Native打包后运行异常的终极秘籍——从零开始彻底攻克那些让你头疼不已的技术难题!
【8月更文挑战第15天】Nacos作为微服务注册与配置中心受到欢迎,但使用Dubbo+Nacos+Spring Boot 3进行GraalVM native打包后常遇运行异常。本文剖析此问题及其解决策略:确认GraalVM版本兼容性;配置反射列表以支持必要类和方法;采用静态代理替代动态代理;检查并调整配置文件;禁用不支持的功能;利用日志和GraalVM诊断工具定位问题;根据诊断结果调整GraalVM配置。通过系统排查方法,能有效解决此类问题,确保服务稳定运行。
51 0
|
1月前
|
Java Windows Spring
Spring Boot CMD 运行日志输出中文乱码
Spring Boot CMD 运行日志输出中文乱码
22 0
|
1月前
|
设计模式 算法 Java
Spring Boot 项目怎么使用策略模式?
策略模式是一种设计模式,它允许在运行时选择不同的算法或行为。此模式通过定义一系列算法并将它们封装在独立的类中实现,这些类可以互相替换。这样可以根据不同情况动态选择最适合的算法。 在Spring框架中,可以通过依赖注入来实现策略模式。首先定义一个抽象策略类(接口或抽象类),然后创建具体策略类实现不同的算法。具体策略类通过`@Service`注解并在名称中指定特定的策略(如加法、减法等)。在上下文类(如Service类)中,通过`@Resource`注入策略对象的Map集合,根据需要选择并执行相应的策略。
|
24天前
|
缓存 Java Maven
Java本地高性能缓存实践问题之SpringBoot中引入Caffeine作为缓存库的问题如何解决
Java本地高性能缓存实践问题之SpringBoot中引入Caffeine作为缓存库的问题如何解决