目录

@Configuration 配置类 与 @Bean 添加组件

@Resource 与 @Autowired 与 @Qualifier

@Qualifier 标记在方法参数前

@Primary 指定主实现类


1、已经知道 @ImportResource 导入Spring 配置文件 如以前经常在 beans.xml 配置的各种定时器、自己写的类以及各种第三方如 MyBatis 与 Hibernate 的类实例等,但 Spring 官方并不建议这么做,因为现在主流是面向全注解编程。

2、所以现在就用 @Configuration(配置类)来替代以前的 Spring 配置文件,用 @Bean 来替代 Spring 配置文件中 <bean> 标签,来给容器中添加组件

@Configuration 配置类 与 @Bean 添加组件

1、@Configuration 配置类

1)@Configuration 指明当前类是一个配置类,相当于把该类作为 spring 的 xml 配置文件中的 。

2)被 @Configuration 注解的类内部包含有一个或多个被 @Bean 注解的方法,这些方法将会被 AnnotationConfigApplicationContext 或AnnotationConfigWebApplicationContext 类进行扫描,并用于构建bean定义,初始化Spring容器。

3) @Configuation 等价于 <beans> ,@Bean 等价于  <bean>。

4)@Configuration 配置类必须是在 @SpringBootApplication 能扫描到的位置,及它的同级或者同级目录的子孙目录下。

2、@Bean 配置类

1)@Bean 是一个方法级别上的注解,配合 @Configuration 注解使用,也可以用在 @Component 注解的类里。

2)默认情况下 bean 的名称和方法名称相同,也可以使用 name 属性来指定,值是一个字符串数组,可以指定多个值。

3)autowire 属性有 3 个值,Autowire.NO:默认装配方式,Autowire.BY_NAME:根据名称装配,,Autowire.BY_TYPE:根据类型装配

4)@Bean 标注的方法在应用启动时就会自动执行,可以 System.out.println() 打印查看。

使用举例

1、提供一个接口与其两个实现类:

//兵器接口
public interface Weapon {String showInfo();
}
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.wmx.web_app.service.Weapon;//刀。业务层实现类此时并没有加 @org.springframework.stereotype.Service 注解
public class Knife implements Weapon {@Overridepublic String showInfo() {JsonNodeFactory nodeFactory = JsonNodeFactory.instance;ObjectNode objectNode = nodeFactory.objectNode();objectNode.put("code", 10011);objectNode.put("name", "血饮狂刀");return objectNode.toString();}
}
//枪、矛
public class Spear implements Weapon {@Overridepublic String showInfo() {JsonNodeFactory nodeFactory = JsonNodeFactory.instance;ObjectNode objectNode = nodeFactory.objectNode();objectNode.put("code", 10010);objectNode.put("name", "火尖枪");return objectNode.toString();}
}

2、提供配置类 @Configuration 与 @Bean 装配自己需要的对象:

import com.wmx.web_app.service.impl.Knife;
import com.wmx.web_app.service.impl.Spear;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** @Configuration 指明当前类是一个配置类;相当于把该类作为 spring 的 xml 配置文件中的 <beans>* @Configuration 配置类可以有多个*/
@Configuration
public class SystemConfig {/*** "@Bean" 相当于在 beans.xml 中的配置:<bean id="knife" class="com.wmx.web_app.service.impl.Knife"/>* 将方法的返回值添加到容器中,容器中这个组件默认的 id 就是方法名*/@Beanpublic Knife knife() {return new Knife();}@Beanpublic Spear spear() {return new Spear();}/*** 同一个实例可以装配多个到容器中,可以根据改变方法名来区分,或者直接使用 name 属性指定组件名称* 这在某些时候是非常有用的,比如装配2个 org.springframework.web.client.RestTemplate,一个使用负载均衡,一个不使用负载均衡*/@Bean(name = {"spearGold"})public Spear spearGold() {return new Spear();}
}

3、提供一个控制层方便从浏览器发请请求:

