目录:

1、使用限定注解;
2、自定义限定注解;
3、自定义bean的生命周期;

开发环境: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; @Configuration
public 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; @RestController
public class DemoController { @Autowired
@Qualifier("bean1")
MyBean bean; @RequestMapping(value = "/")
public String index(){
return bean.getId();
}
}

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

二、自定义限定注解

如果需要根据特定的属性来指定注入的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)
@Qualifier
public @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; @Configuration
public 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; @RestController
public class DemoController { @Autowired
@MyBeanQualifier(type = "bean2")
MyBean bean; @RequestMapping(value = "/")
public String index(){
return bean.getId();
}
}

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

三、自定义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<String,Integer> beanCounts = new HashMap<String,Integer>();
//保存实例
private Map<String,Object> beans = new HashMap<String,Object>(); @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; @Configuration
public class MyConfig { @Autowired
BeanFactory factory; @PostConstruct
public void customScopeConfigurer(){
CustomScopeConfigurer config = new CustomScopeConfigurer();
config.addScope("three", new MyScope());
config.postProcessBeanFactory((ConfigurableListableBeanFactory)factory);
} @Bean
@Scope(scopeName = "three")
public MyBean bean1(){
return new MyBean("1");
} }

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

package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; @RestController
public class DemoController { @Autowired
ApplicationContext ctx; @RequestMapping(value = "/")
public String index(){
for(int i=0;i<5;i++){
System.out.println(ctx.getBean("bean1"));
}
return "";
}
}

运行项目后,浏览器访问:http://localhost:8080/,IDEA控制台输出:
com.example.demo.MyBean@61f13a02
com.example.demo.MyBean@61f13a02
com.example.demo.MyBean@61f13a02
com.example.demo.MyBean@54094334
com.example.demo.MyBean@54094334

可见前3次得到同一个bean实例。

附,项目结构图

Spring高级注解的更多相关文章

  1. Spring高级话题-@Enable***注解的工作原理

    出自:http://blog.csdn.net/qq_26525215 @EnableAspectJAutoProxy @EnableAspectJAutoProxy注解 激活Aspect自动代理 & ...

  2. Spring Boot实战笔记(九)-- Spring高级话题(组合注解与元注解)

    一.组合注解与元注解 从Spring 2开始,为了响应JDK 1.5推出的注解功能,Spring开始大量加入注解来替代xml配置.Spring的注解主要用来配置注入Bean,切面相关配置(@Trans ...

  3. Spring高级装配

    Spring高级装配 目录 一.Profile(根据开发环境创建对应的bean) 二.条件化的创建bean(根据条件创建bean) 三.处理自动装配歧义性(指定首选bean.限定符限制bean) 四. ...

  4. Spring高级装配(一) profile

    Spring高级装配要学习的内容包括: Spring profile 条件化的bean声明 自动装配与歧义性 bean的作用域 Spring表达式语言 以上属于高级一点的bean装配技术,如果你没有啥 ...

  5. spring mvc 注解详解

    1.@Controller 在SpringMVC 中,控制器Controller 负责处理由DispatcherServlet 分发的请求,它把用户请求的数据经过业务处理层处理之后封装成一个Model ...

  6. Spring常用注解用法总结

    转自http://www.cnblogs.com/leskang/p/5445698.html 1.@Controller 在SpringMVC 中,控制器Controller 负责处理由Dispat ...

  7. Spring MVC注解的一些案列

    1.  spring MVC-annotation(注解)的配置文件ApplicationContext.xml <?xml version="1.0" encoding=& ...

  8. Spring系列之Spring常用注解总结

    传统的Spring做法是使用.xml文件来对bean进行注入或者是配置aop.事物,这么做有两个缺点:1.如果所有的内容都配置在.xml文件中,那么.xml文件将会十分庞大:如果按需求分开.xml文件 ...

  9. spring @condition 注解

    spring @condition注解是用来在不同条件下注入不同实现的 demo如下: package com.foreveross.service.weixin.test.condition; im ...

随机推荐

  1. day04逻辑运算符短路、多分支结构(if和switch)、循环结构、while循环

    复习 1.运算符和表达式 1)表达式 2)算数运算符 + - * / % 3)关系运算符 >  <  >=  <=  ==  != 4)逻辑运算符 &&   | ...

  2. Cortex-A7 MPCore 简介与处理器运行模型

    Cortex-A7 MPcore 处理器支持 1~4 核,通常是和 Cortex-A15 组成 big.LITTLE 架构的,Cortex-A15 作为大核负责高性能运算,比如玩游戏啥的,Cortex ...

  3. 最近学习了Http连接池

    起因 6.1大促值班发现的一个问题,一个rpc接口在0~2点用户下单高峰的时候表现rt高(超过1s,实际上针对性优化过的接口rt超过这个值也是有问题的,通常rpc接口里面即使逻辑复杂,300ms应该也 ...

  4. Java连载61-异常的机制与分类

    一.is a.is like a.has a 1.is a(就是继承) public class Animal{ public void method1{ } } public class Dog e ...

  5. openwrt_在PPPOE上网的同时_访问光猫

    openwrt_在PPPOE上网的同时_访问光猫 转载注明来源: 本文链接 来自osnosn的博客,写于 2019-11-14. 参考文章: 光猫桥接模式下,通过路由器访问光猫.简单设置 设置Open ...

  6. 【性能测评】DSP库,MDK5的AC5,AC6,IAR和Embedded Studio的三角函数性能

    测试条件: 1.IAR8.30开最高等级速度优化. 2.MDK5.27正式版使用AC5开最高等级优化3,开启时间优化,测试C标准库和微库MicroLib两种. 3.MDK5.27正式版使用AC6开最高 ...

  7. 解决Entity 实体类中加了@Id 注解后仍然出现org.hibernate.AnnotationException: No identifier specified for entity 错误

    启动报错如下图所示: 解决方案: 查看网上的资料,大部分都说在实体类中没有添加加主键的注解@Id,这个是必须的.但是我的实体类中明明已经添加了@Id,为什么还会报这个错误呢? 后来检查了很久,发现是我 ...

  8. 编译Netty源码遇到的一些问题-缺少io.netty.util.collection包

    缺少包和java类 下载好Netty的源码后,导入到IDE,运行自带的example时编译不通过. 如下图,是因为io.netty.util.collection的包没有 点进去看,确实没有这个包 发 ...

  9. Java描述设计模式(14):解释器模式

    本文源码:GitHub·点这里 || GitEE·点这里 一.解释器模式 1.基础概念 解释器模式是对象的行为模式.给定一个语言之后,解释器模式可以定义出其文法的一种表示,并同时提供一个解释器.客户端 ...

  10. bootstrap-table 常用总结-1

    两种表格工具,今天都用到了,一种是我前几篇写到过的jqgrid,(传送门)另一个就是bootstrap-table了.用过之后会发现,两种表格的方式大同小异,但是为什么这次要换成bootstrap-t ...