【框架学习 | 第三篇】Spring上篇(Spring入门、核心功能、Spring Bean——>定义、作用域、生命周期、依赖注入)

在这里插入图片描述

文章目录

  • 1.Spring简述
    • 1.1什么是Spring框架?
    • 1.2Spring的核心功能
      • 1.2.1 IOC
        • (1)IOC介绍
        • (2)控制?反转?
      • 1.2.2 AOP
        • (1)AOP介绍
        • (2)专业术语
        • (3)Spring AOP和AspectJ AOP有什么区别?
        • (4)多个切面的执行顺序如何控制?
    • 1.3Spring的架构
      • 1.3.1Core容器
      • 1.3.2数据访问/集成
      • 1.3.3Web
      • 1.3.4杂项
  • 2.搭建Spring项目环境
    • 2.1安装Spring框架库
    • 2.2导入框架库
    • 2.3创建类
    • 2.4Bean配置文件
    • 2.5运行程序
  • 3.Spring Bean
    • 3.1Bean定义
      • 3.1.1元数据—>Bean标签的属性
      • 3.1.2配置的方式
        • (1)XML方式
        • (2)注解方式
      • 3.1.3@Component和@Bean的区别?
        • (1)@Bean使用示例
    • 3.2Bean作用域
      • 3.2.1作用域分类
      • 3.2.2配置作用域的方式
        • (1)xml方式
        • (2)注解方式
    • 3.3Bean生命周期
      • 3.3.1初始化回调
        • (1)InitializingBean的afterPropertiesSet()方法
        • (2)init-method属性指定初始化方法
      • 3.3.2销毁回调
        • (1)DisposableBean的destroy方法
        • (2)**destroy-method**属性指定销毁方法
    • 3.4Bean依赖注入
      • 3.4.1定义
      • 3.4.2依赖注入的作用
      • 3.4.3依赖注入的方式
        • (1)构造函数注入
        • (2)Set方式注入(常用)
        • (3)基于xml的自动装配
          • ①搭建环境
          • ②ByName自动装配
          • ③ByType自动装配
          • ④小结
        • (4)基于注解的自动装配
      • 3.4.4详讲@Autowired、@Qualifer、@Resource、@Value
        • (1)@Autowired
          • ①用在何处?
          • ②三种情况
        • (2)@Qualifer
          • ①用在何处
          • ②使用情况
        • (3)@Resource
        • (4)@Value
        • (5)辨别@Autowired和@Resource的异同

1.Spring简述

1.1什么是Spring框架?

Spring 是一款开源的轻量级 Java 开发框架,旨在提高开发人员的开发效率以及系统的可维护性。

1.2Spring的核心功能

Spring提供的核心功能为 IOC控制反转(Inversion of Control)和 AOP面向切面编程 (Aspect-Oriented Programming)

1.2.1 IOC

(1)IOC介绍
  1. IoC(Inversion of Control:控制反转) 是一种设计思想,而不是一个具体的技术实现。
  2. IoC 的思想就是将原本在程序中手动创建对象的控制权,交由 Spring 框架来管理。不过, IoC 并非 Spring 特有,在其他语言中也有应用。
(2)控制?反转?
  • 控制:指的是对象创建(实例化、管理)的权力
  • 反转控制权交给外部环境(Spring 框架、IoC 容器)

IoC 图解

将对象之间的相互依赖关系交给 IoC 容器来管理,并由 IoC 容器完成对象的注入。这样可以很大程度上简化应用的开发,把应用从复杂的依赖关系中解放出来。 IoC 容器就像是一个工厂一样,当我们需要创建一个对象的时候,只需要配置好配置文件/注解即可,完全不用考虑对象是如何被创建出来的。

在 Spring 中, IoC 容器是 Spring 用来实现 IoC 的载体, IoC 容器实际上就是个 Map(key,value),Map 中存放的是各种对象。

Spring 时代我们一般通过 XML 文件来配置 Bean,后来开发人员觉得 XML 文件来配置不太好,于是 SpringBoot 注解配置就慢慢开始流行起来。

1.2.2 AOP

(1)AOP介绍
  1. AOP(Aspect-Oriented Programming:面向切面编程):能够将那些与业务无关,却为业务模块所 共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性。
  2. Spring AOP 就是基于动态代理
    1. 如果要代理的对象,实现了某个接口,那么 Spring AOP 会使用 JDK Proxy,去创建代理对象,
    2. 对于没有实现接口的对象,就无法使用 JDK Proxy 去进行代理了,这时候 Spring AOP 会使用 Cglib 生成一个被代理对象的子类来作为代理,如下图所示:

