在开发中经常会使用Spring的@Autowired来实现对象的自动注入,但是在最近的开发中在多线程中用Spring的@Autowired来自动注入时总是注入不进去,代码如下:
package com.common.base.utils.SpringUtils; import org.springframework.beans.factory.annotation.Autowired; import java.util.concurrent.atomic.AtomicInteger; public class ThreadRunner implements Runnable{ @Autowired private ServiceBean serviceBean; private static AtomicInteger count = new AtomicInteger(0); @Override public void run(){ if (serviceBean ==null){ return; } serviceBean.log(); count.addAndGet(1); System.out.println("当前线程为:" + Thread.currentThread().getName() + "count:" + count); } public ServiceBean getServiceBean() { return serviceBean; } public void setServiceBean(ServiceBean serviceBean) { this.serviceBean = serviceBean; } }
其中,ServiceBean定义如下:
package com.common.base.utils.SpringUtils; import org.springframework.stereotype.Service; @Service("serviceBean") public class ServiceBean{ public void log(){ System.out.println("this is service bean."); } }
只是简单的输出语句。然后在主线程中,启动线程,如下:
package com.common.base.utils.SpringUtils; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath*:Service-*.xml"}) public class SpringMultiThreadTest{ @Test public void testSpringBean(){ for (int i=0; i<10000000; i++){ new Thread(new ThreadRunner()).start(); } try { Thread.sleep(1000); }catch (InterruptedException e){ e.printStackTrace(); } } }
此时,不会有打印信息,serviceBean为空。
原因:在主线程中使用了:
new ThreadRunner()
新建了一个实例,并不在Spring容器中,也就没法获得Spring中的bean。
解决办法:
1、将ThreadRunner类也作为一个bean注入到spring容器中,如下:
package com.common.base.utils.SpringUtils; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath*:Service-*.xml"}) public class SpringMultiThreadTest{ @Autowired private ThreadRunner threadRunner; @Test public void testSpringBean(){ for (int i=0; i<10000000; i++){ new Thread(threadRunner).start(); } try { Thread.sleep(1000); }catch (InterruptedException e){ e.printStackTrace(); } } }
问题解决。
2、使用Spring手动获得ServiceBean,首先写一个手动获得Spring bean的工具类:
package com.common.base.utils.SpringUtils; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; /** * 直接通过Spring 上下文获取SpringBean,用于多线程环境 * by jingquan @20160405 */ public class SpringBeanUtil implements ApplicationContextAware{ private static ApplicationContext applicationContext = null; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { SpringBeanUtil.applicationContext = applicationContext; } public static Object getBeanByName(String beanName) { if (applicationContext == null){ return null; } return applicationContext.getBean(beanName); } public static <T> T getBean(Class<T> type) { return applicationContext.getBean(type); } }
然后在ThreadRunner类中不自动获取,而是手动获取,代码如下:
package com.common.base.utils.SpringUtils; import org.springframework.beans.factory.annotation.Autowired; import java.util.concurrent.atomic.AtomicInteger; public class ThreadRunner implements Runnable{ private ServiceBean serviceBean; private static AtomicInteger count = new AtomicInteger(0); public ThreadRunner(){ this.serviceBean = (ServiceBean)SpringBeanUtil.getBeanByName("serviceBean"); } @Override public void run(){ if (serviceBean ==null){ return; } serviceBean.log(); count.addAndGet(1); System.out.println("当前线程为:" + Thread.currentThread().getName() + "count:" + count); } public ServiceBean getServiceBean() { return serviceBean; } public void setServiceBean(ServiceBean serviceBean) { this.serviceBean = serviceBean; } }
问题解决。
相关推荐
理解并熟练掌握这些方法,有助于在多线程环境下高效、安全地使用Spring注入的bean。在实际开发中,应根据具体需求选择合适的方式,确保代码的可读性、可维护性和性能。在进行线程处理时,还要注意线程安全问题,避免...
在 Spring 框架中,多线程下注入 Bean 是一个常见的问题。本文将详细介绍 Spring 多线程下注入 Bean 问题,并提供两种解决方案。 问题描述 在多线程环境下,使用 Spring 框架时,可能会遇到 Bean 注入失败的问题。...
当我们谈到在Spring中实现多线程,实际上是在讨论如何在Spring环境中创建、管理和协调并发执行的任务。这涉及到Java的并发API以及Spring对这些API的包装和扩展。 首先,让我们了解Java中的多线程基础。在Java中,...
当我们在多线程中使用 @Autowired 注解时,可能会出现 null 的情况。这是因为多线程是防注入的,容器中的组件不会自动注入到多线程中。 解决方案一:将需要使用的service当做多线程实现类的一个属性参数 在多线程...
为了在Spring中使用`ThreadPoolTaskExecutor`,我们需要在配置类中声明一个bean,如下所示: ```java @Configuration public class ThreadPoolConfig { @Bean(name = "threadPoolTaskExecutor") public ...
3. **多线程(TheadTool)**:在Java中,我们可以使用`java.lang.Thread`类来创建和管理线程,但实际开发中可能会遇到一些复杂情况,如线程同步、线程池管理等。TheadTool可能是自定义的工具类,用于简化多线程编程...
在IT行业中,多线程和Spring框架是两个非常重要的领域,尤其对于后端开发者来说,它们是必备的技术栈。下面将分别对这两个主题进行详细的知识点解析。 **多线程** 1. **线程概念**:线程是操作系统分配CPU时间片的...
标题 "HttpClient + Spring 实现多线程" 涉及到的是如何在Spring框架中使用Apache HttpClient库来创建一个支持多线程的HTTP客户端服务。Apache HttpClient是一个强大的HTTP客户端API,它提供了丰富的功能来处理HTTP...
在Spring Boot应用中,多线程的使用是一个关键特性,特别是在处理高并发或者需要执行耗时操作时。本文将深入探讨Spring Boot如何实现多线程,并结合提供的`spring-boot-multithreading.zip`压缩包中的示例进行讲解。...
SpringBoot 多线程处理任务中无法@Autowired注入bean问题解决 在 SpringBoot 应用程序中,多线程处理任务是一个常见的场景,但是,在多线程处理任务中无法使用 @Autowired 注入 bean,这是一个常见的问题。今天,...
总之,"java 后端学习资料包含(spring,多线程)"这个资料包是Java开发者深入学习和提升的宝贵资源,无论是对于Spring框架的使用还是多线程技术的掌握,都将带来实质性的进步。通过学习和实践,开发者可以更好地应对...
在本文中,我们主要探讨了在使用Spring Session以及Redis作为存储方式时,由于消息监听导致创建大量线程的问题及其解决方案。我们将从Spring Session的基础知识、Redis在Spring Session中的作用、监听机制导致线程...
总之,Spring Boot通过`ApplicationContextAware`接口和相关的工具类,使得在多线程环境中获取和使用bean变得简单易行,避免了手动管理bean实例的问题,保证了代码的整洁和可维护性。同时,这种方式也确保了bean的...
"解决SpringBoot项目使用多线程...使用TaskExecutor机制可以解决该问题,通过在配置文件中添加TaskExecutor的配置,并在Controller层中使用@Autowired注解来注入TaskExecutor,然后使用TaskExecutor来执行我们的任务。
综上所述,这个项目涉及到的知识点包括:分布式系统设计、Java多线程与线程池、Spring框架的多数据源支持、MyBatis的使用以及Spring的事务管理。通过这些技术的组合,可以构建出一个高效、可扩展的分布式应用,以...
在Spring Boot中,多线程开发是提升应用性能和并发能力的重要手段。Spring Boot通过`TaskExecutor`接口提供了一种方便的方式来实现多线程和...理解并遵循这些注意事项将有助于构建健壮、高效的多线程Spring Boot应用。
在本例中,我们可以创建一个`UserService`接口,用于处理转账操作,然后使用Spring来注入实现该接口的类。这样,我们可以在不修改代码的情况下更换或扩展服务的实现。 接下来,我们谈谈DBUtils。DBUtils是Apache的...
这份宝典囊括了Java编程中的基础知识、多线程编程、数据库操作、Spring框架、Spring Boot、Spring Cloud、Linux操作系统、分布式系统、设计模式、面试指导以及自我介绍等内容。 基础部分,包括Java编程语言的核心...
在多线程环境中,线程安全是个关键问题。当多个线程并发访问共享资源时,如果没有正确的同步机制,可能会导致数据不一致、死锁等问题。在Spring框架中,我们可以通过以下几种方式实现线程安全: 1. **ThreadLocal**...
3. **Spring注入Bean到Job**:在Job执行时,我们可以直接注入其他由Spring管理的Bean,无需在Job中创建这些对象,从而减少了代码的复杂性,增强了可重用性。 4. **JobFactory的自定义**:Quartz默认使用...