JAVA解决在@autowired,@Resource注入为null的问题

本文介绍如何在Spring框架中使普通Java类能够调用Service层组件,通过使用SpringContextUtil工具类实现跨类依赖注入。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


使用SpringMVC或者SSH过程中,有时可能会遇到这么一个问题。就是在一个普通的JAVA类(不是controller也不是action类)中无法注入在spring配置文件中配置的bean。比如你在一个普通java类想调用某个在spring中配置的service,你会发现不管你用@Resource还是@Autowired注解都无法注入,对象始终是null。那是因为一般普通的Java类没有被spring代理,自然无法通过spring注入相关的对象。难道这样就不能调用了吗?这里提供下面一个类来解决这个问题:


SpringContextUtil


package com.im.utils;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

/**
 * 这个类是为了解决在普通类调用service的问题
 * 
 * @ClassName SpringContextUtil
 * @Description
 * @author kokjuis 189155278@qq.com
 * @date 2016-6-12
 * @content
 *      
 */
public class SpringContextUtil implements ApplicationContextAware {
	private static ApplicationContext applicationContext; // Spring应用上下文

	// 下面的这个方法上加了@Override注解,原因是继承ApplicationContextAware接口是必须实现的方法
	@Override
	public void setApplicationContext(ApplicationContext applicationContext)
			throws BeansException {
		SpringContextUtil.applicationContext = applicationContext;
	}

	public static ApplicationContext getApplicationContext() {
		return applicationContext;
	}

	public static Object getBean(String name) throws BeansException {
		return applicationContext.getBean(name);
	}

	public static Object getBean(String name, Class requiredType)
			throws BeansException {

		return applicationContext.getBean(name, requiredType);
	}

	public static boolean containsBean(String name) {
		return applicationContext.containsBean(name);
	}

	public static boolean isSingleton(String name)
			throws NoSuchBeanDefinitionException {
		return applicationContext.isSingleton(name);
	}

	public static Class getType(String name)
			throws NoSuchBeanDefinitionException {
		return applicationContext.getType(name);
	}

	public static String[] getAliases(String name)
			throws NoSuchBeanDefinitionException {
		return applicationContext.getAliases(name);
	}
}


然后在spring配置文件中配置一下这个类:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:task="http://www.springframework.org/schema/task"
	xmlns:cache="http://www.springframework.org/schema/cache"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	 http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
	 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd  
     http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd 
     http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.3.xsd 
     http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">

	<!--配置spring工具类 -->
	<bean id="SpringContextUtil" class="com.im.utils.SpringContextUtil"
		scope="singleton"></bean>


</beans>


然后通过这个类提供的方法就能正常的获取在spring中托管的bean了,使用很简单:


/**
     * 获取spring托管的redis连接池
     */
    private JedisPool jedisPool = (JedisPool) SpringContextUtil.getBean("jedisPool");