SpringAOPProcess

(2)专业术语
术语含义
目标(Target)被通知的对象
代理(Proxy)向目标对象应用通知之后创建的代理对象
连接点(JoinPoint)目标对象的所属类中,定义的所有方法均为连接点
切入点(Pointcut)被切面拦截 / 增强的连接点(切入点一定是连接点,连接点不一定是切入点)
通知(Advice)增强的逻辑 / 代码,也即拦截到目标对象的连接点之后要做的事情
切面(Aspect)切入点(Pointcut)+通知(Advice)
Weaving(织入)将通知应用到目标对象,进而生成代理对象的过程动作
(3)Spring AOP和AspectJ AOP有什么区别?
  1. Spring AOP 属于运行时增强,而 AspectJ 是编译时增强 Spring AOP 基于代理(Proxying),而 AspectJ 基于字节码操作(Bytecode Manipulation)。

  2. Spring AOP 已经集成了 AspectJ ,AspectJ 应该算的上是 Java 生态系统中最完整的 AOP 框架了。

  3. AspectJ 相比于 Spring AOP 功能更加强大,但是 Spring AOP 相对来说更简单,

  4. 如果我们的切面比较少,那么两者性能差异不大。但是,当切面太多的话,最好选择 AspectJ ,它比 Spring AOP 快很多

(4)多个切面的执行顺序如何控制?
  1. 通常使用 @Order 注解直接定义切面顺序
// 值越小优先级越高
@Order(3)
@Component
@Aspect
public class LoggingAspect implements Ordered {
}
  1. 实现Ordered 接口重写 getOrder 方法
@Component
@Aspect
public class LoggingAspect implements Ordered {// ....@Overridepublic int getOrder() {// 返回值越小优先级越高return 1;}
}

1.3Spring的架构

Spring 框架提供了大约 20 个模块,可以根据应用程序需求使用它们。

Spring 框架架构

1.3.1Core容器

Core 容器由 Core、Beans、Context 和 Expression Language 模块组成,详细信息如下 −

  • Core 模块提供了框架的基本部分,包括 IoC 和依赖注入功能。
  • Bean 模块提供了 BeanFactory,它是工厂模式的一个复杂的实现。
  • Context 模块建立在 Core 和 Beans 模块提供的坚实基础之上,它是访问任何已定义和配置的对象的媒介。 ApplicationContext 接口是上下文模块的焦点。
  • SpEL 模块提供了一种强大的表达式语言,用于在运行时查询和操作对象图。

1.3.2数据访问/集成

数据访问/集成层由 JDBC、ORM、OXM、JMS 和 Transaction 事务模块组成,详细信息如下 −

  • JDBC 模块提供了一个 JDBC 抽象层,它消除了繁琐的 JDBC 相关编码的需要。
  • ORM 模块为流行的对象关系映射 API 提供集成层,包括 JPA、JDO、Hibernate 和 iBatis。
  • OXM 模块提供了一个抽象层,它支持 JAXB、Castor、XMLBeans、JiBX 和 XStream 的 Object/XML 映射实现。
  • Java 消息传递服务 JMS 模块包含用于生成和使用消息的功能。
  • Transaction 模块支持对实现特殊接口的类和所有 POJO 的编程和声明式事务管理。

1.3.3Web

Web 层由 Web、Web-MVC、Web-Socket 和 Web-Portlet 模块组成,具体如下 −

  • Web 模块提供了基本的面向 Web 的集成功能,例如多部分文件上传功能以及使用 servlet 侦听器和面向 Web 的应用程序上下文初始化 IoC 容器。
  • Web-MVC 模块包含 Spring 的 Web 应用程序的 Model-View-Controller(模型-视图-控制器) (MVC) 实现。
  • Web-Socket 模块支持 Web 应用程序中客户端和服务器之间基于 WebSocket 的双向通信。
  • Web-Portlet 模块提供了在portlet 环境中使用的MVC 实现,并反映了Web-Servlet 模块的功能

1.3.4杂项

