Spring详细讲解@Autowired注解

 更新时间:2022年06月17日 10:26:06   作者:写Bug的小廉  
@Autowired注解可以用在类属性,构造函数,setter方法和函数参数上,该注解可以准确地控制bean在何处如何自动装配的过程。在默认情况下,该注解是类型驱动的注入

java注解

在解释spring的注解之前,先了解一下什么是java的注解?:Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。

Java中类、变量、参数、 包等都可以添加注解,java的注解可以通过反射来获取到标注的内容,在编译器生成字节码文件时,标注信息也添加进去。当运行时,JVM可以根据标注信息获取相应的信息。

先给大家介绍一下java中常见的7种注解,这种注解也是spring中的注解的基础!前三个注解是用于代码上的注解,剩下的四个是用于修饰注解!

  • @Override - 检查该方法是否是重写方法。如果发现其父类,或者是引用的接口中并没有该方法时,会报编译错误。
  • @Deprecated - 标记过时方法。如果使用该方法,会报编译警告。
  • @SuppressWarnings - 指示编译器去忽略注解中声明的警告。
  • @Retention - 标识这个注解怎么保存,是只在代码中,还是编入class文件中,或者是在运行时可以通过反射访问。
  • @Documented - 标记这些注解是否包含在用户文档javadoc中。
  • @Target - 标记这个注解应该是哪种 Java 成员。
  • @Inherited - 标记这个注解是继承于哪个注解类(默认 注解并没有继承于任何子类)

spring注解

然后我们来说一下spring中注解的作用。

spring的重要特征就是控制反转和依赖注入。在spring中,将部分需要创建和生成的类的控制权限交给了spring容器进行管理,这就是控制反转。依赖注入就是将属性和类信息注入给相应的类。而这和我们要使用的注解有什么关系呢?

(1)配置文件形式

我们知道在出现注解之前,spring实现bean的管理是通过配置文件来实现的,所以我们先设计一个简答的bean来实现一下,如下:结构图在下面,为了方便我把代码放到了一起,实现请对比结构图!

package com.example.school;
import com.example.studuent.*;
public class chuzhong {
    private lisi Lisi;
    private zhangsan ZhangSan;
    public void setLisi(com.example.studuent.lisi Lisi) {
        this.Lisi = Lisi;
    }
    public void setZhangsan(com.example.studuent.zhangsan ZhangSan) {
        this.ZhangSan = ZhangSan;
    }
    public com.example.studuent.lisi getLisi() {
        return Lisi;
    }
    public com.example.studuent.zhangsan getZhangsan() {
        return ZhangSan;
    }
    public String toString()
    {
        return Lisi.name;
    }
}
package com.example.studuent;
public class lisi {
    public String name = "李四";
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public String studentname(){
        return name;
    }
}
package com.example.studuent;
public class zhangsan {
    public String name = "张三";
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public String studentname(){
        return "这个学生是:" + name;
    }
}
import com.example.school.*;
import com.example.studuent.lisi;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class annotationExample {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        chuzhong cz = (chuzhong) context.getBean("chuzhong");
        String name = cz.getLisi().studentname();
        System.out.println(name);
    }
}

配置文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
        <bean id="chuzhong" class="com.example.school.chuzhong" >
            <property name="lisi" ref="lisi" />
            <property name="zhangsan" ref="zhangsan" />
        </bean>
        <bean id="lisi" class="com.example.studuent.lisi" />
        <bean id="zhangsan" class="com.example.studuent.zhangsan" />
</beans>

运行结果:

可以看到,加载了相应的配置文件,然后spring容器依次创建了相应的实例对象。并成功输出的lisi实例对象的姓名。

这就是未使用注解时候,bean的使用方法。

(2)注解形式

加入了注解之后,我们会省下配置很多不必要信息的时间。最常用的自动装配的注解@Autowired,用于放置在类上用来修饰。

可以了解一下@Autowired的源码中的注解信息,咱们简单看一个重要的信息

这个说,构造函数、字段、setter方法或config方法标记为由Spring的依赖项注入工具自动连接。

而@Autowired这个注解对应的,就是我们在chuzhong类中,写的set和get方法,以及配置文件中的property标签的内容,它可以帮我们自动关联bean对象,实现自动装配功能。

所以我们使用@Autowired注解之后的类文件和配置文件就变成了如下图,关联的zhangsan和lisi类对象的set和get方法省略,并且配置文件中property中内容省略,但是需要加上component-scan组件扫描配置,因为当出现@Autowired注解之后,会从base-package下查找相应的关联bean对象:

@Autowired的解析

我们来分析一下@Autowired中都是什么东西:

1,首先注解是使用@interface修饰的,意味着它实现了 java.lang.annotation.Annotation 接口,使用@interface修饰才可以生成注解的形式

2,绿色字体的意思,注解依赖是否是必须的,也就是你使用了@Autowired这个注解,那么可以手动配置required,是否使用,默认是写了该注解就是使用

3,我们在文章第一段说明了,有四个注解是用来修饰注解的。我用一段来解释一下其中字段的意思。