import com.wmx.web_app.service.impl.Knife;
import com.wmx.web_app.service.impl.Spear;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;//兵器控制层
@RestController
@RequestMapping("weapon")
public class WeaponController {@Autowiredprivate Knife knife;@Resourceprivate Spear spear;@Resource(name = "spearGold") //指定组件名称注入private Spear spearGold;/*** http://192.168.2.77:8080/weapon/info?type=1* http://192.168.2.77:8080/weapon/info?type=2* http://192.168.2.77:8080/weapon/info?type=3** @param type :1 表示枪,2表示刀* @return*/@GetMapping("info")public String info(@RequestParam long type) {String message = null;if (type == 1) {message = spear.showInfo();} else if (type == 2) {message = knife.showInfo();} else {message = spearGold.showInfo();}System.out.println(message);return message;}
}

@Resource 与 @Autowired 与 @Qualifier

1、@Resource、@Autowired 都可以标注在成员属性上,或属性的 setter 方法上。

2、@Autowired 注解按类型转配 bean,有一个 required 属性,表示必须找到匹配的 Bean,否则抛异常,默认值为 true,@Autowired(required=true) ,如果允许 null 值,可以设置它 required 属性为 false

3、@Autowired 可以与 @Qualifier 组合使用,添加限定符,解决按类型匹配找到多个 Bean 问题:

@Autowired
@Qualifier("circular") // circular 为 bean 的名称。表示如果按 Shape 类型匹配了多个时,则使用名称为 circular 的对象
private Shape shape; // 通常如果 Shape 接口有多个实现类被交由容器管理了,则此时需要使用 @Qualifier 进行限定

4、@Resource 先按名称装配 bean,当找不到名称匹配的 bean 时,再按类型装配。常用属性为 name,还有其它几个不常用的属性 lookup、type、mappedName、description 等。

@Resource   //未指定 name 属性时, 默认使用成员属性的变量名,当找不到名称匹配的 bean 时,再按类型装配
private Circular circular;@Resource(name = "rectangle") //指定被注入的 bean 的名称,当找不到名称匹配的 bean 时,不再按类型装配
private Rectangle rectangle;

使用举例

1、提供一个接口 Shape(图形),两个实现类 Circular(圆形)、Rectangle(矩形)代码如下:

//图形接口
public interface Shape {//画图,绘图,绘制void draw();
}
import com.wmx.web_app.service.Shape;
import org.springframework.stereotype.Service;
//矩形
@Service
public class Rectangle implements Shape {@Overridepublic void draw() {System.out.println("绘制矩形.");}
}
//圆形
@Service
public class Circular implements Shape {@Overridepublic void draw() {System.out.println("绘制圆形.");}
}

2、提供一个控制层从浏览器访问测试:

import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.wmx.web_app.service.Shape;
import com.wmx.web_app.service.impl.Circular;
import com.wmx.web_app.service.impl.Rectangle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;@RestController
@RequestMapping("shape")
public class ShapeController {@Autowired //按 Rectangle 类型注入private Rectangle rectangle;@Resource //先按名称(circular)注入,找不到时按 Circular 类型注入private Circular circular;@Autowired@Qualifier("circular") // circular 为 bean 的名称。表示如果按 Shape 匹配了多个类型时,则使用名称为 circular 的对象private Shape shape;@Resource(name = "rectangle") // 因为 Shape 接口有 2 个实现,所以必须指定特定名称private Shape shape2;//绘制图形。flag=1为矩形,flag=2为圆形。http://192.168.2.77:8080/shape/draw?flag=1@GetMapping("draw")public String draw(@RequestParam int flag) {JsonNodeFactory nodeFactory = JsonNodeFactory.instance;ObjectNode objectNode = nodeFactory.objectNode();objectNode.put("code", 200);objectNode.put("flag", flag);if (flag == 1) {rectangle.draw();objectNode.put("message", "矩形绘制");} else if (flag == 2) {circular.draw();objectNode.put("message", "圆形绘制");} else {objectNode.put("code", 500);objectNode.put("message", "参数值错误");}shape.draw();//输出"绘制圆形."shape2.draw();//输出"绘制矩形."return objectNode.toString();}
}

