【问题标题】:How to autowire a bean annoted with @service in other class如何在其他类中自动装配用@service注释的bean
【发布时间】:2025-12-19 22:20:15
【问题描述】:

SPRING BOOT application 我有一个类如下

@Service
public class XYZ{
}

我想在其他类ABC中使用上面的

public class ABC{
@Autowired
private XYZ xyx;
}

它会抛出无法找到 XYZ 的错误。我已经在编写 main 方法的类中有@SpringBootApplication。因此,这将自动在包上启用@ComponentScan。我的理解是,由于 XYZ 已使用@service 进行注释,因此 spring 扫描并创建和注册该 bean。如何在不使用 xml 配置的情况下访问其他类中的 bean?

【问题讨论】:

标签: java spring spring-boot spring-bean


【解决方案1】:

你的 ABC 类也需要有 @Service 或 @Component 注解。否则,您将收到带有以下消息的警告。

自动装配的成员必须在有效的 Spring bean (@Component|@Service|...) 中定义。

@Service
public class ABC {

    @Autowired
    private XYZ xyx;
}

【讨论】:

    【解决方案2】:

    您的 ABC 类不在 Spring Boot 上下文中,这就是您无法获得 bean 的原因。您可能会通过以下方式获得它:

    创建一个 ApplicationContextProvider

    @Component
    public class ApplicationContextProvider implements ApplicationContextAware {
        private static ApplicationContext context;
    
        public static ApplicationContext getApplicationContext() {
            return context;
        }
    
        @Override
        public void setApplicationContext(ApplicationContext applicationContext)
                throws BeansException {
            context = applicationContext;
        }
    }
    

    之后需要通过以下方式调用:

    public class ABC {
       public void method() {
          XYZ xyz = ApplicationContextProvider.getApplicationContext().getBean(XYZ.class);
       }
    }
    

    【讨论】:

      【解决方案3】:

      如果你不想配置@ComponentScan。您需要将Class XYZ和ABC与Spring boot application runner class放在同一级目录中

      【讨论】:

        【解决方案4】:

        你的 ABC 类也应该是弹簧管理的

        您可以通过将其设为组件来做到这一点

        @Component
        public class ABC{
          @Autowired
          private XYZ xyx;
        }
        

        或将其作为 Bean 提供

         @Configuration
         public SomeConfig{
        
            @Bean
            public ABC abc(){
                return new ABC();
            }
         }
        

        【讨论】:

        • 如果Spring扫描这个类就不需要创建一个bean了。
        • @Debopam 您提供了一种将 ABC 注册为 bean autowireBean(abc) 的有效方法...所以 abc 是弹簧管理的
        • 根据代码ABC不是Spring管理的,没有标记注释。
        • @Debopam 但如果你想让@Autowired 工作就必须这样做
        • 否 还有其他工作方式。这就是我举这个例子的原因。即使在执行 new ABC() 之后,Spring 也可以使用对象自动装配实例。检查我的例子。
        【解决方案5】:

        在 Spring 启动应用程序运行器类中使用 @ComponentScan("<your root package>"),以便它检查所有组件并创建可以自动装配的 bean。调用类也应该是带有@Componenent 注释的组件。如果您将 ABC 的对象创建为 new ABC() 那么

        ABC abc = new ABC();  
        ContextProvider.getApplicationContext().getAutowireCapableBeanFactory().autowireBean(abc); //Autowiring dependencies
        
        //Then use the abc object which will have instance of XYZ populated.
        

        ContextProvider 实现

        import org.springframework.beans.BeansException;
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.context.ApplicationContext;
        import org.springframework.context.ApplicationContextAware;
        import org.springframework.core.Ordered;
        import org.springframework.core.annotation.Order;
        import org.springframework.stereotype.Component;
        
        /**
         * @author dpoddar
         *
         */
        @Component("ContextProvider")
        @Order(Ordered.HIGHEST_PRECEDENCE)
        public class ContextProvider implements ApplicationContextAware {
        
            @Autowired
            private static ApplicationContext CONTEXT;
        
            @Override
            public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
                CONTEXT = applicationContext;
            }
            /**
             * @return the cONTEXT
             */
            public static ApplicationContext getApplicationContext() {
                return CONTEXT;
            }
        
        
            /**
             * Get a Spring bean by type.
             **/
            public static <T> T getBean(Class<T> beanClass) {
                return CONTEXT.getBean(beanClass);
            }
        
            /**
             * Get a Spring bean by type.
             **/
            public static <T> T getBean(String beanName,Class<T> beanClass) {
                return CONTEXT.getBean(beanName, beanClass);
            }
        
            /**
             * Get a Spring bean by name.
             **/
            public static Object getBean(String beanName) {
                return CONTEXT.getBean(beanName);
            }
        
        }
        

        【讨论】:

        • 你应该删除 CONTEXT 上的 @Autowired,你不能在 Spring 中自动连接 static 字段。 (注意:CONTEXT 将通过 setApplicationContext 设置)