Springboot开发开发技术以及易错点调整-21

了解IOC和DI

Ioc(Inversion of Control)控制反转

在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。理解好Ioc的关键是要明白以下两点:

  • 谁控制谁,控制什么?是由Ioc容器来控制对象的创建,而不是传统的在对象内部通过new进行创建对象。主要控制的就是外部资源的获取(不仅仅是java对象还包括文件等)
  • 为何是反转,哪些方面反转了?反转是指由容器来帮忙创建及注入依赖对象,而不是像传统开发在内部通过new主动创建依赖,所反转的是依赖对象的获取过程被反转了。

IoC是一个重要的面向对象编程的法则,指导如何设计出松耦合、更优良的程序。传统应用程序都是由我们在类内部主动创建依赖对象,从而导致类与类之间高耦合,难于测试;有了IoC容器后,
把创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,所以对象与对象之间是松散耦合。

DI(Dependency Injection)依赖注入

组件之间的依赖关系由容器在运行期决定,即由容器动态的将某个依赖关系注入到组件之中。依赖注入的主要目的为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台。 理解DI的关键是要理解以下内容:

  • 谁依赖于谁?当然是应用程序依赖于IoC容器;
  • 为什么需要依赖?应用程序需要IoC容器来提供对象需要的外部资源;
  • 谁注入谁?很明显是IoC容器注入应用程序某个对象,应用程序依赖的对象;
  • 注入了什么?就是注入某个对象所需要的外部资源(包括对象、资源、常量数据)。;

IoC和DI本质上是对同一个概念的不同角度描述。这里有一个关键的组织者就是IoC容器,Ioc容器具有依赖注入功能的容器,IoC容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。应用程序无需直接在代码中new相关的对象,应用程序由IoC容器进行组装。它的存在可以让服务消费者不直接依赖于服务提供者的组件设计方式,符合减少类与类之间依赖的设计原则。

Bean作用域

在面向对象程序设计中一般指对象或变量之间的可见范围。而在Spring容器中是指其创建的Bean对象相对于其他Bean对象的请求可见范围。 Spring提供“singleton”和“prototype”两种基本作用域,另外提供“request”、“session”、“global session”三种web作用域。

application配置文件特殊用法

使用配置中的变量

可以使用${}直接使用spring配置文件中的变量,比如:

spring.application.name = springdemo

apiGroupName = ${spring.application.name}

使用随机数

要是应对重复的可能性,比如端口号。这样也方便注册中心的管理。

#10之间的随机数
server.port=${random.int(10)}
#10~20之间的随机数
server.port=${random.int[10,20]}

多模块配置文件

SpringBoot从2.4.x版本开始支持了通过spring.config.import属性导入多种途径的配置文件。spring.config.import属性允许我们在主配置文件中引入其他配置文件,这使得配置文件更加模块化,易于维护和管理。之后就可以用@ConfigurationProperties或@Value来注入使用了。

  • classpath: 导入classpath下的配置文件
spring:
  config:
    import:
    # 导入src/main/resource/default.properties配置文件
    - classpath:/default/default.properties
    # 导入src/main/resource/service.yml配置文件
    - classpath:/service/service.yml
  • optional: 导入系统目录下的配置文件
spring:
  config:
    import:
    # 导入系统目录/Users/yuqiyu/Downloads/system.properties配置文件
    - optional:/Users/yuqiyu/Downloads/system.properties
  • 导入Nacos配置中心的配置文件
spring:
  config:
    import:
    # 导入nacos配置中心的配置文件
    - optional:nacos:spring-config-import-example.yaml

命令行启动参数配置

命令行运行

在用命令行方式启动 SpringBoot 应用时,连续的两个减号 – 就是对 application.properties 中的属性值进行赋值的标识,比如下列命令,将添加/替换掉application.properties中同名的属性。

java -jar xxx.jar --server.port=8888

springboot配置优先级,从高到低:
命令行–操作系统(System.getProperties())–系统环境变量(Enviorent)–application-profile.properties–application.properties
需要注意读取properties文件时先读jar外的同路径文件再读jar包中的同名文件。

设置Macos系统JDK

打开终端,编辑.bashrc或.bash_profile文件,一般是编辑.bash_profile文件,添加以下行:

export JAVA_HOME=/path/to/your/jdk
export PATH=$JAVA_HOME/bin:$PATH

然后执行