@Qualifier 标记在方法参数前

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.sql.DataSource;
/*** Springboot + JdbcTemplate 多数据源配置* 1、自定义 {@link DataSource}* 2、自定义 {@link JdbcTemplate}** @author wangMaoXiong* @version 1.0* @date 2022/2/23 17:06*/
@Configuration
public class DataSourceConfig {/*** 默认数据源* bean:name 属性用于指定实例的名称,同时添加到 Spring 容器中。不指定名称时,默认是与方法名称相同。* Primary:当使用 @Resource、@Autowired 注入时,如果出现多个相同类型,则选择 primary 标记的类型优先注入。* ConfigurationProperties:为实例注入全局配置文件中指定前缀下的配置信息*/@Bean@Primary@ConfigurationProperties(prefix = "spring.datasource.default")public DataSource dataSource() {return DataSourceBuilder.create().build();}//workflow 数据源@Bean(name = "workflowDataSource")@ConfigurationProperties(prefix = "spring.datasource.workflow")public DataSource workflowDataSource() {return DataSourceBuilder.create().build();}//element 数据源@Bean(name = "elementDataSource")@ConfigurationProperties(prefix = "spring.datasource.element")public DataSource elementDataSource() {return DataSourceBuilder.create().build();}//使用自定义的数据源重新创建 JdbcTemplate 实例,参数 DataSource 此时默认取的是上面 Primary 标记的实例@Bean(name = "jdbcTemplate")public JdbcTemplate defaultJdbcTemplate(DataSource dataSource) {return new JdbcTemplate(dataSource);}//使用自定义的数据源重新创建 JdbcTemplate 实例,使用 Qualifier 获取指定名称的 DataSource 实例@Bean(name = "workflowJdbcTemplate")public JdbcTemplate workflowJdbcTemplate(@Qualifier("workflowDataSource") DataSource dataSource) {return new JdbcTemplate(dataSource);}//使用自定义的数据源重新创建 JdbcTemplate 实例,使用 Qualifier 获取指定名称的 DataSource 实例@Bean(name = "elementJdbcTemplate")public JdbcTemplate elementJdbcTemplate(@Qualifier("elementDataSource") DataSource dataSource) {return new JdbcTemplate(dataSource);}
}

@Primary 指定主实现类

1、@Primary 注解同样可以用来处理一个接口多个实现类的值注入情况,它直接写在实现类上,标识如果出现多个类型时,选择此类型优先注入。

/*** 圆形* @Primary 注解标识此类为 Shape 接口的主实现,当根据类型注入 Shape 有多个子类型时,选择本类进行注入*/
@Service
@Primary
public class Circular implements Shape {@Overridepublic void draw() {System.out.println("绘制圆形.");}
}

2、现在注入 Shape 时,@Resource 可以不再需要 name 属性指定 bean 的名称,@Autowired 也不需要借助 @Qualifier 注解指定 bean 的名称,因为它默认会使用 Circular 进行注入。

    @Resourceprivate Shape shape3;@Autowiredprivate Shape shape4;