@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE}) 表示这个注解是用来修改哪种成员的,如果没有写这个@Target则表示,它可以用在任何地方。然后我们了解一下ElementType这个枚举类中中各个字段的意思。从下面我们可以看出,它可以修饰构造器、方法、参数、成员变量以及注解。所以多个ElementType对应一个注解。

TYPE:                 能修饰类、接口或枚举类型
FIELD:                能修饰成员变量
METHOD:               能修饰方法
PARAMETER:            能修饰参数
CONSTRUCTOR:          能修饰构造器
LOCAL_VARIABLE:       能修饰局部变量
ANNOTATION_TYPE:      能修饰注解
PACKAGE:              能修饰包
TYPE_PARAMETER:       能修饰类型参数
TYPE_USE:             所有类型都可以修饰(不包括类)

@Retention(RetentionPolicy.RUNTIME)用于指定该注解的生命周期,存活到什么时候,RUNTIME表明存活到运行时,可以反射获取相应的信息。

SOURCE:该注解存在于源码中,当编译成字节码时,就消失了。
CLASS: 该注解在java文件生成字节码文件后,存在于字节中,但是在jvm运行中就没了。@Retention的默认值,即当没有显式指定@Retention的时候,就会是这种类型。
RUNTIME: 该标注信息存在字节码中,jvm运行该字节码时,可以通过标注获取相应的信息

@Documented文中第一段有说明。

@Autowired的生效流程

而@Autowired是如何生效的呢?我引用一下别人的文章:SpringBoot中@Autowired是如何生效的,希望大家也可以看一看,我摘重点说一下。下图就是spring启动之后的流程。

首先是AutowiredPorcessor的BeanDefinition的注册

1, 创建ApplicationContext

2, 创建AnnotatedBeanDefinitionReader

3, 注册BeanDefinition registerAnnotationConfigProcessors

然后是AutowiredProcessor注册为bean

1,registerBeanPostProcessors

最后是注入

1,获取bean getBean()

2,创建bean doCreateBean()

​3,生成bean populateBean()

4,应用AutowiredProcessor ibp.postProcessProperties()

5,找到可注入的字段 buildAutowiringMetadata

6,注入 metadata.inject

spring的其余注解也可以参考这种形式,逐一进行分析,个人的注解放到(二)中实现。

到此这篇关于spring详细讲解@Autowired注解的解析的文章就介绍到这了,更多相关spring @Autowired内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java面试官最喜欢问的关键字之volatile详解

    Java面试官最喜欢问的关键字之volatile详解

    这篇文章主要给大家介绍了关于Java面试官最喜欢问的关键字之volatile的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Java具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-03-03
  • Ribbon负载均衡服务调用的示例详解

    Ribbon负载均衡服务调用的示例详解

    Rbbo其实就是一个软负载均衡的客户端组件,他可以和其他所需请求的客户端结合使用,这篇文章主要介绍了Ribbon负载均衡服务调用案例代码,需要的朋友可以参考下
    2023-01-01
  • Spring Cloud 动态刷新配置信息教程详解

    Spring Cloud 动态刷新配置信息教程详解

    这篇文章主要介绍了Spring Cloud 动态刷新配置信息的教程,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-06-06
  • Java 文件解压缩实现代码

    Java 文件解压缩实现代码

    这篇文章主要介绍了Java 文件解压缩实现代码,有需要的朋友可以参考一下
    2013-12-12
  • java启动参数之谜的排查过程

    java启动参数之谜的排查过程

    在日常操作中,相信很多人对Java启动参数存在疑惑,下面这篇文章主要给大家介绍了关于java启动参数之谜的排查过程,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-06-06
  • SpringMvc获取请求头请求体消息过程解析

    SpringMvc获取请求头请求体消息过程解析

    这篇文章主要介绍了SpringMvc获取请求头请求体消息过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09
  • java阻塞队列BlockingQueue详细解读

    java阻塞队列BlockingQueue详细解读

    这篇文章主要介绍了java阻塞队列BlockingQueue详细解读,在新增的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题,通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大的便利,需要的朋友可以参考下
    2023-10-10
  • 详细解读spring中的@Resource注解

    详细解读spring中的@Resource注解

    这篇文章主要介绍了详细解读spring中的@Resource注解,此注解来源于JSR规范(Java Specification Requests),其作用是找到依赖的组件注入到应用来,它利用了JNDI技术查找所需的资源,需要的朋友可以参考下
    2023-10-10
  • SpringBoot无法访问/static下静态资源的解决

    SpringBoot无法访问/static下静态资源的解决

    这篇文章主要介绍了SpringBoot无法访问/static下静态资源的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • MybatisPlus逆向工程的项目实践

    MybatisPlus逆向工程的项目实践

    Mybatis-Plus逆向工程,是MP官方提供的一款代码生成器,可以自动生成对应的实体类、Mapper接口和配置文件,,本文主要介绍了MybatisPlus逆向工程的项目实践,感兴趣的可以了解一下
    2024-03-03

最新评论