其他重要的模块很少,如 AOP、Aspects、Instrumentation、Web 和 Test 模块,具体如下 −

  • AOP 模块提供了一个面向方面的编程实现,允许您定义方法拦截器和切入点,以清晰地解耦实现应该分离的功能的代码。
  • Aspects 模块提供与 AspectJ 的集成,AspectJ 又是一个强大且成熟的 AOP 框架。
  • Instrumentation 模块提供类检测支持和类加载器实现以用于某些应用程序服务器。
  • Messaging 模块支持将 STOMP 作为 WebSocket 子协议在应用程序中使用。 它还支持注解编程模型,用于路由和处理来自 WebSocket 客户端的 STOMP 消息。
  • Test 模块支持使用 JUnit 或 TestNG 框架对 Spring 组件进行测试。

2.搭建Spring项目环境

2.1安装Spring框架库

下载路径: https://repo.spring.io/release/org/springframework/spring

下载完成之后,在libs 目录中可以找到所有 Spring 库

2.2导入框架库

IDEA导入Spring框架库

2.3创建类

  • HelloWorld类
public class HelloWorld {private String message;public void setMessage(String message){this.message  = message;}public void getMessage(){System.out.println("Your Message : " + message);}
}
  • MainApp类——主应用程序
public class MainApp {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");HelloWorld obj = (HelloWorld) context.getBean("helloWorld");obj.getMessage();}
}
  • 第一步是在我们使用框架 API ClassPathXmlApplicationContext() 的地方创建应用程序上下文。 此 API 加载 bean 配置文件,并最终基于提供的 API,它负责创建和初始化所有对象,即配置文件中提到的 bean。
  • 第二步用于使用创建的上下文的 getBean() 方法获取所需的 bean。 该方法使用 bean ID 返回一个通用对象,最终可以转换为实际对象。 一旦有了对象,就可以使用该对象调用任何类方法。

2.4Bean配置文件

  • 该配置文件放置在src目录下即可

    通常开发人员将此文件命名为 Beans.xml,必须确保该文件在 CLASSPATH 中可用,并在主应用程序中使用相同的名称

<?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/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsd"><bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld"><property name = "message" value = "Hello World!"/></bean></beans>

2.5运行程序

运行MainApp程序,输出结果:

Your Message : Hello World!

3.Spring Bean

3.1Bean定义

简单来说,Bean 代指的就是那些被 IoC 容器所管理的对象

我们需要告诉 IoC 容器帮助我们管理哪些对象,这个是通过配置元数据来定义的。配置元数据可以是 XML 文件、注解或者 Java 配置类。

3.1.1元数据—>Bean标签的属性

  1. 在IOC容器创建Bean对象时候,需要知道这三个信息
    • 如何创建一个bean(class)
    • bean的生命周期
    • bean的依赖关系

所有配置元数据都转换为一组构成每个 bean 标签定义的以下属性

序号属性描述
1class指定了用于创建 bean 的 bean类型
2id或者name唯一地指定 bean 标识符
3scope指定从特定 bean 定义创建的对象的范围
4constructor-arg用于注入依赖关系
5properties用于注入依赖关系
6autowiring mode用于注入依赖关系
7lazy-initialization mode延迟初始化的 bean,即 告诉 IoC 容器在第一次被请求时创建一个 bean 实例,而不是在启动时
8initialization method在容器设置了 bean 上的所有必要属性之后调用的回调
9destruction method包含 bean 的容器被销毁时要使用的回调

3.1.2配置的方式

Spring IoC 容器与实际写入此配置元数据的格式完全分离。 以下是向 Spring 容器提供配置元数据的三个重要方法 −

  • 基于 XML 的配置文件。(Spring)
  • 基于注解的配置(SpringBoot)
  • 基于 Java 的配置
(1)XML方式
<bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld"><property name = "message" value = "Hello World!"/></bean>
(2)注解方式
  1. @Component通用的注解,可标注任意类为 Spring 组件。如果一个 Bean 不知道属于哪个层,可以使用@Component 注解标注。
  2. @Repository : 对应持久层即 Dao 层,主要用于数据库相关操作。
  3. @Service : 对应服务层,主要涉及一些复杂的逻辑,需要用到 Dao 层。
  4. @Controller : 对应 Spring MVC 控制层,主要用于接受用户请求并调用 Service 层返回数据给前端页面。

