【框架学习 | 第三篇】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 {

    // ....

    @Override
    public 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/beans
   http://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 {
    @Bean
    public 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;
    
        @Override
        public 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实现。如果两个都找不到的情况下,就报错。

在这里插入图片描述

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

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

相关文章

BadUsb制作

BadUsb制作 一个树莓派pico kali监听 需要的文件 https://pan.baidu.com/s/1_kyzXIqk9JWHGHstTgq7sQ?pwd6666 1.将pico插入电脑 2.将Bad USB固件中的文件复制到pico中&#xff0c;pico会重启 3.将Bad USB目录文件复制进去&#xff08;打开Bad USB目录文件复制&#xff09; …

Spring Boot单元测试与热部署简析

1 Spring Boot的简介 Spring Boot是一个用于构建独立的、生产级别的Spring应用程序的框架。它简化了Spring应用程序的开发过程&#xff0c;提供了自动配置和默认配置&#xff0c;使得开发者只需专注于业务逻辑的实现&#xff0c;而不用去关注繁琐的配置问题。 Spring …

伪分布Hadoop的安装与部署

1.实训目标 &#xff08;1&#xff09;熟悉掌握使用在Linux下安装JDK。 &#xff08;2&#xff09;熟悉掌握使用在Linux下安装Hadoop。 &#xff08;3&#xff09;熟悉掌握使用配置SSH免密登录。 2.实训环境与软件 环境 版本 说明 Windows 10系统 64位 操作电脑配置 …

HTML 学习笔记(一)开始

一、介绍: 首先引用百度百科的一段话作为介绍:   HTML的全称为超文本标记语言&#xff0c;是一种标记语言。它包括一系列标签&#xff0c;通过这些标签可以将网络上的文档格式统一&#xff0c;使分散的Internet资源连接为一个逻辑整体。HTML文本是由HTML命令组成的描述性文本…

[贰],万能开篇HelloWorld

1&#xff0c;新建项目 File/New/Project Android/Android Application Project 输入程序名字HelloWorld Next Next 选择Blank Activity 修改为HelloWorldActivity 2&#xff0c;异常点 2.1&#xff0c;异常1&#xff1a;No resource found that matches the given name The…

如何在Windows系统使用固定tcp公网地址ssh远程Kali系统

文章目录 1. 启动kali ssh 服务2. kali 安装cpolar 内网穿透3. 配置kali ssh公网地址4. 远程连接5. 固定连接SSH公网地址6. SSH固定地址连接测试 简单几步通过[cpolar 内网穿透](cpolar官网-安全的内网穿透工具 | 无需公网ip | 远程访问 | 搭建网站)软件实现ssh 远程连接kali! …

ubuntu23.10安装搜狗拼音

1.添加fcitx仓库 sudo add-apt-repository ppa:fcitx-team/nightly 更新: sudo apt-get update 安装fcitx sudo apt-get install fcitx fcitx安装成功 切换输入系统为fcitx

设计模式 代理模式

代理模式主要使用了 Java 的多态&#xff0c;主要是接口 干活的是被代理类&#xff0c;代理类主要是接活&#xff0c; 你让我干活&#xff0c;好&#xff0c;我交给幕后的类去干&#xff0c;你满意就成&#xff0c;那怎么知道被代理类能不能干呢&#xff1f; 同根就成&#xff…

Android14之解决报错:No module named selinux(一百九十三)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

Win32汇编操作数据库学习

1 连接数据库 使用odbc连接&#xff1b;在此层次没有ado或dao技术&#xff0c;只有odbc&#xff1b; 先写一个asm只是连接数据库&#xff1b; .386.model flat, stdcalloption casemap :none ; case sensitiveinclude windows.inc include user32.inc includelib user32.l…

R语言复现:中国Charls数据库一篇现况调查论文的缺失数据填补方法

编者 在临床研究中&#xff0c;数据缺失是不可避免的&#xff0c;甚至没有缺失&#xff0c;数据的真实性都会受到质疑。 那我们该如何应对缺失的数据&#xff1f;放着不管&#xff1f;还是重新开始?不妨试着对缺失值进行填补&#xff0c;简单又高效。毕竟对于统计师来说&#…

深入浅出计算机网络 day.1 概论④ 计算机网络的定义和分类

不要退却&#xff0c;要绽放魅力 我的心会共鸣 和你 —— 24.3.9 一、计算机网络的定义 计算机网络早期的一个最简单定义 现阶段计算机网络的一个较好的定义 二、计算机网络的分类 按交换方式分类 按使用者分类 按传输介质分类 按覆盖范围分类 按拓扑结构分类&#xff0c;可…

【C语言】linux内核ip_generic_getfrag函数

一、讲解 这个函数ip_generic_getfrag是传输层用于处理分段和校验和的一个辅助函数&#xff0c;它通常用在IP层当需要从用户空间拷贝数据构建成网络数据包时。这个函数的实现提供了拷贝数据和进行校验和计算&#xff08;如果需要的话&#xff09;的功能。函数的参数解释如下&a…

指针--2

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言1.指针运算1.1.指针-整数1.2.指针-指针1.3.指针的关系运算 2.野指针2.1 野指针成因2.2 如何规避野指针 3.assert 断言4.指针的使用和传址调用4.1 strlen的模拟实…

汇编语言程序设计实验四

实验目的和要求 1、熟练掌握汇编语言的程序格式&#xff0c;程序设计方法&#xff1b;学会使用masm6.11对源程序进行编译、链接、调试和运行 2、利用DOS功能调用INT21H的2号和9号功能进行屏幕显示的方法。 3、利用^Break退出程序的方法及局限性。 4、汇编程序的编写 实验环…

微服务自动化管理初步认识与使用

目录 一、ETCD 1.1、ETCD简介 对于实施工程师&#xff1a; 1.2、特点 1.3. 使用场景 1.4、 关键字 1.5 工作原理 二、ETCD的安装 2.1、下载路径 2.2、介绍 2.3、具体操作 安装服务端 安装etcd客户端 测试 三、ETCD使用 3.1、前奏具体操作 3.2、 常用操作 一、ET…

递归、搜索与回溯算法简介

何为递归&#xff1a;递归就是递去归来&#xff0c;函数自己调用自己的情况。 不在意递归的细节展开图 把递归的函数当成黑盒&#xff08;给黑盒一个东西&#xff0c;它就能完成想要的事&#xff09; 相信黑盒一定能完成这个任务 深度优先遍历和深度优先搜索都是指一个东西dfs…

德国史托斯 KARL STORZ tricam SLII telecam SLII SCBI thermoflator xenen 300 维修

德国史托斯 KARL STORZ tricam SLII telecam SLII SCBI thermoflator xenen 300 维修

微信小程序-侧滑删除

简介 movable-view和movable-area是可移动的视图容器&#xff0c;在页面中可以拖拽滑动。 本篇文章将会通过该容器实现一个常用的拖拽按钮功能。 使用效果 代码实现 side-view.wtml 布局见下面代码&#xff0c;left view为内容区域&#xff0c;right view为操作按钮&a…

公众号IP白名单已添加服务器IP 122.88... 依然给出 40164 错误

公众号的IP白名单已添加 122.88... 依然给出 40164 错误。 {"errcode":40164,"errmsg":"invalid ip 122.88... ipv6 ::ffff:122.88..., not in whitelist rid: 65e85a07-458dfc0d-16003e03"} 解决方案&#xff1a; 一、检查 AppID 是否正确&…