<think>首先,用户的问题是:“在Spring Boot项目中注入实例时,应该使用@Autowired还是@Resource,它们的区别和适用场景是什么?”这是一个关于Spring Boot中依赖注入注解的问题。 我需要基于提供的引用内容来回答。引用内容来自用户提供的文本,包括引用[1]到[4]。这些引用讨论了@Autowired@Resource的区别。 关键点总结自引用: - **来源不同**:@Autowired是Spring框架的注解;@ResourceJava EE规范的一部分(JSR-250)。[^1][^2] - **注入方式**: - @Autowired默认按类型注入。如果需要按名称注入,可以结合@Qualifier注解。[^1][^2][^4] - @Resource默认按名称注入(通过name属性)。如果名称未指定,则按类型注入。[^1][^2][^3] - **其他区别**: - @Autowired在IDEA中可能产生警告(如果字段未初始化),而@Resource不会出现警告。[^1] - @Autowired支持required属性,允许null值(设置required=false)。[^4] - @Resource支持更多参数,如name和type。[^1] - **适用场景**: - 如果项目已经使用Spring框架,@Autowired更自然。 - 如果希望代码更符合Java EE标准,或需要按名称注入@Resource可能更好。 - 在混合使用多个实现时,@Autowired + @Qualifier或@Resource都可以处理。[^2][^3] 用户的问题是关于在Spring Boot项目中如何选择。Spring Boot是基于Spring的,所以两者都可以使用,但推荐使用@Autowired因为它更Spring-centric。 回答结构: - **清晰结构**:逐步解释区别、优缺点、适用场景。 - **真实可靠**:基于引用内容,避免添加未提及的信息。 - **中文回答**:所有内容用中文。 - **LaTeX格式**:如果有数学表达式,使用$...$或$$...$$,但这个问题可能不涉及数学,所以可能不需要。用户指令说所有行内数学表达式必须使用$...$,但这里没有数学内容,所以忽略。 - **生成相关问题**:在末尾添加相关问题。 - **引用标识**:在回答中引用的内容末尾添加引用标识,如[^1]。 回答大纲: 1. **介绍**:简要说明@Autowired@Resource的作用。 2. **主要区别**:列出来源、注入方式、IDEA提示等。 3. **优缺点**:讨论各自的优势和劣势。 4. **适用场景**:建议在什么情况下使用哪个。 5. **总结**:给出一般推荐。 6. **相关问题**:生成3个相关问题。 相关问题应基于主题,如: 1. 如何在Spring Boot中处理多个实现类的注入? 2. @Autowired@Resource的性能差异? 3. 如何避免依赖注入时的常见错误? 确保回答基于引用: - 引用[1]:来源、查找顺序、参数、注入支持、IDEA提示。 - 引用[2]:注入方式示例。 - 引用[3]:为什么有时不能用注解(类未由Spring管理)。 - 引用[4]:@Autowired的required属性和@Qualifier使用。 最终回答: - 开头:直接回答问题。 - 主体:结构化解释。 - 结尾:相关问题。</think>### @Autowired@Resource 在 Spring Boot 中的选择与区别 在 Spring Boot 项目中,依赖注入是核心特性之一,用于管理对象之间的依赖关系。`@Autowired` 和 `@Resource` 都是常用的注入注解,但它们有显著差异。选择哪个取决于具体场景,如代码规范、注入需求及框架兼容性。下面我将逐步解释它们的区别、优缺点和适用场景,帮助您做出合理决策。 #### 1. **核心区别概述** - **来源不同**: - `@Autowired` 是 Spring 框架原生提供的注解,属于 Spring IOC(控制反转)的核心组件,专为 Spring 生态系统设计[^1][^2]。 - `@Resource` 是 Java EE 规范(JSR-250)的一部分,由 Java 标准支持,不依赖 Spring 框架[^1][^2]。这使得它在非 Spring 项目中更通用。 - *适用场景*:如果项目纯 Spring Boot 环境,`@Autowired` 更自然;如果需要跨框架兼容(如 Jakarta EE),`@Resource` 更合适。 - **注入方式不同**: - `@Autowired` 默认按**类型(Type)**注入。例如,注入一个 `UserService` 接口时,Spring 会查找其实现类。如果存在多个实现,需配合 `@Qualifier` 指定 Bean 名称[^2][^4]: ```java @Autowired @Qualifier("userServiceImpl1") // 指定名称 private UserService userService; ``` - `@Resource` 默认按**名称(Name)**注入,优先匹配 Bean 的 ID 或名称。如果名称未找到,则回退到按类型注入[^1][^3]: ```java @Resource(name = "userService") // 可省略 name 属性 private UserService userService; ``` - *适用场景*:当接口有多个实现类时,`@Resource` 的按名称注入更简洁;如果依赖关系基于类型设计,`@Autowired` 更直观。 - **其他关键差异**: - **参数支持**:`@Autowired` 支持 `required` 属性(默认为 `true`),允许注入为 `null`(设置 `required = false`)。而 `@Resource` 不支持此属性,但提供 `name` 和 `type` 参数[^1][^4]。 - **编译器提示**:在 IntelliJ IDEA 等 IDE 中,`@Autowired` 可能警告字段未初始化(需配合 `@Qualifier` 消除),而 `@Resource` 通常无此类警告[^1]。 - **依赖查找顺序**:`@Autowired` 严格依赖 Spring 容器;`@Resource` 先通过 JNDI 查找(在 Java EE 中),再回退到 Spring 的依赖注入[^1]。 #### 2. **优缺点分析** - **`@Autowired` 的优点**: - 与 Spring 生态无缝集成,支持高级特性如构造函数注入和 `@Qualifier`。 - 灵活性高,可通过 `required = false` 处理可选依赖。 - 缺点:在非 Spring 环境中不可用;多实现时需额外注解,代码稍显冗余。 - **`@Resource` 的优点**: - 符合 Java 标准,代码可移植性强。 - 按名称注入简化了多实现场景,减少配置。 - 缺点:功能不如 `@Autowired` 丰富(如不支持构造函数注入);在纯 Spring 项目中可能被视为“外来者”。 - **性能考虑**:两者在运行时性能无显著差异,但 `@Resource` 的按名称注入在复杂 Bean 图中可能略快,因为减少了类型匹配开销[^2]。 #### 3. **适用场景推荐** - **优先使用 `@Autowired` 的情况**: - 项目完全基于 Spring Boot,无需考虑跨框架兼容。 - 需要构造函数注入(如强制依赖)或处理可选依赖(`required = false`)。 - 示例:核心业务服务注入,结合 Lombok 或构造函数注入以提升可测试性。 ```java @Service public class OrderService { private final PaymentService paymentService; @Autowired public OrderService(PaymentService paymentService) { // 构造函数注入 this.paymentService = paymentService; } } ``` - **优先使用 `@Resource` 的情况**: - 项目混合 Java EE 和 Spring 技术栈,或需要代码可移植性。 - 接口有多个实现类,且希望简化配置(避免 `@Qualifier`)。 - 示例:第三方库或遗留系统集成,其中 Bean 名称明确。 ```java @Service public class ReportService { @Resource // 按名称注入 "pdfGenerator" private DocumentGenerator pdfGenerator; } ``` - **通用原则**: - **一致性**:在团队中统一选择一种注解,避免混用(如引用[2]所述,混用可能导致维护混乱)。 - **避免常见错误**:确保类被 Spring 管理(如添加 `@Component`、`@Service` 等注解),否则任何注入注解都无效[^3]。 - **Spring Boot 默认推荐**:Spring Boot 官方文档倾向于 `@Autowired`,但实际中两者均可工作。 #### 4. **总结** 在 Spring Boot 项目中,`@Autowired` 和 `@Resource` 的核心区别在于来源、注入方式和 IDE 支持。`@Autowired` 更适合纯 Spring 环境,提供更灵活的注入控制;`@Resource` 则胜在标准化和名称注入的简洁性。建议根据项目需求选择: - 新项目或纯 Spring Boot:优先 `@Autowired`。 - 混合技术栈或多实现场景:考虑 `@Resource`。 无论选择哪个,确保依赖的类已被 Spring 管理,否则注入将失败[^3]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值