千家信息网

Spring中@Resource注解的作用是什么

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,Spring中@Resource注解的作用是什么,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。CommonAnnotationBea
千家信息网最后更新 2026年11月02日Spring中@Resource注解的作用是什么

Spring中@Resource注解的作用是什么,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

CommonAnnotationBeanPostProcessor是Spring中用于处理JavaEE5中常用注解(主要是EJB相关的注解)和Java6中关于JAX-WS相关的注解,可以处理@PostConstruct、@PreDestroy等Bean生命周期相关事件的注解,该后置处理最核心的是处理@Resource注解,同时还可以处理JAX-WS相关的注解。

一、触发方式

  • Spring容器在每个Bean实例化之后,调用后置处理器CommonAnnotationBeanPostProcessor的postProcessMergedBeanDefinition方法,查找该Bean是否有@Resource注解。

  • Spring在每个Bean实例化的时候,调用populateBean进行属性注入的时候,即调用postProcessPropertyValues方法,查找该Bean是否有@Resource注解。

二、构造函数

//CommonAnnotationBeanPostProcessor.java//构造方法public CommonAnnotationBeanPostProcessor() {        setOrder(Ordered.LOWEST_PRECEDENCE - 3);        //设置初始的注解类型为@PostConstruct        setInitAnnotationType(PostConstruct.class);        //设置销毁的注解为@ PreDestroy        setDestroyAnnotationType(PreDestroy.class);        //当使用@Resource注解时,忽略JAX-WS的资源类型        ignoreResourceType("javax.xml.ws.WebServiceContext");        }

三、注入

//CommonAnnotationBeanPostProcessor.javapublic PropertyValues postProcessPropertyValues(                PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {        //获取@Resource注解中配置的属性值元数据        InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs);        try {                //注入属性值,与AutowiredAnnotationBeanPostProcessor中处理相同                metadata.inject(bean, beanName, pvs);        }        catch (Throwable ex) {                throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex);        }        return pvs;        }

继续追踪,看metadata.inject(bean, beanName, pvs)方法

//InjectionMetadata.javapublic void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {        Collection checkedElements = this.checkedElements;        //要注入的字段集合        Collection elementsToIterate =                        (checkedElements != null ? checkedElements : this.injectedElements);        if (!elementsToIterate.isEmpty()) {                boolean debug = logger.isDebugEnabled();                //遍历 注入                for (InjectedElement element : elementsToIterate) {                        if (debug) {                                logger.debug("Processing injected element of bean '" + beanName + "': " + element);                        }                        element.inject(target, beanName, pvs);                }        }        }

这里和AutowiredAnnotationBeanPostProcessor不同的是,AutowiredAnnotationBeanPostProcessor调用的element.inject(target, beanName, pvs)方法是自己实现的,如图:

而CommonAnnotationBeanPostProcessor调用的element.inject(target, beanName, pvs)是原始方法,如下:

//InjectionMetadata.javaprotected void inject(Object target, @Nullable String requestingBeanName, @Nullable PropertyValues pvs)                throws Throwable {        if (this.isField) {                Field field = (Field) this.member;                //强吻访问                ReflectionUtils.makeAccessible(field);                //给字段赋值,即属性注入                field.set(target, getResourceToInject(target, requestingBeanName));        }        else {                if (checkPropertySkipping(pvs)) {                        return;                }                try {                        Method method = (Method) this.member;                        ReflectionUtils.makeAccessible(method);                        method.invoke(target, getResourceToInject(target, requestingBeanName));                }                catch (InvocationTargetException ex) {                        throw ex.getTargetException();                }        }        }

这里重点看getResourceToInject(target, requestingBeanName)方法,该方法的实现是具体获取@Resource中的值的。 我们可以看到在CommonAnnotationBeanPostProcessor类中,对该方法有实现:

//CommonAnnotationBeanPostProcessor.javaprotected Object getResourceToInject(Object target, @Nullable String requestingBeanName) {        return (this.lazyLookup ? buildLazyResourceProxy(this,requestingBeanName) :                getResource(this, requestingBeanName));        }

lazyLookup是CommonAnnotationBeanPostProcessor内部类ResourceElement的一个成员变量,表示是否懒加载,默认是false。 我们先来看下非懒加载的流程,即getResource(this, requestingBeanName):

