@primary注解_阿里架构师分享Spring高级注解,Java程序员你都懂了吗?

971c4b83da8b7444aeded8a7844a4f63.png

开发环境:IntelliJ IDEA 2019.2.2

Spring Boot版本:2.1.8

新建一个名称为demo的Spring Boot项目。

一、限定注解

当存在多个同类型的bean时,可以使用Primary注解指定优先注入的bean。如果对bean的注入选择做进一步的控制,则可以使用限定注解。

限定注解可以与特定的参数关联起来,缩小类型匹配的范围,最后选择一个符合条件的bean来注入。

1、新建类 MyBean.java

package com.example.demo;public class MyBean { public MyBean(String id){ this.id = id; } private String id; public String getId() { return id; } public void setId(String id) { this.id = id; }}

2、新建类 MyConfig.java

package com.example.demo;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class MyConfig { @Bean public MyBean bean1(){ return new MyBean("1"); } @Bean public MyBean bean2(){ return new MyBean("2"); }}

3、新建一个控制器 DemoController.java

package com.example.demo;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RestControllerpublic class DemoController { @Autowired @Qualifier("bean1") MyBean bean; @RequestMapping(value = "/") public String index(){ return bean.getId(); }}

运行项目后,浏览器访问:http://localhost:8080/,页面显示:

1
ee897d09f5a3b4b0bd846c4bca6eb150.png

二、自定义限定注解

如果需要根据特定的属性来指定注入的bean,则可以自定义限定注解。

1、继续使用上面例子的类 MyBean.java

2、新建一个接口 MyBeanQualifier.java

package com.example.demo;import org.springframework.beans.factory.annotation.Qualifier;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target({ ElementType.FIELD, ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@Qualifierpublic @interface MyBeanQualifier { String type();}

3、修改上面例子代码 MyConfig.java

在配置bean时,需要为相应的bean设置不同的类型。

package com.example.demo;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class MyConfig { @Bean @MyBeanQualifier(type = "bean1") public MyBean bean1(){ return new MyBean("1"); } @Bean @MyBeanQualifier(type = "bean2") public MyBean bean2(){ return new MyBean("2"); }}

4、修改上面例子控制器代码 DemoController.java

package com.example.demo;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RestControllerpublic class DemoController { @Autowired @MyBeanQualifier(type = "bean2") MyBean bean; @RequestMapping(value = "/") public String index(){ return bean.getId(); }}

运行项目后,浏览器访问:http://localhost:8080/,页面显示:

2
775b1a5d02c09dd977846f7ba8fbf279.png

三、自定义bean的生命周期

Scope注解主要用于配置bean在容器中的生命周期,除了可以配置为singleton和prototype,在Web环境还可以配置为request、session等 值,表示容器会为一次请求或一个会话分配一个bean的实例。

如果对bean的生命周期有特殊需求,可以使用自定义的Scope。

例子:一个bean被使用3次后,就获取新的bean实例。

1、继续使用上面例子的类 MyBean.java

2、新建一个自定义的Scope类 MyScope.java

package com.example.demo;import org.springframework.beans.factory.ObjectFactory;import org.springframework.beans.factory.config.Scope;import java.util.HashMap;import java.util.Map;public class MyScope implements Scope { //记录bean的使用次数 private Map beanCounts = new HashMap(); //保存实例 private Map beans = new HashMap(); @Override public Object get(String s, ObjectFactory> objectFactory) { if(beanCounts.get(s) == null){ beanCounts.put(s, 0); } //第一次使用,放到实例的Map中 Integer beanCount = beanCounts.get(s); if(beanCount == 0){ Object newObject = objectFactory.getObject(); beans.put(s, newObject); } Object bean = beans.get(s); //计数器加1 Integer newBeanCount = beanCount + 1; if(newBeanCount >= 3){ newBeanCount = 0; } //设置新的次数 beanCounts.put(s, newBeanCount); return bean; } @Override public Object remove(String s) { return null; } @Override public void registerDestructionCallback(String s, Runnable runnable) { } @Override public Object resolveContextualObject(String s) { return null; } @Override public String getConversationId() { return null; }}

3、修改上面例子代码 MyConfig.java

将自定义Scope注册到容器中。

package com.example.demo;import org.springframework.beans.factory.BeanFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;import org.springframework.beans.factory.config.CustomScopeConfigurer;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Scope;import javax.annotation.PostConstruct;@Configurationpublic class MyConfig { @Autowired BeanFactory factory; @PostConstruct public void customScopeConfigurer(){ CustomScopeConfigurer config = new CustomScopeConfigurer(); config.addScope("three
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值