【问题标题】:Spring: Properly setup @ComponentScanSpring:正确设置@ComponentScan
【发布时间】:2013-07-25 12:15:36
【问题描述】:

我已经为我的Spring Application Context 设置了以下设置。


@Configuration
public class RmiContext {
@Bean
    public RmiProxyFactoryBean service() {
        RmiProxyFactoryBean rmiProxy = new RmiProxyFactoryBean();
        rmiProxy.setServiceUrl("rmi://127.0.1.1:1099/Service");
        rmiProxy.setServiceInterface(Service.class);
        return rmiProxy;
    }
}


@Configuration
public class LocalContext {
@Bean
    public Controller Controller() {
        return new ControllerImpl();
    }
}


@Configuration
@Import({RmiContext.class, LocalContext.class})
public class MainContext {

}

上述设置工作正常,但我想启用 @ComponentScan 使用 @Component 注释 @Component,因为我的应用程序中有许多 Controllers,当使用 @Bean 逐一声明时,这很乏味。


@Configuration
@ComponentScan(basePackageClasses = {Controller.class})
public class LocalContext {
    /* ... */
}
问题是当我做@ComponentScan(basePackageClasses = {Controller.class}) 时,以前正常工作的RmiProxyFactoryBean 无法识别或无法创建。

那么,如何配置我的MainContext 以便通过 RMI 和本地 bean 创建 bean?

【问题讨论】:

    标签: spring components rmi applicationcontext spring-remoting


    【解决方案1】:

    @Configuration 也是组件扫描的候选对象,因此您可以通过以下方式扫描 RmiContext 中的所有 bean 和控制器包中的所有控制器:

    @Configuration
    @ComponentScan(basePackages = {"org.example.controllers", "package.of.RmiContext"})
    public class MainContext {
    }
    

    --编辑--

    @Configuration 是组件扫描的候选者,这是在我的电脑上工作的测试用例:

    package scan.controllers;
    @Controller
    public class ExampleController {
    }
    
    package scan;
    public interface RMIService {
    }
    
    package scan;
    @Configuration
    public class RmiContext {
        @Bean
        public RmiProxyFactoryBean service() {
            RmiProxyFactoryBean rmiProxy = new RmiProxyFactoryBean();
            rmiProxy.setServiceUrl("rmi://127.0.1.1:1099/Service");
            rmiProxy.setServiceInterface(RMIService.class);
            rmiProxy.setLookupStubOnStartup(false);
            return rmiProxy;
        }
    }
    
    package scan;
    @Configuration
    //MainContext will auto scan RmiContext in package scan and all controllers in package scan.controllers
    @ComponentScan(basePackages = {"scan", "scan.controllers"})
    public class MainContext {
    }
    
    package scan;
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(classes={MainContext.class})
    public class TestContext {
    
        @Autowired private RMIService rmi;
        @Autowired private ExampleController controller;
    
        @Test
        public void test() {
            //both controller and rmi service are autowired as expected
            assertNotNull(controller);
            assertNotNull(rmi);
        }
    }
    

    【讨论】:

    • 就像我在问题中提到的那样,当 @ComponentScan 用于其他带有注释的 bean 时,无法识别通过 RMI(即服务)的 bean(即没有找到 Service 类型的 bean)异常@Component
    【解决方案2】:

    也许你可以尝试使用你的类的基础包(RMI、Controller):

    
    @ComponentScan(basePackages = {"your controller package", "your rmi package"})
    

    如果 RMI 类包与控制器不同,那么它们将无法通过 spring 实例化。

    【讨论】:

    • 另外你在创建控制器时不需要\@Configuration注解。只需使用 \@Controller
    • 我怎么知道“RMI 包”,因为这些 RMI 服务在远程调用时没有包?
    • @AyubMalik 我想你误会了。 @Configuration 是一个注解,用于定义基于 Java 的 spring 配置。也许你认为它是@Component。这基本上就是我想要做的,用@Component 或@Controller 注释组件类并使用@ComponentScan 而不是手动定义每个组件的@Bean。但问题是,当我这样做时,Rmi services 组件 bean 不再被创建或识别。
    【解决方案3】:

    如果我理解正确,您使用“@ComponentScan(basePackageClasses”) 但它没有检测和注册您的 spring bean?

    几分钟前我遇到了同样的问题。我没有放弃,尝试了所有有趣的猜测。一个猜测做到了。

    我必须在 XML 中添加一个 XML 组件扫描条目。我只是在那里放了一个虚拟包,如下所示:

     component-scan base-package="dummy.filler.to.enable.component.scan"
    

    XML 中的组件扫描似乎启用了@ComponentScan。

    [后期编辑:我注意到,我的 spring xml 架构是 spring 2.5。无论如何,我不知道这是否重要。最好的问候。]

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-04-12
      • 2015-10-22
      • 1970-01-01
      • 2017-03-16
      • 1970-01-01
      • 1970-01-01
      • 2017-07-25
      相关资源
      最近更新 更多