Java多线程中调用Spring的Bean三种实现方式
- 工作小总结
- 时间:2023-05-17 15:37
- 2617人已阅读
简介
一、背景 工作中我们想写个线程是很简单的,方式也很多,我在之前的文章Java实现多线程方式详解也介绍过,就不多讲了,但是实际工作中,尤其是采用spirng注解的方式的情况下,有时我们就要在线程中调用Spring的Bean,很多小伙伴还不知道怎么处理,我们今天就来聊聊Java多线程中调用Spring的Bean的几种方式,本文中SpringBoot版本为2.5.2,JDK环境为1.8,本文中使用到的
🔔🔔🔔好消息!好消息!🔔🔔🔔
有需要的朋友👉:联系凯哥
一、背景
工作中我们想写个线程是很简单的,方式也很多,我在之前的文章Java实现多线程方式详解也介绍过,就不多讲了,但是实际工作中,尤其是采用spirng注解的方式的情况下,有时我们就要在线程中调用Spring的Bean,很多小伙伴还不知道怎么处理,我们今天就来聊聊Java多线程中调用Spring的Bean的几种方式,本文中Spring Boot版本为2.5.2,JDK环境为 1.8,本文中使用到的依赖如下:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <version>2.5.2</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.14</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>compile</scope> </dependency>
本文使用@PostConstruct 进行测试,@PostConstruct 是一个java的注解,它修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器执行一次。
二、方式一:实现ApplicationContextAware接口
当一个类实现了这个接口(ApplicationContextAware)之后,这个类就可以方便获得ApplicationContext中的所有bean。前提是该类上有IOC相关注解才会生效,例如@Component(当然使用xml配置的bean信息也可以)
2.1、工具类
SpringBeanUtil.java
package com.alian.multithread.common; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; @Component public class SpringBeanUtil implements ApplicationContextAware { //定义静态ApplicationContext private static ApplicationContext applicationContext; //重写接口的方法,该方法在启动项目的时候会自动执行 //该类上有IOC相关注解才会生效,例如@Component @Override public void setApplicationContext(ApplicationContext context) throws BeansException { applicationContext = context; } //通过beanName获取Bean @SuppressWarnings("unchecked") public static <T> T getBean(String beanName) { return (T) applicationContext.getBean(beanName); } //通过beanClass获取Bean public static <T> T getBean(Class<T> beanClass) { return applicationContext.getBean(beanClass); } }
2.2、发送短信服务类
package com.alian.multithread.service; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @Slf4j @Service public class PushSmsService { public void pushSms() { log.info("推送短信服务子线程【{}】执行", Thread.currentThread().getName()); } }
2.3、发送短信线程类
package com.alian.multithread.thread; import com.alian.multithread.common.SpringBeanUtil; import com.alian.multithread.service.PushSmsService; public class PushSmsRunnable implements Runnable{ @Override public void run() { //获取到我们需要的bean PushSmsService pushSmsService = SpringBeanUtil.getBean(PushSmsService.class); pushSmsService.pushSms(); } }
2.4、发送短信测试
package com.alian.multithread.service; import com.alian.multithread.thread.PushSmsRunnable; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; @Slf4j @Service public class TestPushSmsService { @PostConstruct public void testPushSms() { for (int i = 0; i < 3; i++) { Thread thread = new Thread(new PushSmsRunnable()); thread.start(); } } }
运行结果:
三、方式二:线程内部构造方法
3.1、发送邮件服务类
package com.alian.multithread.service; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @Slf4j @Service public class SendEmailService { public void sendEmail() { log.info("发送邮件服务子线程【{}】执行", Thread.currentThread().getName()); } }
3.2、发送邮件线程类
package com.alian.multithread.thread; import com.alian.multithread.service.SendEmailService; public class SendEmailRunnable implements Runnable{ private SendEmailService sendEmailService; public SendEmailRunnable(SendEmailService sendEmailService){ this.sendEmailService=sendEmailService; } @Override public void run() { sendEmailService.sendEmail(); } }
3.3、发送邮件测试
package com.alian.multithread.service; import com.alian.multithread.thread.SendEmailRunnable; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; @Slf4j @Service public class TestSendEmailService { @Autowired private SendEmailService sendEmailService; @PostConstruct public void testSendEmail() { for (int i = 0; i < 4; i++) { Thread thread = new Thread(new SendEmailRunnable(sendEmailService)); thread.start(); } } }
运行结果:
四、方式三:内部类(推荐)
4.1、个性化服务类
package com.alian.multithread.service; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @Slf4j @Service public class PersonalService { public void personalBuss() { log.info("个性化服务子线程【{}】执行", Thread.currentThread().getName()); } }
4.2、个性化服务类测试
package com.alian.multithread.service; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; @Slf4j @Service public class TestPersonalService { @Autowired private PersonalService personalService; @PostConstruct public void execute() { for (int i = 0; i < 5; i++) { new PersonalThread().start(); } } private class PersonalThread extends Thread { @Override public void run() { TestPersonalService.this.personalService.personalBuss(); } } }