@Configuration、@Bean 装配组件 与 @Resource 与 @Autowired 与 @Qualifier 、@Primary 获取组件相关推荐

  1. Spring中@Resource与@Autowired、@Qualifier的用法与区别

    Spring中@Resource与@Autowired.@Qualifier的用法与区别 1.@Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法 ...

  2. @Resource、@Autowired、@Qualifier区别与使用,以及bean name 的默认生成规则。

    文章目录 前言 一.注解区别 1. @Autowired 2. @Qualifier 3. @Resource 二.使用三个注解 三.bean name默认生成规则 前言 一.注解区别 1. @Aut ...

  3. 同一接口有多个实现类,怎么来注入一个指定的实现?@Resource、@Autowired、@Qualifier

    如果一个接口有2个以上不同的实现类, 那么如何Autowire一个指定的实现 1:首先,UserService接口有两个实现类 UserService1和 UserService2 UserServi ...

  4. Spring @Resource、@Autowired、@Qualifier区别

    @Resource默认是按照名称来装配注入的,只有当找不到与名称匹配的bean才会按照类型来装配注入: @Autowired默认是按照类型装配注入的,如果想按照名称来转配注入,则需要结合@Qualif ...

  5. 【Spring注解驱动开发】使用@Autowired@Qualifier@Primary三大注解自动装配组件,你会了吗?

    写在前面 [Spring专题]停更一个多月,期间在更新其他专题的内容,不少小伙伴纷纷留言说:冰河,你[Spring专题]是不是停更了啊!其实并没有停更,只是中途有很多小伙伴留言说急需学习一些知识技能, ...

  6. 自动装配——@Autowired 构造器,参数,方法,属性都是从容器中获取参数组件的值||自定义组件想要使用Spring容器底层的一些组件 ApplicationContext,BeanFactory

    @Autowired:构造器,参数,方法,属性:都是从容器中获取参数组件的值 * 1).[标注在方法位置]:@Bean+方法参数:参数从容器中获取;默认不写@Autowired效果是一样的:都能自动装 ...

  7. spring的注解开发@Component @Bean @Value @Autowired、@Qualifier @PropertySource @Configuration

    spring的注解开发 启动注解功能 启动注解功能 ⚫ 启动注解扫描,加载类中配置的注解项 ⚫ 说明: ◆ 在进行包所扫描时,会对配置的包及其子包中所有文件进行扫描 ◆ 扫描过程是以文件夹递归迭代的形 ...

  8. 2、组件注册-@Configuration@Bean给容器中注册组件

    2.组件注册-@Configuration&@Bean给容器中注册组件 2.1 创建maven项目 spring-annotation pom.xml文件添加 spring-context 依 ...

  9. spring5学习系列之------1 给容器注册组件一 @Configuration  @Bean  @Scope  @Lazy

    在工作中我们对spring已经很常用了,但是用的大部分都是spring一些很少的部分,该系列是基于spring5版本的,先介绍相关组件的内容,在涉及到源码内容.话不多说,直接上干货吧 常用注解之给容器 ...

  10. Error creating bean with name 'userServiceImpl'Injection of autowired 分布式新搭建项目无法自动装配 creating bean

    错误:Error creating bean with name 'userServiceImpl': Injection of autowired dependencies failed; nest ...

最新文章

  1. input限制文字个数但是输入中文时会被切断_Python文字转换语音,让你的文字会「说话」抠脚大汉秒变撒娇萌妹...
  2. SAP MM MIGO + 301 K 可以对供应商寄售库存跨工厂转库
  3. NodeJS http服务端获取POST请求数据
  4. Python+selenium 自动化-基本环境搭建,调用selenium库访问百度查询天气实例演示
  5. java xwork_java-与休眠的Struts2 xwork类型转换
  6. xamarin和mysql_Xamarin.Android 使用 SQLiteOpenHelper 进行数据库操作
  7. 通知中心 NSNotificationCenter 的简单使用方法
  8. GPU:上的了AI,下的了游戏 | 简谈计算机图形学、深度学习与硬件的“三角关系“
  9. 一对一直播app大热,使用源码或自主开发一对一APP需要了解哪些技术?
  10. GridView合并表头多重表头无错完美版(以合并3列3行举例)
  11. [网络安全自学篇] 九.社会工程学之基础概念、IP获取、IP物理定位、文件属性
  12. 题6.12:有一行电文,已按照下面规律翻译成密码: A->Z a->z B->Y b->y C->X c->x即第1个字母编程第26个字母,第i个字母编程第(26-i+1)个字母,非字母字符不变,要求
  13. u盘1kb快捷方式病毒修复_修复“无法为2097152KB对象堆保留足够的空间” JFrog Artifactory启动错误...
  14. EasyUI(DataGrid修改删除)
  15. frp服务端(frps) 安装及使用
  16. 【Mysql数据库 第10章】MySQL的存储函数使用
  17. gitbook 插件 文章 TOC 目录
  18. python爬取网站m3u8视频,将ts解密成mp4,合并成整体视频
  19. cf655A Buses Between Cities
  20. 【锐捷无线】边缘感知配置

热门文章

  1. C语言内存地址对齐详解
  2. 解决VisualStudio2008下asp.net mvc开发向View中添加服务器控件崩溃的问题
  3. 孙鑫VC学习笔记:第十七讲 (一) 用剪贴板实现进程间的通信
  4. vs如何包含库文件以及头文件
  5. java流意外结束_java – POI – null之后的文件意外结束
  6. java 拉钩技术_拉钩JAVA高薪训练营笔记汇总
  7. (3)Matplotlib_subplot, subplots
  8. JSP教程第3讲笔记
  9. C++const类型
  10. caffe命令行解析