Spring三种方法的注解自动注入问题

 更新时间:2022年12月28日 10:15:50   作者:良猿啊  
这篇文章主要介绍了Spring三种方法的注解自动注入问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

Spring三种方法的注解自动注入

1 @Autowired注解

@Autowired是Spring提供的自动注入的方法,该注解可以放在变量和方法上,在bean+返回值类型的注解中,@Autowired还可以放在参数前;@Autowired默认的注入是根据类型注入,如果相同类型的bean有多个,可以配合@Qualifier使用,则会根据名字自动注入;除了配合@Qualifier使用之外,还可以在相同类型的多个bean中的其中一个加上@Primary注解,那么根据类型注入就会第一注入有@Primary注解的bean。

示例代码:

@Repository("stuDao1")
public class StudentDaoImpl1 implements StudentDao {
}
@Primary
@Repository("stuDao2")
public class StudentDaoImpl2 implements StudentDao {
}
@Service("stuService")
public class StudentService {
	
	@Autowired	//从IOC容器中找到StudentDao类型的bean加入到studentDao中,AutoWired注入不调用set方法
	@Qualifier("stuDao")
	private StudentDao studentDao;
 
	//@Autowired	//也可以把AutoWired注解放到set方法上,并且会调用set方法
	public void setStudentDao(StudentDao studentDao) {
		this.studentDao = studentDao;
	}
}

2 @Resource

@Resource注解是Java规范(JSR250)提供的方法,该注解默认是根据bean的名字自动注入,如果没有找到对应的名字,则会自动根据类型查找并注入,可以使用name和type来指定根据名字还是类型来查找;@Resource注解同样可以使用@Primary。

示例代码:

public class StudentService {
 
//	@Resource(name="stuDao1") //根据名字查找bean
	@Resource(type=StudentDao.class)    //根据类型查找bean
	private StudentDao studentDao;
 
//  @Resource    //放在方法上
	public void setStudentDao(StudentDao studentDao) {
		this.studentDao = studentDao;
	}
}

3 @Inject

@Inject注解也是Java规范(JSR330)提供的方法,该注解默认是根据bean的类型自动注入,不过使用此注解需要导入javax-Inject.jar包;使用方法和@Autowired差不多一样,也可以配合@Qualifier和@Primary使用。

javax-Inject.jar下载地址

示例代码

@Service("stuService")
public class StudentService {
 
//	@Inject
//	@Qualifier("stuDao2")
	private StudentDao studentDao;
 
	@Inject
	@Qualifier("stuDao2")
	public void setStudentDao(StudentDao studentDao) {
		this.studentDao = studentDao;
	}
 
}

Spring 注解版 属性赋值 自动注入

spring的属性赋值,给一个bean的属性进行赋值,可以使用@Value注解。

该注解可以注入基本数值,字符串什么的@Value("zhangsan"),也可以结合SpEL表达式@Value("#{18+1}"),还可以读取配置文件中的属性@Value("${person.nickname}")(person.nickname,是外部配置文件的一个属性名)。

Person.java(一个普通的bean)

package com.sixteen.entity;

import lombok.Data;
import org.springframework.beans.factory.annotation.Value;

@Data
public class Person {

    /**
     * @Value注解
     * 1. 基本数值都可注入
     * 2. SPEl表达式 #{}
     * 3. ${} 获取配置文件中的值
     */

    // 配置文件中的值默认加载进环境变量
    /**可以这样在环境中取出
     * ApplicationContext context = new AnnotationConfigApplicationContext(SpringPropertiesValueConfig.class);
     * Environment environment = context.getEnvironment();
     * String property = environment.getProperty("person.nickname");
     * System.out.println(property);
     */
    @Value("zhangsan")
    private String name;
    @Value("#{18+1}")
    private Integer age;

    @Value("${person.nickname}")
    private String nickename;
}

SpringPropertiesValueConfig.java(配置类)

package com.sixteen.config;

import com.sixteen.entity.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

//使用@PropertySource导入外部配置文件,在bean里用@Value注解(@Value("${person.nickname}"))进行属性赋值
@PropertySource(value = {"classpath:person.properties"})
@Configuration
public class SpringPropertiesValueConfig {

    @Bean
    public Person person(){
        return new Person();
    }
}

person.properties(外部配置文件)

person.nickname="xiaosan"

这样就可以给实体类(bean)的属性进行赋值了,在springboot中读取外部配置文件的值时,还可以使用@ConfigurationProperties,这个注解之后再详细说,也可以百度查询资料,不过一般用于需要赋值的属性过多时可以考虑,因为这一个注解就可以将所有属性赋值,而不像@Value需要在每个属性上加上。

自动注入(又被叫做DI注入)即在一个组件中如果想用另一个组件就可以注入想用的组件(因为spring接管了所有的bean和组件,所以想要用别的bean或者组件就得从IOC容器中获取)。最典型的例子就是,在service层需要调用dao层方法(或者叫做mapper)这个时候就可以采用自动注入。

此时使用的配置文件和上面的配置文件不一样

SpringAutowiredConfig,java

