Spring在异步中无法自动注入(@Autowired)实例问题

Spring在异步中无法自动注入(@Autowired)实例问题

1、Spring实现异步开发

在较大型项目中,肯定会用到Java多线程的功能,不可能全部等待主线程来执行所有的任务,这样会一种的消耗时间。

在spring中通过注解方式就可以达到多线程的效果,不需要自己实现Runnable接口或者继承Thread的方法来实现多线程。通过@Anysc注解就可以实现异步开发,不阻塞主线程,开启线程来执行相应的任务。

具体的实现方式是,在Spring的配置类上加上注解@EnableAsync,表示启动异步任务,然后在具体的方法上面加上@Anysc注解,则表明该方法就可以通过异步的方式实现了。

2、Spring在异步中无法自动注入(@Autowired)实例问题

采用异步开发,等让效率得到提升,但是也会遇到一些问题,比如在Spring/SpringBoot经常会用@Autowired注解来实现自动注入Bean,但是在异步任务中,再通过自动注入获取实例对象就不行了,因为获得到的实例都为Null。再调用实例的方法就会抛出空指针异常。

这说明在异步任务中是不能采用自动注入的方法,为了解决这一问题,在网上找了很多的资料才发现下面这个代码是可以解决这个问题的,亲测可用。

以下代码来自于博文解决SpringBoot/Spring在异步中无法注入实例问题

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SpringUtils implements ApplicationContextAware {

    private static ApplicationContext applCon;
	/**
	* 为空时,设置实例
	*/
    @Override
    public void setApplicationContext(ApplicationContext applCon) throws BeansException {
        if (SpringUtils.applCon == null) {
            SpringUtils.applCon = applCon;
        }
    }

    /**
     * 获取applicationContext的实例applCon
     */
    public static ApplicationContext getApplicationContext() {
        return applCon;
    }
    
    /**
     * 通过name,以及Clazz获取指定的Bean
     */
    public static <T> T getBean(String name, Class<T> clazz) {
        return getApplicationContext().getBean(name, clazz);
    }

    /**
     * 通过clazz获取Bean(推荐使用这种)
     */
    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }
    
    /**
     * 通过name获取 Bean
     */
    public static Object getBean(String name) {
        return getApplicationContext().getBean(name);
    }
}
### 若依项目中 `@Autowired` 注解失效的原因 在若依项目或其他基于 Spring Boot 的应用中,`@Autowired` 注解可能因为多种原因而失效。通常情况下,这可能是由于依赖注入发生在非托管组件内或特定上下文中。 #### 反射导致的 `@Autowired` 失效 当使用反射创建对象时,这些对象不会被 Spring 容器管理,因此无法自动完成依赖注入[^2]。对于这种情况,可以考虑采用静态代理模式来确保目标对象能够访问到容器中的 Bean 实例。 ```java public class ReflectionUtil { private static final ApplicationContext context; static { context = SpringApplication.run(MyApplication.class); } public static Object getBean(String beanName){ return context.getBean(beanName); } } ``` #### 多线程环境下的 `@Autowired` 失效 另一个常见场景是在多线程环境中执行异步任务时遇到的问题。默认情况下,在新启动的工作线程里是没有办法直接继承父级作用域内的 Bean 实例的[^4]。针对这个问题,可以通过实现 `ApplicationContextAware` 接口来自定义工具类获取当前应用程序上下文,并从中提取所需的 Bean 对象: ```java @Component public class ApplicationContextHolder implements ApplicationContextAware { private static ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext ctx) throws BeansException { applicationcontext = ctx; } public static <T> T getBean(Class<T> requiredType) { return applicationContext.getBean(requiredType); } } ``` 随后可以在任何地方通过调用此类的方法取得所需的服务层组件实例来进行操作。 #### 邮件工具类中 `@Autowired` 失效的情况 如果是在邮件发送功能模块发现此异常,则需确认 UserMapper 是否已被正确配置为 Spring 管理的对象以及其所在包路径是否已加入扫描范围之内[^1]。另外还需注意检查是否存在循环依赖等问题影响正常初始化过程。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值