【spring bean】@Resource注解的自动注入策略 , 以 项目中注入多个线程池的Bean为例 附加自定义SpringBeanSupport
2021-03-06 08:27
标签:图片 应用 view 默认 ssi span exce card 返回 @Resource和@Autowired注解都是用来实现依赖注入的。只是@AutoWried按by type自动注入,而@Resource默认按byName自动注入。 @Resource有两个重要属性,分别是name和type spring将name属性解析为bean的名字,而type属性则被解析为bean的类型。所以如果使用name属性,则使用byName的自动注入策略,如果使用type属性则使用byType的自动注入策略。如果都没有指定,则通过反射机制使用byName自动注入策略。 @Resource依赖注入时查找bean的规则:(以用在field上为例) 1. 既不指定name属性,也不指定type属性,则自动按byName方式进行查找。如果没有找到符合的bean,则回退为一个原始类型进行查找,如果找到就注入。 此时name是变量名 错误示例: 此时的name值是配置bean里的name属性指定的值,而不是id的值 这里为什么要重新理解,是因为之前我一直认为对应的是配置文件的id属性的值,直到在配置上面两个String类型的bean的时候,居然会报错,如下: No qualifying bean of type [java.lang.String] is defined: expected single matching bean but found 2: bucketName,styleName 这是因为spring会去找bean元素里name属性值和变量名一致的bean,但是因为都没有指定name属性,所以找不到然后就按照原始类型String去查找,结果一下找到了两个,所以就报错。 2. 只是指定了@Resource注解的name,则按name后的名字去bean元素里查找有与之相等的name属性的bean。 正确示例 3. 只指定@Resource注解的type属性,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常 4. 既指定了@Resource的name属性又指定了type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常 ===========================以一份程序中 隔离多个业务线程池为例=================== 1.yml文件 2.java文件 线程池注入为Bean交给Spring管理 3.使用场景 3.1使用的地方[如果都是如下这样使用,则没有任何问题]: 如上的方式使用,则没有任何问题,因为 @Resource是byName自动注入的。 3.2 但是如果是下面这种使用方式,则会出现问题: 如上使用方式就会有问题,因为 B类中是按照byClass去注入的,而咱们隔离的三个独立的线程池,都是ThreadPoolTaskExecutor类型的,所以启动会报错,因为这个getBean会找到三个。 3.3 但是如果是修改为下面这种使用方式,则问题解决: 附加 附上SpringBeanSupport源码: 【spring bean】@Resource注解的自动注入策略 , 以 项目中注入多个线程池的Bean为例 附加自定义SpringBeanSupport 标签:图片 应用 view 默认 ssi span exce card 返回 原文地址:https://www.cnblogs.com/sxdcgaq8080/p/14301929.html@Resource
private String bucketName;
@Resource
private String styleName;
bean id="bucketName " class="java.lang.String">
constructor-arg value="${oos.bucketName}"/>
bean>
bean id="styleName " class="java.lang.String">
constructor-arg value="${oos.styleName}"/>
bean>
@Resource(name="bucket")
private String bucketName;
@Resource(name="style")
private String styleName;
bean name="bucket" class="java.lang.String">
constructor-arg value="${oos.bucketName}"/>
bean>
bean name="style" class="java.lang.String">
constructor-arg value="${oos.styleName}"/>
bean>
# 线程池配置
thread:
pool:
core:
size: 10
max:
size: 10
queue:
capacity: 10000
alive:
seconds: 1000
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ThreadPoolExecutor;
@Configuration
@ConditionalOnProperty(name = "thread.pool.core.size")
public class ThreadPoolConfiguration {
@Value("${thread.pool.core.size}")
private Integer coreSize;
@Value("${thread.pool.max.size}")
private Integer maxSize;
@Value("${thread.pool.queue.capacity}")
private Integer queueCapacity;
@Value("${thread.pool.alive.seconds}")
private Integer keepAliveSeconds;
@Bean(name = "taskExecutor1")
public ThreadPoolTaskExecutor taskExecutor() {
ThreadPoolTaskExecutor poolTaskExecutor = new ThreadPoolTaskExecutor();
poolTaskExecutor.setCorePoolSize(coreSize);
poolTaskExecutor.setMaxPoolSize(maxSize);
poolTaskExecutor.setQueueCapacity(queueCapacity);
poolTaskExecutor.setKeepAliveSeconds(keepAliveSeconds);
return poolTaskExecutor;
}
@Bean(name = "taskExecutor2")
public ThreadPoolTaskExecutor monitorTaskExecutor() {
ThreadPoolTaskExecutor poolTaskExecutor = new ThreadPoolTaskExecutor();
poolTaskExecutor.setCorePoolSize(coreSize);
poolTaskExecutor.setMaxPoolSize(maxSize);
poolTaskExecutor.setQueueCapacity(queueCapacity);
poolTaskExecutor.setKeepAliveSeconds(keepAliveSeconds);
poolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy());
poolTaskExecutor.setThreadNamePrefix("plat-form-monitor-pool-");
return poolTaskExecutor;
}
@Bean(name = "taskExecutor3")
public ThreadPoolTaskExecutor reportTaskExecutor() {
ThreadPoolTaskExecutor reportpoolTaskExecutor = new ThreadPoolTaskExecutor();
reportpoolTaskExecutor.setCorePoolSize(coreSize);
reportpoolTaskExecutor.setMaxPoolSize(maxSize);
reportpoolTaskExecutor.setQueueCapacity(queueCapacity);
reportpoolTaskExecutor.setKeepAliveSeconds(keepAliveSeconds);
reportpoolTaskExecutor.setThreadNamePrefix("report-export-pool-");
return reportpoolTaskExecutor;
}
}
A.Class中
@Resource
ThreadPoolTaskExecutor taskExecutor1;
B.Class中
@Resource
ThreadPoolTaskExecutor taskExecutor2;
C.Class中
@Resource
ThreadPoolTaskExecutor taskExecutor3;
A.Class中
@Resource
ThreadPoolTaskExecutor taskExecutor1;
B.Class中
public class B {
private static final ThreadPoolTaskExecutor taskExecutor;
static {
taskExecutor2 = SpringBeanSupport.getBean(ThreadPoolTaskExecutor.class);
}
}
A.Class中
@Resource
ThreadPoolTaskExecutor taskExecutor1;
public class B {
private static final ThreadPoolTaskExecutor taskExecutor;
static {
taskExecutor2 = SpringBeanSupport.getBean("taskExecutor2");
}
}
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class SpringBeanSupport implements ApplicationContextAware {
/** Spring应用上下文环境 */
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringBeanSupport.applicationContext = applicationContext;
}
/**
* @return ApplicationContext
*/
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* 获取对象
* @param name
* @return Object 一个以所给名字注册的bean的实例
* @throws BeansException
*/
public static
文章标题:【spring bean】@Resource注解的自动注入策略 , 以 项目中注入多个线程池的Bean为例 附加自定义SpringBeanSupport
文章链接:http://soscw.com/index.php/essay/60771.html