Java后端 - 碎片知识(持续更新)

Spring

@Autowired和@Resource区别?

定义上的不同

@Autowired
对类成员变量、方法及构造函数进行标注,完成自动装配的工作。

@Resource
在语义上被定义为通过其唯一的名称来标识特定的目标组件,其中声明的类型与匹配过程无关。

如果没有明确指定名称,则默认名称是从字段名称或设置方法(get、set方法)派生的。 如果用在字段上,则采用字段名称; 如果用在在setter方法,它采用其属性名称(例如setProperty()方法,取property做为属性名称)。

注解的属性不同

@Autowired只包含一个参数:required,表示是否开启自动注入,默认是true。而@Resource包含七个参数,其中最重要的两个参数是:name 和 type。如下:

public @interface Autowired {
 
    /**
     * 是否开启自动注入,有些时候我们不想使用自动装配功能,可以将该参数设置成false。
     */
	boolean required() default true;
 
}
 
 
public @interface Resource {
    /**
     * bean的名称
     */
    String name() default "";
 
    String lookup() default "";
 
    /**
     * Java类,被解析为bean的类型
     */
    Class<?> type() default java.lang.Object.class;
 
    enum AuthenticationType {
            CONTAINER,
            APPLICATION
    }
 
    /**
     * 身份验证类型
     */
    AuthenticationType authenticationType() default AuthenticationType.CONTAINER;
 
    /**
     * 组件是否可以与其他组件之间共享
     */
    boolean shareable() default true;
 
    String mappedName() default "";
 
    /**
     * 描述
     */
    String description() default "";
}

默认装配不同

@Autowired如果要使用byName,需要使用@Qualifier一起配合。而@Resource如果指定了name,则用byName自动装配,如果指定了type,则用byType自动装配。

使用地方不同

@Autowired能够用在:构造器、方法、参数、成员变量和注解上,而@Resource能用在:类、成员变量和方法上。

来源不同

@Autowired是Spring定义的注解,而@Resource是JSR-250定义的注解。所以@Autowired只能在Spring框架下使用,而@Resource则可以与其他框架一起使用。

装配方式不同

@Autowired的装配顺序如下:

@Autowired默认先按byType进行匹配,如果发现找到多个bean,则又按照byName方式进行匹配,如果还有多个,则报出异常。
在这里插入图片描述

@Resource的装配顺序如下:

如果同时指定了name和type,流程如下:
在这里插入图片描述
如果指定了name,流程如下:
只是指定了@Resource注解的name,则按name后的名字去bean元素里查找有与之相等的name属性的bean。

在这里插入图片描述

如果指定了type,流程如下:
只指定@Resource注解的type属性,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常。
在这里插入图片描述
如果既没有指定name,也没有指定type,流程如下:
既不指定name属性,也不指定type属性,则自动按byName方式进行查找。如果没有找到符合的bean,则回退为一个原始类型进行进行查找,如果找到就注入。
在这里插入图片描述

AI问答

Q:Spring的IOC是指控制反转,将创建对象交给框架,我的疑问是当我使用注解来注入一个对象到controller或者service,这个过程是Spring实现是吧,是怎么实现的?
A:是的,当你在Spring框架中使用注解来注入一个对象到Controller或Service时,这个过程是由Spring框架自动实现的。具体实现机制大致可以分为以下几个步骤:

  1. 扫描与注册Bean

    • 组件扫描:Spring会根据@ComponentScan注解(通常在配置类上)指定的包路径,扫描该包及其子包下的所有带有特定注解的类(如@Component@Service@Repository@Controller等),并将这些类识别为Bean定义。
    • Bean定义注册:扫描到的类会被注册为Bean定义,保存在Spring容器中。每个Bean定义包含了如何创建该Bean实例的信息,比如类名、作用域、依赖关系等。
  2. 依赖解析与注入

    • 依赖注入注解:在需要依赖的对象中,你可以使用@Autowired注解来标记需要注入的字段或方法,Spring会自动查找匹配的Bean并注入。如果存在多个匹配的Bean,可以通过@Qualifier注解来指定具体的Bean名称。
    • 构造器注入与Setter注入:Spring支持通过构造器和Setter方法进行依赖注入。当一个Bean的构造器或Setter方法带有@Autowired注解时,Spring会在创建Bean实例时解析这些依赖,并调用相应的构造器或Setter方法来注入依赖的Bean。
  3. Bean的生命周期管理

    • 实例化:当请求一个Bean时,Spring首先检查是否已经存在该Bean的实例,如果没有,则根据Bean定义创建一个新的实例。
    • 初始化前处理:实例化后,Spring会调用初始化回调方法(如实现了InitializingBean接口的afterPropertiesSet方法,或使用@PostConstruct注解的方法)。
    • 属性注入:在初始化回调之前或之后(根据配置),Spring会解析Bean定义中的依赖关系,并执行相应的依赖注入。
    • 使用:Bean准备就绪后,可以被应用程序的其他部分使用。
    • 销毁:当容器关闭时,Spring会调用销毁回调方法(如实现了DisposableBean接口的destroy方法,或使用@PreDestroy注解的方法)来清理资源。