3.1.3@Component和@Bean的区别?

  • 相同:两者都是用来声明一个Bean类,交给IOC容器处理

  • 不同:

    1. 作用的地方不同@Component 注解作用于类,而==@Bean注解作用于方法==。
    2. 产生的作用不同
      1. @Component通常是通过类路径扫描来自动侦测以及自动装配到 Spring 容器中(我们可以使用 @ComponentScan 注解定义要扫描的路径从中找出标识了需要装配的类自动装配到 Spring 的 bean 容器中)。
      2. @Bean 注解通常是我们在标有该注解的方法中定义产生这个 bean,@Bean告诉了 Spring 这是某个类的实例,当我需要用它的时候还给我。
    3. 自定义强度不同
      1. @Bean 注解比 @Component 注解的自定义性更强
      2. 很多地方我们只能通过 @Bean 注解来注册 bean。比如当我们引用第三方库中的类需要装配到 Spring容器时,则只能通过 @Bean来实现
(1)@Bean使用示例
@Configuration
public class AppConfig {@Beanpublic TransferService transferService() {return new TransferServiceImpl();}}

上面的代码相当于下面的 xml 配置:

<beans><bean id="transferService" class="com.acme.TransferServiceImpl"/>
</beans>

3.2Bean作用域

3.2.1作用域分类

  1. singleton : IoC 容器中只有唯一的 bean 实例。Spring 中的 bean 默认都是单例的,是对单例设计模式的应用。
  2. prototype : 每次获取都会创建一个新的 bean 实例。也就是说,连续 getBean() 两次,得到的是不同的 Bean 实例。
  3. request (仅 Web 应用可用): 每一次 HTTP 请求都会产生一个新的 bean(请求 bean),该 bean 仅在当前 HTTP request 内有效。
  4. session (仅 Web 应用可用) : 每一次来自新 session 的 HTTP 请求都会产生一个新的 bean(会话 bean),该 bean 仅在当前 HTTP session 内有效。
  5. application/global-session (仅 Web 应用可用):每个 Web 应用在启动时创建一个 Bean(应用 Bean),该 bean 仅在当前应用启动时间内有效。
  6. websocket (仅 Web 应用可用):每一次 WebSocket 会话产生一个新的 bean。

3.2.2配置作用域的方式

(1)xml方式
<bean id="..." class="..." scope="singleton"></bean>
(2)注解方式
@Bean
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public Person personPrototype() {return new Person();
}

3.3Bean生命周期

对于普通的 Java 对象来说,它们的生命周期就是:

  • 实例化
  • 该对象不再被使用时通过垃圾回收机制进行回收

对于 Spring Bean 的生命周期来说:

  1. 实例化bean
  2. bean属性赋值
  3. 初始化bean
    1. 执行处理aware接口,分别调用 setBeanName()、setBeanFactory()、 setApplicationContext()方法
    2. 调用BeanPostProcessor的预初始化方法
    3. 调用InitializingBean的afterPropertiesSet()方法
    4. 调用init-method属性指定初始化方法
    5. 调用BeanPostProcessor的初始化后方法
  4. 使用bean
  5. 销毁bean
    1. 调用DisposableBean的destroy方法
    2. 调用destroy-method属性指定的方法

Spring Bean 生命周期

3.3.1初始化回调

(1)InitializingBean的afterPropertiesSet()方法

org.springframework.beans.factory.InitializingBean 接口指定单个方法

void afterPropertiesSet() throws Exception;

可以简单地实现上述接口,并且可以在 afterPropertiesSet() 方法中完成初始化工作,如下所示 −

public class ExampleBean implements InitializingBean {public void afterPropertiesSet() {// do some initialization work}
}
public class ExampleBean implements InitializingBean {public void afterPropertiesSet() {// do some initialization work}
}
(2)init-method属性指定初始化方法

基于 XML 的配置元数据的情况下,您可以使用 init-method 属性来指定具有 void 无参数签名的方法的名称。

<bean id = "exampleBean" class = "examples.ExampleBean" init-method = "init"/>
  • 下面是类的定义
public class ExampleBean {public void init() {// do some initialization work}
}

3.3.2销毁回调

(1)DisposableBean的destroy方法

org.springframework.beans.factory.DisposableBean 接口指定一个方法

void destroy() throws Exception;

因此,您可以简单地实现上述接口,并且可以在destroy() 方法中完成如下工作

public class ExampleBean implements DisposableBean {public void destroy() {// do some destruction work}
}
(2)destroy-method属性指定销毁方法
  • xml配置文件
<bean id = "exampleBean" class = "examples.ExampleBean" destroy-method = "destroy"/>
  • 类的定义
public class ExampleBean {public void destroy() {// do some destruction work}
}

3.4Bean依赖注入

3.4.1定义