//CommonAnnotationBeanPostProcessor.java//根据给定名称或者类型获取资源对象        protected Object getResource(LookupElement element, @Nullable String requestingBeanName) throws BeansException {        //如果注解对象元素的mappedName属性不为空        if (StringUtils.hasLength(element.mappedName)) {                //根据JNDI名称和类型去Spring的JNDI容器中获取Bean                return this.jndiFactory.getBean(element.mappedName, element.lookupType);        }        //如果该后置处理器的alwaysUseJndiLookup属性值为true        if (this.alwaysUseJndiLookup) {                //从Spring的JNDI容器中查找指定JDNI名称和类型的Bean                return this.jndiFactory.getBean(element.name, element.lookupType);        }        if (this.resourceFactory == null) {                throw new NoSuchBeanDefinitionException(element.lookupType,                                "No resource factory configured - specify the 'resourceFactory' property");        }        //使用autowiring自动依赖注入装配,通过给定的名称和类型从资源容器获取Bean对象        //一般情况下,都是走这一步        return autowireResource(this.resourceFactory, element, requestingBeanName);        }

autowireResource代码:

//CommonAnnotationBeanPostProcessor.javaprotected Object autowireResource(BeanFactory factory, LookupElement element, @Nullable String requestingBeanName)                throws BeansException {        Object resource;        Set autowiredBeanNames;        String name = element.name;        if (this.fallbackToDefaultTypeMatch && element.isDefaultName &&                        factory instanceof AutowireCapableBeanFactory && !factory.containsBean(name)) {                autowiredBeanNames = new LinkedHashSet<>();                //根据类型从Spring容器中查找资源                //调用依赖解析器,跟@Autowired是同样的代码                resource = ((AutowireCapableBeanFactory) factory).resolveDependency(                                element.getDependencyDescriptor(), requestingBeanName, autowiredBeanNames, null);                if (resource == null) {                        throw new NoSuchBeanDefinitionException(element.getLookupType(), "No resolvable resource object");                }        }        //根据名称从Spring容器中查找资源        else {                resource = factory.getBean(name, element.lookupType);                autowiredBeanNames = Collections.singleton(name);        }        //注册Bean的依赖关系        if (factory instanceof ConfigurableBeanFactory) {                ConfigurableBeanFactory beanFactory = (ConfigurableBeanFactory) factory;                for (String autowiredBeanName : autowiredBeanNames) {                        if (requestingBeanName != null && beanFactory.containsBean(autowiredBeanName)) {                                beanFactory.registerDependentBean(autowiredBeanName, requestingBeanName);                        }                }        }        return resource;        }

这里的逻辑比较简单:

  • 首先判断@Resource是按名称来查询还是类型,如果是类型,则调用依赖解析器根据类型从Spring容器中查找(这里和@Autowired的代码一样:Spring注解@Autowired源码分析)

  • 如果是按名称,则直接调用BeanFactory的getBean()方法,根据BeanName从Spring容器中查找

  • 最后由于发生了依赖注入,需要从新注册Bean的依赖关系

总结
  • @Resource注解既可以按照名称来注入,也可以按类型来注入。

关于Spring中@Resource注解的作用是什么问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注行业资讯频道了解更多相关知识。

注解 方法 类型 名称 容器 处理 属性 资源 代码 对象 问题 作用 处理器 字段 实例 时候 更多 分析 帮助 解答 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 南京欣网互联网络科技 互联网科技有限公司经营范围 科技互联网政务服务 互联网最新的科技有限公司 平安科技 互联网 华中科技大学互联网 小马过河互联网科技 南京欣网互联网科技 上海喔噻互联网科技 互联网养老 桔豆科技 互联网科技类展会 中国最先进互联网科技公司 天速互联网络科技有限公司 互联网教育科技公司vipkid 开一家科技互联网公司需要多少钱 晋城互联网科技 锡山区互联网智能科技产品供应 梅州GM互联网络科技有限公司 广州百诚互联网科技有限公司官网 科技信息时代互联网发展 互联网下的科技发展 互联网科技股有哪些 科技类的互联网平台 须眉科技是互联网公司吗 互联网企业和科技型企业 互联网软件和科技 允成互联网科技有限公司融资 广州千川互联网科技有限公司 领航科技大厦互联网公司 互联网科技包装股份有限公司上市
0