整个过程是基于Spring的BeanFactory(更具体的是ApplicationContext,它是BeanFactory的扩展)实现的,它负责管理Bean的定义、创建、配置和生命周期。这一切都是通过反射、代理(如JDK动态代理或CGLIB)等技术在运行时动态完成的,使得开发者无需手动编写繁琐的工厂模式或服务定位器模式代码,大大简化了应用的架构和开发过程。

Q:spring容器中是只能存在一个相同的Bean对象吗?
A:在Spring容器中,是否能存在多个相同类型的Bean对象,取决于这些Bean的定义中设置的作用域(Scope)。Spring支持多种作用域,主要有以下几种:

  1. singleton(单例):这是默认的作用域。当一个Bean定义为singleton时,Spring容器中只会存在一个该类型的Bean实例,每次请求该Bean时,Spring都会返回同一个共享的实例。这意味着,在整个应用的上下文中,相同类型的Bean都是同一个对象。

  2. prototype(原型):如果将Bean定义为prototype,那么每当请求获取该类型的Bean时,Spring都会创建一个新的实例。这意味着在容器中可以有多个相同类型的Bean实例,每个实例都是独立的。

  3. request(请求):在Web应用中,每次HTTP请求都会创建一个新的Bean实例,该作用域仅在Spring Web环境中有效。

  4. session(会话):同样在Web应用中,每个HTTP Session对应一个Bean实例,也仅在Spring Web环境中有效。

  5. globalSession(全局会话):主要用于Portlet环境中的全局会话作用域。

因此,简单来说,如果一个Bean定义为singleton作用域,那么Spring容器中只能存在一个相同的Bean对象;而如果定义为prototype或其他某些特定作用域,就可以存在多个不同的实例。

Q:都会创建一个新的Bean实例,那怎么区分哪个Bean对应哪个controller或者service?
A:在Spring框架中,尽管你可能会有多个相同类型的Bean实例(特别是当它们被定义为prototype作用域时),Spring仍然能够准确地管理并区分这些Bean实例,确保它们被正确地注入到需要它们的Controller或Service中。这主要通过以下几种方式实现:

  1. Bean的ID或Name:每个Bean在定义时都会有一个唯一的ID或Name(在XML配置中通过idname属性指定,在注解配置中通常是类名首字母小写作为默认Bean名称,也可以通过@Component("自定义名称")等方式指定)。Spring容器内部通过这些ID或Name来唯一标识每一个Bean实例。

  2. 依赖注入时的限定符:当有多个相同类型的Bean且需要注入到某个Controller或Service时,可以通过@Qualifier注解来指定确切的Bean名称,以告知Spring应该注入哪一个实例。例如,@Autowired @Qualifier("specificBeanName") MyService myService;

  3. 自动装配的逻辑:Spring在进行依赖注入时,会考虑Bean的类型、名称、以及@Qualifier等注解来精确匹配依赖项。对于原型(prototype)作用域的Bean,即使类型相同,Spring也能通过请求的上下文(如request或session)来区分不同的实例。

  4. 作用域代理:特别是对于prototype作用域的Bean,如果它们被注入到singleton作用域的Bean中,Spring会自动创建一个代理来管理原型Bean的生命周期。这个代理会在每次调用时动态地创建或获取一个新的prototype Bean实例,同时确保singleton Bean持有的引用仍然是有效的。

总结来说,通过Bean的名称、限定符注解、以及Spring内部的自动装配逻辑和作用域代理机制,Spring能够确保每个Controller或Service都能得到其预期的Bean实例,即便存在多个相同类型的实例。

SpringBoot

Spring和SpringBoot区别?

配置文件

application.yml 基础配置

默认的主配置文件,Spring Boot 应用会自动加载该文件。存放应用程序的主要配置。是 Spring Boot 中用于配置应用程序属性的主要配置文件之一。这个文件
通常用于配置应用程序的一般性属性,包括数据库连接、日志级别、端口
号等。下面是一些常见的在 application.yml 中配置的示例:

# 服务器端口
server:
  port: 8080

# 数据库连接配置
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mydatabase
    username: root
    password: password
    driver-class-name: com.mysql.cj.jdbc.Driver