  • 依赖bean对象的依赖于容器
  • 注入bean对象中的所有属性,由容器来注入

依赖注入,是IOC的一个方面,是个通常的概念,它有多种解释。这概念是说你不用创建对象,而只需要描述它如何被创建。你不在代码里直接组装你的组件和服务,但是要在配置文件里描述哪些组件需要哪些服务,之后一个容器(IOC容器)负责把他们组装起来

3.4.2依赖注入的作用

  1. 作用:降低程序间的耦合

    依赖关系的管理,以后都交给spring来维护

    在当前类需要用到其他类的对象,由spring为我们提供,我们只需要在配置文件中说明依赖关系的维护,就称之为依赖注入。

3.4.3依赖注入的方式

  • 可以注入的数据(三类):

    • 基本类型和String
    • 其他bean类型(在配置文件中或者注解配置过的bean)
    • 复杂类型/集合类型:(不演示)
  • 注入的方式(三种):十分重要

    • 构造函数注入
    • set方法注入
    • 基于xml的自动装配(bean标签的autowire属性(byName—>根据bean标签的id属性查找、byType——>根据bean标签的Class属性查找))
    • 注解注入()
(1)构造函数注入
  • 定义:用类中的构造函数,给成员变量赋值。注意,赋值的操作不是我们自己做的,而是通过配置的方式,让 spring 框架来为我们注入。

  • 说明:

    • 使用的标签:constructor-arg
    • 标签出现的位置:bean标签的内部
    • 标签中的属性:
      • type:用于指定要注入的数据的数据类型,该数据类型也是构造函数中某个或某些参数的类型。
      • index:用于指定要注入的数据给构造函数中指定索引位置的参数赋值。索引的位置是从0开始。
      • name:用于指定给构造函数中指定名称的参数赋值。
      • ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象
      • value:要注入的数据
    • 优点:在获取bean对象时,注入数据是必须的操作,否则对象无法创建成功。
    • 缺点:改变了bean对象的实例化方式,使得我们在创建对象时,如果用不到这些数据,也必须提供
  • 举例

    <!--默认构造器方式-->
    <bean id="user" class="com.kuang.pojo.User"><property name="name" value="张三"/>
    </bean><!--通过有参构造创建对象。方式一:下标赋值-->
    <bean id="user" class="com.kuang.pojo.User"><constructor-arg index="0" value="jerry"/>
    </bean><!--通过有参构造创建对象。方式二:类型创建,不建议使用-->
    <bean id="user" class="com.kuang.pojo.User"><constructor-arg type="java.lang.String" value="jarry"/>
    </bean><!--通过有参构造创建对象。方式三:通过参数名,推荐使用-->
    <bean id="user" class="com.kuang.pojo.User"><constructor-arg name="name" value="jarry"/><constructor-arg name="birthday" ref="now"/>
    </bean>
    <!-- 配置一个日期对象 -->
    <bean id="now" class="java.util.Date"></bean>
    
(2)Set方式注入(常用)
  • 定义:在类中提供需要注入成员的 set 方法
  • 说明:
    • 涉及的标签:property
    • 出现的位置:bean标签的内部
    • 标签的属性
      • name:用于指定注入时注入的对象的名称(IOC容器会调用该对象的set方法)
      • value:用于提供基本类型和String类型的数据
      • ref:用于指定其他的bean类型数据
    • 优势:创建对象时没有明确的限制,可以直接使用默认构造函数。
    • 弊端:如果有某个成员必须有值,则获取对象是有可能set方法没有执行。
(3)基于xml的自动装配
  • 定义:
    • 自动装配是spring满足bean依赖注解一种方式
    • Spring会在上下文中自动寻找,并自动给bean装配属性
  • 三种自动装配方式:
    • 在xmI中显示的配置(ByName、ByType)
    • 注解显示配置
    • 隐式的自动装配bean 【重要】
①搭建环境
    public class Cat {public void shout(){System.out.println("喵喵");}}public class Dog {public void shout(){System.out.println("旺旺");}}public class Person {private Cat cat;private Dog dog;private String name;@Overridepublic String toString() {return "Person{" +"cat=" + cat +", dog=" + dog +", name='" + name + '\'' +'}';}//getting、setting}
②ByName自动装配
  • byName:会自动在容器上下文中查找,和自己对象set方法后面的值对应的beanId
<bean id="cat" class="com.kuang.pojo.Cat"/>
<bean id="dog" class="com.kuang.pojo.Dog"/><bean id="person" class="com.kuang.pojo.Person" autowire="byName"><property name="name" value="小海子"/>
</bean>
③ByType自动装配
  • byType:会自动在容器上下文中查找,和自己对象属性类型相同的bean
    <bean class="com.kuang.pojo.Cat"/><bean class="com.kuang.pojo.Dog"/><bean id="person" class="com.kuang.pojo.Person" autowire="byType"><property name="name" value="小海子"/></bean>
④小结
  • byname的时候,需要保证所有bean的id唯一 ,并且这个bean需要和自动注入的属性的set方法的值一致。
  • bytype的时候, 需要保证所有bean的class唯一 ,并且这个bean需要和自动注入的属性的类型一致;全局唯一,id属性可以省略。
(4)基于注解的自动装配
  • jdk1.5支持的注解,Spring2.5支持注解

