@Configuration、@Bean 装配组件 与 @Resource 与 @Autowired 与 @Qualifier 、@Primary 获取组件
目录
@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 获取组件相关推荐
- Spring中@Resource与@Autowired、@Qualifier的用法与区别
Spring中@Resource与@Autowired.@Qualifier的用法与区别 1.@Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法 ...
- @Resource、@Autowired、@Qualifier区别与使用,以及bean name 的默认生成规则。
文章目录 前言 一.注解区别 1. @Autowired 2. @Qualifier 3. @Resource 二.使用三个注解 三.bean name默认生成规则 前言 一.注解区别 1. @Aut ...
- 同一接口有多个实现类,怎么来注入一个指定的实现?@Resource、@Autowired、@Qualifier
如果一个接口有2个以上不同的实现类, 那么如何Autowire一个指定的实现 1:首先,UserService接口有两个实现类 UserService1和 UserService2 UserServi ...
- Spring @Resource、@Autowired、@Qualifier区别
@Resource默认是按照名称来装配注入的,只有当找不到与名称匹配的bean才会按照类型来装配注入: @Autowired默认是按照类型装配注入的,如果想按照名称来转配注入,则需要结合@Qualif ...
- 【Spring注解驱动开发】使用@Autowired@Qualifier@Primary三大注解自动装配组件,你会了吗?
写在前面 [Spring专题]停更一个多月,期间在更新其他专题的内容,不少小伙伴纷纷留言说:冰河,你[Spring专题]是不是停更了啊!其实并没有停更,只是中途有很多小伙伴留言说急需学习一些知识技能, ...
- 自动装配——@Autowired 构造器,参数,方法,属性都是从容器中获取参数组件的值||自定义组件想要使用Spring容器底层的一些组件 ApplicationContext,BeanFactory
@Autowired:构造器,参数,方法,属性:都是从容器中获取参数组件的值 * 1).[标注在方法位置]:@Bean+方法参数:参数从容器中获取;默认不写@Autowired效果是一样的:都能自动装 ...
- spring的注解开发@Component @Bean @Value @Autowired、@Qualifier @PropertySource @Configuration
spring的注解开发 启动注解功能 启动注解功能 ⚫ 启动注解扫描,加载类中配置的注解项 ⚫ 说明: ◆ 在进行包所扫描时,会对配置的包及其子包中所有文件进行扫描 ◆ 扫描过程是以文件夹递归迭代的形 ...
- 2、组件注册-@Configuration@Bean给容器中注册组件
2.组件注册-@Configuration&@Bean给容器中注册组件 2.1 创建maven项目 spring-annotation pom.xml文件添加 spring-context 依 ...
- spring5学习系列之------1 给容器注册组件一 @Configuration @Bean @Scope @Lazy
在工作中我们对spring已经很常用了,但是用的大部分都是spring一些很少的部分,该系列是基于spring5版本的,先介绍相关组件的内容,在涉及到源码内容.话不多说,直接上干货吧 常用注解之给容器 ...
- Error creating bean with name 'userServiceImpl'Injection of autowired 分布式新搭建项目无法自动装配 creating bean
错误:Error creating bean with name 'userServiceImpl': Injection of autowired dependencies failed; nest ...
最新文章
- input限制文字个数但是输入中文时会被切断_Python文字转换语音,让你的文字会「说话」抠脚大汉秒变撒娇萌妹...
- SAP MM MIGO + 301 K 可以对供应商寄售库存跨工厂转库
- NodeJS http服务端获取POST请求数据
- Python+selenium 自动化-基本环境搭建,调用selenium库访问百度查询天气实例演示
- java xwork_java-与休眠的Struts2 xwork类型转换
- xamarin和mysql_Xamarin.Android 使用 SQLiteOpenHelper 进行数据库操作
- 通知中心 NSNotificationCenter 的简单使用方法
- GPU:上的了AI,下的了游戏 | 简谈计算机图形学、深度学习与硬件的“三角关系“
- 一对一直播app大热,使用源码或自主开发一对一APP需要了解哪些技术?
- GridView合并表头多重表头无错完美版(以合并3列3行举例)
- [网络安全自学篇] 九.社会工程学之基础概念、IP获取、IP物理定位、文件属性
- 题6.12:有一行电文,已按照下面规律翻译成密码: A->Z a->z B->Y b->y C->X c->x即第1个字母编程第26个字母,第i个字母编程第(26-i+1)个字母,非字母字符不变,要求
- u盘1kb快捷方式病毒修复_修复“无法为2097152KB对象堆保留足够的空间” JFrog Artifactory启动错误...
- EasyUI(DataGrid修改删除)
- frp服务端(frps) 安装及使用
- 【Mysql数据库 第10章】MySQL的存储函数使用
- gitbook 插件 文章 TOC 目录
- python爬取网站m3u8视频,将ts解密成mp4,合并成整体视频
- cf655A Buses Between Cities
- 【锐捷无线】边缘感知配置