Spring详细讲解@Autowired注解

目录
  • java注解
  • spring注解
    • (1)配置文件形式
    • (2)注解形式
  • @Autowired的解析
  • @Autowired的生效流程

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内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Spring注解@Autowired背后实现的原理

    目录 前言 使用spring开发时,进行配置主要有两种方式,一是xml的方式,二是java config的方式. spring技术自身也在不断的发展和改变,从当前springboot的火热程度来看,java config的应用是越来越广泛了,在使用java config的过程当中,我们不可避免的会有各种各样的注解打交道,其中,我们使用最多的注解应该就是@Autowired注解了.这个注解的功能就是为我们注入一个定义好的bean. 那么,这个注解除了我们常用的属性注入方式之外还有哪些使用方式呢?它

  • Spring @Autowired注解超详细示例

    目录 前言 一.依赖注入的方式 手动注入 自动装配 二.注解@Autowired的自动装配原理 @Autowired自动装配过程 实现原理 ①首先看看spring的源代码定义 ②核心逻辑在buildAutowiringMetadata中 ③InjectionMetadata类 ④ 实现注入逻辑 ⑤调用InjectionMetadata中的公共inject ⑥遍历调用protect的inject方法 前言 说明:我们今天要分享的是依赖注入(DI)通过自动装配的注解方式@Autowird注解方法的作

  • 理解Java注解及Spring的@Autowired是如何实现的

    首先我们可以自己写一个注解: @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface AnnoSample { String value(); } 注解使用 @interface来标识.这个注解定义了一个属性value,只能作用于方法上,生命周期是运行时. @Target用于指定可以放置注解的位置,这里指定的METHOD说明该注解只能放置到方法上面,还可以指定TYPE(类.接口.枚举类),

  • Spring使用@Autowired注解实现自动装配方式

    目录 Spring支持注解配置 引入注解依赖 启用注解 使用@Autowired注解实现自动装配 1.IOC容器配置 2.实体类使用@Autowired注解注入属性 3.测试结果 @Autowired注解的使用和注入规则 1.使用在变量域上面 2.@Autowired注解使用在构造器上面 Spring支持注解配置 引入注解依赖 <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="ht

  • spring中使用@Autowired注解无法注入的情况及解决

    目录 spring @Autowired注解无法注入 问题简述 原因:(此处只说第二种) 解决方案 @Autowired注解注入失败,提示could not autowire spring @Autowired注解无法注入 问题简述 在使用spring框架的过程中,常会遇到这种两情况: 1.在扫描的包以外使用需要使用mapper 2.同目录下两个controller或者两个service,在使用@Autowired注解注入mapper或者service时,其中一个可以注入,另一个却为空. 原因:

  • Spring为什么不推荐使用@Autowired注解详析

    目录 引言 Spring的三种注入方式 属性(filed)注入 构造器注入 set方法注入 属性注入可能出现的问题 问题一 问题二 问题三 spring建议 使用@Resource代替@Autowired 使用@RequiredArgsConstructor构造器方式注入 总结 引言 使用IDEA开发时,同组小伙伴都喜欢用@Autowired注入,代码一片warning,看着很不舒服,@Autowired作为Spring的亲儿子,为啥在IDEA中提示了一个警告:Field injection i

  • 基于Spring@Autowired注解与自动装配详谈

    1 配置文件的方法 我们编写spring 框架的代码时候.一直遵循是这样一个规则:所有在spring中注入的bean 都建议定义成私有的域变量.并且要配套写上 get 和 set方法. Boss 拥有 Office 和 Car 类型的两个属性: 清单 3. Boss.java package com.baobaotao; public class Boss { private Car car; private Office office; // 省略 get/setter @Override p

  • SpringBoot @Autowired注解注入规则介绍

    目录 @Autowired注解注入规则 验证 小结一下 @Autowired注解无法自动注入的错误 @Autowired注解注入规则 @Autowired - 注入默认根据类型,匹配不到则根据bean名字 Spring中注解方式的默认beanName生成规则: 在Spring中,当我们配置一个bean的时候,可以不指定name,这样的话,Spring会生成一个默认的beanName 1. 驼峰形式类名首字母小写:UserService--userService 2. 特殊情况--当类名的首字母和

  • Spring使用@Autowired注解静态实例对象方式

    目录 Spring @Autowired注解静态实例对象 问题 原因 解决方案 方式一 方式二 方式三 方式四 总结 @Autowired注解和静态方法 一.业务场景 二.原理剖析 三.解决方法 1.将@Autowire加到构造方法上 2.用@PostConstruct注解 Spring @Autowired注解静态实例对象 问题 最近项目小组在重新规划工程的业务缓存,其中涉及到部分代码重构,过程中发现有些工具类中的静态方法需要依赖别的对象实例(该实例已配置在xml成Spring bean,非静

  • Spring详细讲解@Autowired注解

    目录 java注解 spring注解 (1)配置文件形式 (2)注解形式 @Autowired的解析 @Autowired的生效流程 java注解 在解释spring的注解之前,先了解一下什么是java的注解?:Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制. Java中类.变量.参数. 包等都可以添加注解,java的注解可以通过反射来获取到标注的内容,在编译器生成字节码文件时,标注信息也添加进去.当运行时,JVM可以根据标注信息获取相应的信息.

  • Spring详细讲解事务失效的场景

    目录 1)未被Spring管理 2)数据库引擎不支持事务 3)事务方法没有被public修饰 4)方法使用final修饰 5)同一类中方法调用 6)未开启事务 7)多线程调用 8)错误的传播行为 9)自己try…catch…掉了异常 10)手动抛出了错误的异常 11)自定义回滚异常 12)嵌套事务回滚多了 1)未被Spring管理 使用Spring事务的前提是:对象要被Spring管理,事务方法所在的类要被加载为bean对象 如果事务方法所在的类没有被加载为一个bean,那么事务自然就失效了,示

  • SpringBoot超详细讲解@Value注解

    目录 一.非配置文件注入 1.注入普通字符串 2.注入JAVA系统变量 3.注入表达式 4.注入其他Bean属性 5.注入文件资源 6.注入URL资源 二.通过配置文件注入 1.注入普通字符串 2.注入基本类型 3.注入数组类型 4.注入List类型 5.注入Map类型 一.非配置文件注入 1.注入普通字符串 直接附在属性名上,在 Bean 初始化时,会赋初始值. @Value("admin") private String name; 2.注入JAVA系统变量 @Value(&quo

  • Spring详细讲解FactoryBean接口的使用

    目录 一.基本使用 二.高级使用 FactoryBean是一个接口,创建对象的过程使用了工厂模式. 一.基本使用 让Spring容器通过FactoryBean来实现对象的创建. 创建FactoryBean案例 public class SimpleFactoryBean implements FactoryBean<Cat> { @Override public Cat getObject() throws Exception { // 创建Cat对象并且返回 return new Cat(&

  • SpringBoot超详细讲解@Enable*注解和@Import

    目录 @Enable* 解决办法 解放方案一 解决方案二 解决方案三 @Import 1.导入Bean 2.导入配置类 3.导入ImportSelector实现类 4.导入ImportBeanDefinitionRegistrar实现类 @Enable* 创建一个主启动类 package com.you.boot; import com.you.config.EnableUser; import com.you.config.UserConfig; import org.springframew

  • Spring详细讲解循环依赖是什么

    目录 前言 什么是循环依赖 Spring如何处理的循环依赖 只用一级缓存会存在什么问题 只用二级缓存会存在什么问题 Spring 为什么不用二级缓存来解决循环依赖问题 总结 前言 Spring在我们实际开发过程中真的太重要了,当你在公司做架构升级.沉淀工具等都会多多少少用到Spring,本人也一样,在研习了好几遍Spring源码之后,产生一系列的问题, 也从网上翻阅了各种资料,最近说服了自己,觉得还是得整理一下,有兴趣的朋友可以一起讨论沟通一波.回到标题,我们要知道以下几点: (1)什么是循环依

  • Spring框架中 @Autowired 和 @Resource 注解的区别

    Spring框架中 @Autowired 和 @Resource 注解的区别 在 spring 框架中,除了使用其特有的注解外,使用基于 JSR-250 的注解,它包括 @PostConstruct, @PreDestroy 和 @Resource 注释. 首先,咱们简单了解 @PostConstruct 和 @PreDestroy 注释: 为了定义一个 bean 的安装和卸载,我们可以使用 init-method 和 destroy-method 参数简单的声明一下 ,其中 init-meth

  • 详解Java的Spring框架中的注解的用法

    1. 使用Spring注解来注入属性 1.1. 使用注解以前我们是怎样注入属性的 类的实现: class UserManagerImpl implements UserManager { private UserDao userDao; public void setUserDao(UserDao userDao) { this.userDao = userDao; } ... } 配置文件: <bean id="userManagerImpl" class="com.

随机推荐