  • 作用:和在xml配置文件中的bean标签中写一个标签的作用是一样

  • 注解:

    注解功能使用前提
    @Autowired根据属性类型进行自动装配
    即通过byType——>bean标签的class属性方式实现
    /
    @Qualifer根据属性名称(由@Component的value值指定)进行注入
    即通过byName——>bean标签的id属性实现
    在该属性注入的基础上
    @Resource根据类型注入,可以根据名称注入(默认根据类型注入)/
    @Value注入普通类型属性/

3.4.4详讲@Autowired、@Qualifer、@Resource、@Value

  • spring的IOC底层实际上就是一个Map结构容器,所谓**key 就是 bean标签 中的 idvalue 则是对应 bean标签 中的 class**
(1)@Autowired
①用在何处?
  1. Spring 2.5 引入了 @Autowired 注释,可以对类成员变量方法构造函数、参数等进行标注【主要还是用在变量方法】,完成自动装配的工作。
  2. 使用@Autowired注解注入的属性,该属性不需要这个类提供set方法,方便快捷
  3. @Autowired作用就和在xml配置文件中的bean标签中写一个< property >标签的作用是一样的。
  4. @Autowired自动装配首先会在IOC容器中跳过key直接去容器中找到对应的属性(bean标签中的Class)!也就是说与key无关
②三种情况
  1. 容器中有==唯一的一个bean对象类型(Class类路径)==和被@Autowired修饰的变量类型匹配,就可以注入成功!
  2. 容器中没有一个bean对象类型和被@Autowired修饰的变量类型匹配,则注入失败运行报错。
  3. 容器中有==多个bean对象类型和被@Autowired修饰的变量类型匹配,则根据被@Autowired修饰的变量名寻找==,找到则注入成功【重点】
(2)@Qualifer
①用在何处
  1. @Qualifier的作用是在按照类中注入的基础之上按照名称注入
  2. 它在给类成员注入时不能单独使用(但是在给方法参数注入时可以单独使用)
  3. @Qualifier常常组合@Autowired一起使用,用来==指明具体名字的自动装配==
②使用情况
  • UserDaoImpl2类

image-20240309170911266