package com.sixteen.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
 * @Autowired 自动注入
 *
 * @Autowired
 * private YyyMapper mapper;
 * 1) 默认按照类型去容器中找对应的组件,找到就赋值 context.getBean(SpringService.class);
 * 2) 如果找到多个相同类型的组件,再将属性的名称(mapper)作为组件id去容器查找 context.getBean("mapper")
 * @Qualifier(),传入bean的id,可以指定注入的bean,而不是用属性名
 *
 * 自动装配默认装配好,如果找不到组件,就报错
 * 也可以设置@Autowired(require=false),如果找不到装配的组件就不装配,也不会报错
 *
 * 可以使用@Primary注解,使装配首选为该bean,使用此注解时可再用@Qualifier()
 *  XxxService{
 *      YyyMapeer mapper;
 *  }
 */

@Configuration
@ComponentScan(basePackages = {"com.sixteen.service","com.sixteen.mapper"})
public class SpringAutowiredConfig {
}

SpringService.java(service层)

package com.sixteen.service;

import com.sixteen.mapper.SpringMapper;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class SpringService {

    @Autowired
    private SpringMapper mapper;
}

SpringMapper.java

package com.sixteen.mapper;

import org.springframework.stereotype.Repository;

@Repository
public class SpringMapper {
}

一般情况这样注入是没问题的,但如果你想自动注入的组件/bean有多个在IOC容器时,那么就有可能注入的不是你所想要的,具体规则如下:

/**
 * @Autowired 自动注入
 *
 * @Autowired
 * private YyyMapper mapper;
 * 1) 默认按照类型去容器中找对应的组件,找到就赋值 context.getBean(SpringService.class);
 * 2) 如果找到多个相同类型的组件,再将属性的名称(mapper)作为组件id去容器查找 context.getBean("mapper")
 * @Qualifier(),传入bean的id,可以指定注入的bean,而不是用属性名
 *
 * 自动装配默认装配好,如果找不到组件,就报错
 * 也可以设置@Autowired(require=false),如果找不到装配的组件就不装配,也不会报错
 *
 * 可以使用@Primary注解,使装配首选为该bean,使用此注解时可再用@Qualifier()
 *  XxxService{
 *      YyyMapeer mapper;
 *  }
 */

像service层中属性这样写的话,@Autowired private SpringMapper mapper;,如果IOC容器中有不止一个SpringMapper这种组件,那么就会根据mapper这个临时起的属性名,作为bean的id去IOC容器中查找是否有组件,所以在必要时,一个属性的名称不要随意起变量名。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Gateway+Swagger2配置聚合文档方式

    Gateway+Swagger2配置聚合文档方式

    这篇文章主要介绍了Gateway+Swagger2配置聚合文档方式,具有很好的参考价值,希望对大家有所帮助。
    2023-03-03
  • OpenTelemetry初识及调用链Trace详解

    OpenTelemetry初识及调用链Trace详解

    这篇文章主要为为大家介绍了OpenTelemetry初识及调用链Trace详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • Java枚举_动力节点Java学院整理

    Java枚举_动力节点Java学院整理

    enum 的全称为 enumeration, 是 JDK 5 中引入的新特性,存放在 java.lang 包中。这篇文章给大家介绍Java枚举相关知识,需要的的朋友参考下
    2017-04-04
  • Springboot和Jpa实现学生CRUD操作代码实例

    Springboot和Jpa实现学生CRUD操作代码实例

    这篇文章主要介绍了Springboot和Jpa实现学生CRUD操作代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • java  hibernate使用注解来定义联合主键

    java hibernate使用注解来定义联合主键

    这篇文章主要介绍了java hibernate使用注解来定义联合主键的相关资料,需要的朋友可以参考下
    2017-01-01
  • Spring Boot实现web.xml功能示例详解

    Spring Boot实现web.xml功能示例详解

    这篇文章主要介绍了Spring Boot实现web.xml功能,通过本文介绍我们了解到,在Spring Boot应用中,我们可以通过注解和编程两种方式实现web.xml的功能,包括如何创建及注册Servlet、Filter以及Listener等,需要的朋友可以参考下
    2023-09-09
  • 利用EasyPOI实现多sheet和列数的动态生成

    利用EasyPOI实现多sheet和列数的动态生成

    EasyPoi功能如同名字,主打的功能就是容易,让一个没见接触过poi的人员就可以方便的写出Excel导出,Excel导入等功能,本文主要来讲讲如何利用EasyPOI实现多sheet和列数的动态生成,需要的可以了解下
    2025-03-03
  • eclipse创建项目没有dynamic web的解决方法

    eclipse创建项目没有dynamic web的解决方法

    最近上课要用到eclipse,要用到Dynamic web project.但是我下载的版本上没有.接下来就带大家了解 eclipse创建项目没有dynamic web的解决方法,文中有非常详细的图文示例,需要的朋友可以参考下
    2021-06-06
  • springboot编程式事务TransactionTemplate的使用说明

    springboot编程式事务TransactionTemplate的使用说明

    这篇文章主要介绍了springboot编程式事务TransactionTemplate的使用说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • Java数据结构之数组(动力节点之Java学院整理)

    Java数据结构之数组(动力节点之Java学院整理)

    这篇文章主要介绍了Java数据结构之数组(动力节点之Java学院整理)的相关资料,包括创建和内存分配,数组封装后的使用等,需要的朋友参考下吧
    2017-04-04

最新评论