source ~/.bash_profile

指定JDK版本执行

这个命令在mac下好用,/java21是随意写的一个值,测试后,发现其是采用代码编译的版本,同时再查找本地是否有相应的JDK。

JAVA_HOME=/java21 java -jar your-application.jar

另一个官方命令如下,但在mac下不好用,不知道为啥

java -Djava.home=/opt/jdk1.8.0_231 -jar your-application.jar

核心注解

@Configuration

通过@Configuration注解的类将被作为配置类使用,使用@Configuration 注解的类本身也是一个Bean,同时@Configuration在实现上也会被@Component注解,所以不需要再有@Component标识。

import org.springframework.context.annotation.Configuration;
@Configuration("ctxConfig")
public class ApplicationContextConfig {
//定义Bean配置元数据 
}

@ConfigurationProperties

一般要和类的@Component一起使用,目的是将使用了 @ConfigurationProperties 注解的配置类生效,将该类注入到 IOC 容器中统一管理。

@Component
@EnableConfigurationProperties(DemoConfig.class)
public class Test implements ApplicationRunner {

    @Autowired
    DemoConfig demoConfig;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println(demoConfig);
    }
}

@Bean

@Bean注解主要用于标识在方法上,同时方法所在的类也要用@Component标识。方法名默认就是Bean名,该方法返回值就是Bean对象。

@Bean
@Scope(value="prototype")
public Printer prototypePrinter() {
    return new Printer();
 }
 
@Bean
@Scope(value="singleton")
public Printer singletonPrinter() {
    return new Printer();
}

@Import

这个注解主要用于类上,它可以把非bean变成一个bean类(即不在springboot扫描范围内的类)。此注解一般也被设计用于模块化配置类。

@Import({TestBean1.class,
        ImportBeanByConfig.class,
        ImportBeanByImportSelector.class,
        ImportBeanByImportBeanDefinitionRegistrar.class})
@Configuration
public class ImportTest {

    //这种用法是TestBean1不被spring扫描到,这样才有意义
    @Autowired(required = false)
    private TestBean1 testBean1;
    
}

ImportSelector接口

另一种用ImportSelector接口实现的示例如下,注意这里引入的是实现类的名称,这种方法适合在外部组织引入的模块化。方法中annotationMetadata参数表示当前被@Import注解给标注的所有注解信息。

public class ImportBeanByImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
    	// 这里全类名
        return new String[]{"com.gzl.cn.springbootcache.config.TestBean3"};
    }
}

//使用
@Import({ImportBeanByImportSelector.class})

ImportBeanDefinitionRegistrar接口

另一种更方便的实现方法如下,其用法同ImportSelector接口一样。

public class ImportBeanByImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(TestBean4.class); // 这里类名
        registry.registerBeanDefinition("TestBean4", rootBeanDefinition);
    }
}

@RequestMapping

这个注解表示通用的GetMapping和PostMapping,但使用起来有点实践上的区别,RequestMapping配合通配符使用,可以起到模块划分的作用。即在类上面注解会比较合适。

  • 多个URL映射到同一地址:@RequestMapping(value={“/test1”, “/user/create”}):
  • 过滤请求:@RequestMapping(params=“submitFlag=create”, method=RequestMethod.GET),表示只接受请求中有
    “submitFlag=create”请求参数且请求方法为“GET”的URL地址;
  • 只对请求头为“Content-Type:application/json”的进行请求处理:@RequestMapping(value = “/request/ContentType”, method = RequestMethod.POST, headers = “Content-Type=application/json”)
//类似URL为/api/user/的请求全部转到这个模块,这样也方便异常处理
@Controller
@RequestMapping("/api/user/")
public class ReadingListController {

}

@Profile

当应用程序需要部署到不同的运行环境时,一些配置细节通常会有所不同。比如,数据库连 接的细节在开发环境下和测试环境下就会不一样,在生产环境下又不一样。

@Profile("production")
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

}

使用@Profile注解要求运行时激活production Profile,这样才能应用该配置。可以启动时指定,也可以在配置文件中配置,比如:

$ java -jar readinglist-0.0.1-SNAPSHOT.jar --spring.profiles.active=production

SpringBootTest测试