  • UserService3类注入UserDaoImpl2类

image-20240309170941360

(3)@Resource
  1. @Resource由J2EE提供,默认是按照byName自动注入(通过名字自动注入

  2. @Resource有两个重要的属性,name和type

    当然默认是通过name属性

    type属性多此一举,还不如用@Autowired

  3. @Resource 相当于 @Autowired + @Qualifier

    举例:

    @Autowired
    @Qualifier(value="userDaoImpl2")
    //相当于
    @Resource(name="userDaoImpl2")
    
(4)@Value
  1. @Value专门用来注入基本类型和String类型数据
  2. @Value注解有一个value 属性:用于指定数据的值。它可以使用spring中SpEL(也就是spring的EL表达式)。SpEL的写法:${表达式},当然也可以类似mybatis中的 #{表达式} 的写法
@Value("#{2*3}")  //#写法 表示6
private int age;@Value("178")    //普遍写法 178
private int height;@Value("${man.weight}")  //SpEL的写法一般操作配置文件中数据
private int weight;
(5)辨别@Autowired和@Resource的异同
  • 相同:两者都是用来自动装配的,都可以放在属性字段上
  • 不同:
    • 实现方式不同:
      • @ Autowired 通过byType的方式实现
      • @Resource 默认通过byname的方式实现
    • 找的过程不同:
      • 若@ Autowired 通过byType的方式找不到,则报错
      • 若@Resource 默认通过byname的方式找不到,则通过byType实现。如果两个都找不到的情况下,就报错。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

docker学习笔记——Dockerfile

Dockerfile是一个镜像描述文件&#xff0c;通过Dockerfile文件可以构建一个属于自己的镜像。 如何通过Dockerfile构建自己的镜像&#xff1a; 在指定位置创建一个Dockerfile文件&#xff0c;在文件中编写Dockerfile相关语法。 构建镜像&#xff0c;docker build -t aa:1.0 .(指…

Oracle SQL优化(读懂执行计划 一)

目录 SQL执行计划的作用示例演示执行计划概念介绍执行计划实例DISPLAY_CURSOR 类型DISPLAY_AWR 类型 指标详解 SQL执行计划的作用 示例演示 执行计划概念介绍 执行计划实例 DISPLAY_CURSOR 类型 DISPLAY_AWR 类型 指标详解

云服务器99元1年选腾讯云还是阿里云?站长测评

99元一年云服务器可以选择阿里云或腾讯云&#xff0c;选择阿里云99元服务器还是腾讯云99元服务器&#xff1f;价格相同&#xff0c;阿腾云建议选择阿里云99元服务器&#xff0c;原因有二&#xff0c;阿里云99元服务器是ECS&#xff0c;腾讯云99元服务器是轻量应用服务器&#x…

qt练习案例

记录一下qt练习案例&#xff0c;方便学习qt知识点 基本部件 案例1 需求&#xff0c;做一个标签&#xff0c;显示"你好"知识点&#xff0c;QLabel画面 4. 参考&#xff0c;Qt 之 QLabel 案例2 需求&#xff0c;做一个标签&#xff0c;显示图片 知识点&#xff0c;…

【JavaSE】抽象类与接口

Object 类 类 java.lang.Object是类层次结构的根类&#xff0c;即所有类的父类。 除Object类之外的任何一个Java类&#xff0c;全部直接或间接的继承于Object类。由此&#xff0c;Object类也被称为根父类。Object类中声明的成员具有通用性&#xff0c;并且Object类中没有声明…

Leetcode 59.螺旋矩阵Ⅱ

1.题目 2.思路 &#xff08;借用代码随想录的图&#xff09; 1.我们将转一圈看作一个循环&#xff08;1->2->3->4->5->6->7->8 这是一个循环&#xff09; 2.在这个循环里&#xff0c;我们要画四条边&#xff08;上右下左&#xff09; 填充上行从左到右 填…

Java对接腾讯云直播示例

首先是官网的文档地址 云直播 新手指南 可以发现它这个主要是按流量和功能收费的 价格总览 流量这里还只收下行的费用&#xff0c;就是只收观看消耗的流量费 其它的收费就是一些增值业务费 &#xff08;包括直播转码、直播录制、直播截图、直播审核、智能鉴黄、实时监播、移动直…

04-ESP32S3-GPIO

ESP32S3-IDF GPIO GPIO简介 ESP32S3提供了多达45个物理GPIO管脚&#xff0c;这些管脚不仅可以作为通用的输入输出接口&#xff0c;还可以连接到内部外设信号。通过GPIO交换矩阵、IO MUX和RTC IO MUX&#xff0c;可以灵活地配置外设模块的输入信号来源于任何GPIO管脚&#xff0…

空间复杂度(数据结构)

概念&#xff1a; 空间复杂度也是一个数学表达式&#xff0c;是对一个算法在运行过程中临时占用存储空间大小的量度 。 空间复杂度不是程序占用了多少bytes的空间&#xff0c;因为这个也没太大意义&#xff0c;所以空间复杂度算的是变量的个数。空间复杂度计算规则基本跟实践复…

【性能测试】性能测试各知识第1篇:性能测试大纲【附代码文档】

性能测试完整教程&#xff08;附代码资料&#xff09;主要内容讲述&#xff1a;性能测试大纲。。。。。。。。。。。。。。 全套笔记资料代码移步&#xff1a; 前往gitee仓库查看 感兴趣的小伙伴可以自取哦&#xff0c;欢迎大家点赞转发~ 性能测试大纲 |序号|阶段|概述| |--…

【MATLAB第100期】基于MATLAB的多种改进拉丁超立方LHS数据抽样方法

【MATLAB第100期】基于MATLAB的多种改进拉丁超立方LHS数据抽样方法 一、LHS种类 1、LHS 使用随机搜索生成拉丁超立方体样本。LHS函数特别适用于非常大的设计&#xff0c;当本机MATLAB函数内存不足时。这可能取决于MATLAB版本和所用机器的配置。当尝试运行“lhsdesign”但未成…

springboot实现国际化

引言 今天在开发过程中&#xff0c;遇到国外客户&#xff0c;要求项目一些返回msg中&#xff0c;不能再有中文&#xff0c;于是便有了国际化需求。 How to do 1.在项目resources下创建i18n文件夹以及messages.properties文件 messages.properties 国际化主文件 phoneErr.ms…

Guiding Large Language Models viaDirectional Stimulus Prompting

1. 通过定向刺激提示指导大语言模型 论文地址&#xff1a;[2302.11520] Guiding Large Language Models via Directional Stimulus Prompting (arxiv.org) 源码地址&#xff1a;GitHub - Leezekun/Directional-Stimulus-Prompting: [NeurIPS 2023] Codebase for the paper: &qu…

C语言——函数指针——函数指针数组 (详解)

函数指针数组 函数指针数组的作用 函数指针数组是一个数组&#xff0c;其中的每个元素都是一个函数指针。函数指针是指向函数的指针变量&#xff0c;可以用来调用相应的函数。函数指针数组的作用是可以根据需要动态地选择并调用不同的函数。 函数指针数组的使用场景有很多&…

站库分离技术--反向代理技术-雷池云WAF-给自己搭建一个安全点的网站

文章目录 概要整体架构流程技术名词解释技术细节ssh-ubuntu服务器docker-映射-链接-通信nginx反代mysql设置数据库新密码 小结我的mysql映射目录我的wordpress映射目录 成果展示 概要 新买了一个云服务器&#xff0c;想搭建一个站库分离的wordpress为主的网站&#xff0c;采用d…

docker容器的数据卷

1配置数据卷 docker run --namen01 -d --restartalways -p 80:80 -v /qy172/data/nginx/html:/usr/share/nginx/html nginx 2Docker应用部署 1搜索mysql镜像 docker search mysql 2拉取mysql镜像 docker pull mysql:5.6 3创建容器&#xff0c; 设置端口映射、目录映射 d…

每日一题leetcode第2834:找出美丽数组的最小和

目录 一.题目描述 二.思路及优化 三.C代码 一.题目描述 二.思路及优化 首先我们看到这个题&#xff0c;就是根据给出的数组元素个数N&#xff0c;从[1&#xff0c;N]找出N个元素&#xff0c;使得N个元素的和最小&#xff0c;其中随便抽两个数出来&#xff0c;两个数之和不能为…

Vue前端的工作需求

加油&#xff0c;新时代打工人&#xff01; 需求&#xff1a; 实现带树形结构的表格&#xff0c;父数据显示新增下级&#xff0c;和父子都显示编辑。 技术&#xff1a; Vue3 Element Plus <template><div><el-table:data"tableData"style"width…

基于斑翠鸟优化算法(Pied Kingfisher Optimizer ,PKO)的无人机三维路径规划(MATLAB)

一、无人机路径规划模型介绍 二、算法介绍 斑翠鸟优化算法&#xff08;Pied Kingfisher Optimizer ,PKO&#xff09;&#xff0c;是由Abdelazim Hussien于2024年提出的一种基于群体的新型元启发式算法&#xff0c;它从自然界中观察到的斑翠鸟独特的狩猎行为和共生关系中汲取灵…

Python刘诗诗

写在前面 刘诗诗在电视剧《一念关山》中饰演了女主角任如意&#xff0c;这是一个极具魅力的女性角色&#xff0c;她既是一位有着高超武艺和智慧的女侠士&#xff0c;也曾经是安国朱衣卫前左使&#xff0c;身怀绝技且性格坚韧不屈。剧中&#xff0c;任如意因不满于朱衣卫的暴行…