# 日志级别
logging:
  level:
    root: INFO
    com.example.mypackage: DEBUG

# 应用程序自定义属性
myapp:
  name: My Spring Boot App
  version: 1.0

上述示例展示了一些常用的配置项,但根据应用程序的需求,你可以在 application.yml 中配置各种属性。Spring Boot 非常灵活,可以根据属性的前缀识别属性,并将其绑定到对应的 Java 对象上,以方便在代码中使用。

需要注意的是,application.yml 文件采用 YAML(YAML Ain’t Markup Language)语法,它使用缩进和冒号来表示层次关系。因此,正确的缩进对于保持文件的结构是很重要的。

application-{profile}.properties/application-{profile}.yml:

可以根据不同的环境配置不同的属性文件,{profile} 表示环境名称。
例如,application-dev.properties 用于开发环境,application-prod.properties用于生产环境。

bootstrap.properties/bootstrap.yml

用于 Spring Cloud 应用,是 Spring Cloud Config 服务的默认配置文件。
存放一些启动时需要优先加载的配置,比如连接到 Config Server 的配置。

application-{label}.properties/application-{label}.yml

用于 Git 和配置服务器的外部化配置,{label} 表示 Git 的标签。
例如,application-v1.properties 用于版本 1。

这些文件命名规范允许你根据不同的环境、配置标签或者配置文件类型组织和管理你的配置信息。Spring Boot 会根据上述规则自动加载相应的配置文件。

多配置文件,怎么知道用哪个?

Spring Boot 在启动时会加载默认的主配置文件,即 application.yml 或 application.properties。如果有不同环境的配置文件,如 application-test.yml 或 application-dev.yml,Spring Boot 会根据当前激活的环境来选择加载对应的配置文件。

配置文件设置 spring.profiles.active 指定激活环境

你可以通过在 application.yml 或 application.properties 中设置 spring.profiles.active 属性来指定激活的环境。例如:

spring:
  profiles:
    active: dev

上述配置表示激活 dev 环境,因此 Spring Boot 会加载 application-dev.yml 文件中的配置。

如果没有设置 spring.profiles.active 属性,Spring Boot 将默认使用主配置文件的配置。

命令行参数指定环境

除了通过属性文件来设置激活的环境外,你还可以通过命令行参数、系统属性、环境变量等方式来指定激活的环境。例如,通过命令行参数启动时指定环境:

java -jar your-application.jar --spring.profiles.active=dev

这样就会加载 application-dev.yml 的配置。

tips:Springboot中配置文件的加载顺序

application.yml、application.properties和bootStrap.yml加载顺序

以jar包发布springboot项目时
默认会先使用jar包根目录下的application.properties来作为项目配置文件。

如果在不同的目录中存在多个配置文件,它的读取顺序是:

1、config/application.properties(项目根目录中config目录下)
2、config/application.yml
3、application.properties(项目根目录下)
4、application.yml
5、resources/config/application.properties(项目resources目录中config目录下)
6、resources/config/application.yml
7、resources/application.properties(项目的resources目录下)
8、resources/application.yml

  • 21
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
作为一个Java后端程序员,有几个必备的知识是非常重要的: 1. Java核心知识:你需要熟悉Java的基本语法、面向对象编程的概念和特性,以及Java的常用类库和API。 2. 数据结构和算法:理解常用的数据结构(如数组、链表、栈、队列、树、图等)和基本算法(如排序、查找、递归等),能够根据问题的特点选择合适的数据结构和算法。 3. 多线程和并发:对于Java后端开发来说,多线程和并发是非常重要的概念。你需要了解线程的创建与管理、线程安全、锁机制等相关知识。 4. 数据库和SQL:大部分后端开发都会涉及到数据库操作,你需要熟悉关系型数据库(如MySQL、Oracle等)和SQL语言的基本知识,能够编写高效的SQL查询语句。 5. Web开发:掌握Java的Web开发框架(如Spring、Spring Boot等),了解HTTP协议、Servlet技术、RESTful服务等。 6. 设计模式:熟悉常用的设计模式(如单例模式、工厂模式、观察者模式等),能够应用到实际项目中,提高代码的可维护性和可扩展性。 7. 单元测试:掌握单元测试框架(如JUnit、TestNG等),能够编写和执行单元测试,保证代码的质量和稳定性。 8. 版本控制工具:熟练使用版本控制工具(如Git、SVN等),能够进行团队协作和代码管理。 除了以上的知识持续学习和自我提升也是非常重要的。不断关注新技术、参与开源项目和技术社区,积累经验和提高技能。希望对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值