有几个特殊的注解需要理解下:

  • @RunWith(SpringJUnit4ClassRunner.class):引入 Spring对 JUnit4的支持,一般不太使用;
  • @SpringApplicationConfiguration (classes= HelloApplication. class):指定SpringBoot的启动类;
  • @WebAppConfiguration:开启 Web 应用的配置,用于模拟 ServletContexto MockMvc对象;
  • Mockery.java:jMock核心类,用于创建Mock对象的,通过其mock方法来创建相应接口或类的Mock对象。

一个完整的例子如下:

public class GoodsHibernateDaoUnitTest {
    //Mock对象上下文,用于创建Mock对象, ClassImposteriser.INSTANCE表示可以支持Mock非接口类,默认只支持Mock接口
    private final Mockery context = new Mockery() {{
        setImposteriser(ClassImposteriser.INSTANCE);
    }};
    
    //Mock IGoodsCodeDao接口
    private IGoodsCodeDao goodsCodeDao = context.mock(IGoodsCodeDao.class);

    @Before
    public void setUp() { }
    
    @Test
    public void testSave () {
        final GoodsModel expected = new GoodsModel();
    
        //8、定义预期行为,并在后边来验证预期行为是否正确(可选)
        context.checking(new org.jmock.Expectations() {
            goodsCodeDao.get(GoodsModel.class, 1)  //调用一次goodsCodeDao.get()方法,且参数必须为1
            .one()
            .will(returnValue(expected)); //返回值
        });
        GoodsModel actual = goodsDao.get(1); 
        
        //验证第8步定义的预期行为是否正确执行了(可选)
        context.assertIsSatisfied(); 
        
        //验证goodsDao.get(1)返回结果是否正确 , expected是一个事先定义好的变量
        Assert.assertEquals(goods, expected);
    }

切换日志组件

默认情况下,Spring Boot会用Logback(http://logback.qos.ch)来记录日志,并用INFO级别输 出到控制台。如果决定使 用Log4j或者Log4j2,那么你只需要修改依赖,引入对应该日志实现的起步依赖,同时排除掉 Logback。

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter</artifactId>
  <exclusions>
    <exclusion> 
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-logging</artifactId>
    </exclusion>
  </exclusions>
</dependency>

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

开发自己的springboot-starter

有一个叫spring cloud starts是一个基础的starts版本。

Maven相关

Maven内置变量

maven 内置变量 Maven 提供了一些内置的变量,称为"内置属性",可以在项目的pom.xml文件中直接使用。使用示例如下:

<build>
    <directory>${project.basedir}/target</directory>
    <outputDirectory>${project.build.directory}/classes</outputDirectory>
    <finalName>${project.artifactId}-${project.version}</finalName>
</build>
  1. 基于项目的变量
    • {basedir}: 项目根目录
    • ${version}:项目版本
    • ${project.basedir}:项目的根目录,即包含 pom.xml 文件的目录。
    • ${project.baseUri}:项目的文件地址(URI)。
    • ${project.groupId}:项目的 groupId。
    • ${project.artifactId}:项目的 artifactId。
    • ${project.version}:项目的版本。
    • ${project.packaging}:项目的打包方式,如 jarwar 等。
    • ${project.name}:项目的名称。
    • ${project.description}:项目的描述。
    • ${project.build.directory}:构建生成的文件存放的目录,默认为 ${project.basedir}/target
    • ${project.build.outputDirectory}:主代码编译后的输出目录,默认为 ${project.build.directory}/classes
    • ${project.build.sourceDirectory}:主代码的源目录,默认为 src/main/java
    • ${project.build.testSourceDirectory}:测试代码的源目录,默认为 src/test/java
    • ${project.build.testOutputDirectory}:测试代码编译后的输出目录,默认为 ${project.build.directory}/test-classes
    • ${project.build.finalName} 产出物名称,缺省为 ${project.artifactId} - ${project.version}
  2. 设置和环境变量
    • ${settings.localRepository}:本地仓库的路径。
    • ${env.JAVA_HOME}:Java 安装目录的环境变量。
    • ${env.MAVEN_OPTS}:传递给 Maven JVM 的参数。
  3. 时间和构建相关
    • ${maven.build.timestamp}:构建开始的时间戳。
    • ${maven.build.timestamp.format}:构建开始时间的格式化字符串,默认为 yyyyMMdd-HHmm
  4. Maven 系统属性
    • 这些是 Java 系统属性,可以通过 System.getProperty() 访问,也可以在 Maven 中使用。例如 ${java.version}${os.name} 等。
  5. 命令行属性
    • 你可以在 Maven 命令行中通过 -D 参数设置自定义属性。例如 mvn install -DmyProp=myValue,然后在 POM 或构建脚本中通过 ${myProp} 引用它。

SpringBoot-maven插件

主要功能包括: 打包你的应用为一个可执行的JAR或WAR,包含所有必要的类和资源,可以在生产环境中执行,内嵌了Tomcat, Jetty, Undertow。如果不提供这个插件,则用maven package指令打包后的应用不能正常运行,因为没有依赖包。

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

mvn clean package
mvn spring-boot:run

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/601489.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

css--控制滚动条的显示位置

各种学习后的知识点整理归纳&#xff0c;非原创&#xff01; ① direction属性 滚动条在左侧显示② transform:scaleY() 滚动条在上侧显示 正常的滚动条会在内容超出规定的范围后在区域右侧和下侧显示在有些不正常的需求下会希望滚动条在上侧和左侧显示自己没有想到好的解决方案…

Vue3:menu导航栏出现多个同一跳转路径的菜单处理

文章目录 需求整理实现思路实现过程 需求整理&#xff0c;实现思路 最近公司想将之前老的项目整理出来&#xff0c;因为这个老项目内容太杂什么页面都往里面塞&#xff0c;导致菜单特别多&#xff0c;公司就像将这个老的项目迁出来&#xff0c;这个旧的项目本来是后端PHP写的。…

面试分享——订单超30分钟未支付自动取消用什么实现?如何使用Redis实现延迟队列?

目录 1.订单超时未支付自动取消&#xff0c;这个你用什么方案实现&#xff1f; 2.如何使用Redis实现延迟队列 2.1实验步骤 2.2实现生产可用的延迟队列还需关注什么 3.总结 电商场景中的问题向来很受面试官的青睐&#xff0c;因为业务场景大家都相对更熟悉&#xff0c;相关…

禹晶、肖创柏、廖庆敏《数字图像处理(面向新工科的电工电子信息基础课程系列教材)》Chapter 5插图

禹晶、肖创柏、廖庆敏《数字图像处理&#xff08;面向新工科的电工电子信息基础课程系列教材&#xff09;》 Chapter 5插图

【Verilog】big_small_cnt

通用大小计数器 timescale 1ns / 1ps // // Company: // Engineer: wengf // Create Date: // Design Name: // Module Name: big_small_cnt // Project Name: // Target Devices: // Tool Versions: // Description: // Dependencies: // Revision: // Revision 0…

超声波测距传感器--第七天

1.超声波测距 型号:HC-SR04 接线参考:模块除了两个电源引脚外,还有TRIG,ECHO引脚,这两个引脚分别接我们开发板的P1.5和P1.6端 超声波模块是用来测量距离的一种产品,通过发送超声波,利用时间差和声音传播速度,计算模块到前方障碍物的距离。 2. 如何让它发送波: Tri…

Linux入门攻坚——22、通信安全基础知识及openssl、CA证书

Linux系统常用的加解密工具&#xff1a;OpenSSL&#xff0c;gpg&#xff08;是pgp的实现&#xff09; 加密算法和协议&#xff1a; 对称加密&#xff1a;加解密使用同一个秘钥&#xff1b; DES&#xff1a;Data Encryption Standard&#xff0c;数据加密标准&…

【postgreessql 】查询数据库表占用物理空间

查询单个表的磁盘使用量&#xff1a; SELECTrelname,pg_size_pretty ( pg_total_relation_size ( relid ) ) AS total_size FROMpg_catalog.pg_statio_user_tables; 查询所有表的总磁盘使用量&#xff1a; SELECTpg_size_pretty ( SUM ( pg_total_relation_size ( relid ) )…

简洁大气APP下载单页源码

源码介绍 简洁大气APP下载单页源码&#xff0c;源码由HTMLCSSJS组成&#xff0c;记事本打开源码文件可以进行内容文字之类的修改&#xff0c;双击html文件可以本地运行效果&#xff0c;也可以上传到服务器里面 效果截图 源码下载 简洁大气APP下载单页源码

[oeasy]python0016_在vim中直接运行python程序

回忆上次内容 上次 置换 esc 和 caps lock 任何操作 都可以在不移动 手腕的状态下完成了 每次都要 退出vim编辑器&#x1f634; 才能 在shell中 运行python程序有点麻烦 想要 不退出vim 直接在 vim应用 中运行 py程序可能吗&#xff1f;&#x1f914; 运行程序 以前都是 先退…

0507华为od二面

只记录自己没回答上的问题 1、ZGC的缺点&#xff1a; 1)只是适用于32位系统 2)最大只是支持4TB内存容量 3)最糟糕的情况下吞吐量会下降15%&#xff0c;这都不是事至于吞吐量&#xff0c;通过扩容分分钟解决 4)分代的原因:不同对象的生命周期不相同&#xff0c;可能会扫描整个堆…

TiDB数据库 使用tiup 缩容遇到的tikv处于下线中状态无法转为tombstone状态

官方的缩容文档 https://docs.pingcap.com/zh/tidb/stable/scale-tidb-using-tiup 论坛地址 https://tidb.net/ 问题&#xff1a;使用tiup 缩容遇到的tikv处于下线中状态无法转为tombstone状态 解决方法 1.缩容 tiup cluster scale-in --node 10.0.1.5:20160 2.查看 tiup…

2024.5.6 关于 SpringCloud 的基本认知

目录 引言 微服务框架所包含的技术栈 微服务架构演变 单体架构 分布式架构 微服务架构 微服务技术对比 认识 SpringCloud SpringBoot 版本兼容关系 服务拆分和远程调用 服务拆分注意事项 远程调用 引言 微服务是一种框架风格&#xff0c;按照业务板块来划分应用代码…

彻底解决python的pip install xxx报错(文末附所有依赖文件)

今天安装pip install django又报错了&#xff1a; C:\Users\Administrator>pip install django WARNING: Ignoring invalid distribution -ip (d:\soft\python\python38\lib\site-pac kages) Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple Collecting djan…

构建 WebRTC 一对一信令服务器

构建 WebRTC 一对一信令服务器 构建 WebRTC 一对一信令服务器前言为什么选择 Nodejs&#xff1f;Nodejs 的基本原理浏览器使用 Nodejs安装 Nodejs 和 NPMsocket.io信令服务器搭建信令服务器客户端服务端启动服务器并测试 总结参考 构建 WebRTC 一对一信令服务器 前言 我们在学…

Bookends for Mac v15.0.2 文献书籍下载管理

Bookends Mac版可以轻松地将其导入参考 &#xff0c;并直接搜索和进口从数以百计的线上资料来源。Bookends Mac版使用内置在浏览器中下载参考与PDF格式的文件&#xff0c;或和/或网页的点击。 Bookends for Mac v15.0.2注册激活版下载 本文由 mdnice 多平台发布

信息系统项目管理师0092:项目管理原则(6项目管理概论—6.4价值驱动的项目管理知识体系—6.4.1项目管理原则)

点击查看专栏目录 文章目录 6.4价值驱动的项目管理知识体系6.4.1项目管理原则1.原则一:勤勉、尊重和关心他人2.原则二:营造协作的项目管理团队环境3.原则三:促进干系人有效参与4.原则四:聚焦于价值5.原则五:识别、评估和响应系统交互6.原则六:展现领导力行为7.原则七:根…

python菜鸟级安装教程 -下篇(安装编辑器)

来来~接着上篇的来~ 安装好python.exe之后&#xff0c;我们可以根据cmd命令窗口&#xff0c;码代码。 这算最简单入门了~ 如果我们在安装个编辑器。是什么效果&#xff0c;一起体验一下吧 第一步&#xff0c;下载编辑器&#xff0c;选择官网&#xff0c;下载免费版本入门足…

探索Baidu Comate:编程世界中的新利器

文章目录 Baidu Comate 介绍Baidu Comate的优势Baidu Comate安装过程Baidu Comate实战演练代码调优代码解释代码生成注释生成 总结 Baidu Comate 介绍 随着GPT的大火&#xff0c;衍生了各种AI工具&#xff0c;这些AI工具遍布在各行业各领域中&#xff0c;有AI写作、AI办公、AI…

Linux 认识与学习Bash——3

在Linux bash中&#xff0c;数据流重定向是指将命令的输出从默认的标准输出&#xff08;通常是终端&#xff09;重定向到其他位置&#xff0c;如文件或另一个命令的输入。这是通过使用特定的符号来实现的。例如&#xff0c;>用于将输出重定向到文件&#xff0c;而<用于将…
最新文章