【问题标题】:Using @ComponentScan or <context:component-scan /> with only one class仅对一个类使用 @ComponentScan 或 <context:component-scan />
【发布时间】:2014-01-28 02:46:45
【问题描述】:

我正在维护一个包含两组主要包的项目,该项目使用 Spring 和 Spring MVC,其中一个包包含多个控制器并使用 XML 配置 (&lt;context:component-scan /&gt;) 进行扫描。

问题是另一个包中只有一个类(未扫描),我需要扫描这个类,但只有这个类,包中没有其他内容。我现在不能改变它的包裹,因为现在风险太大了。

那么有没有办法使用 annotations 或 XML 来做到这一点?

【问题讨论】:

  • 将最底部的包添加到您的context:componnent-scan
  • 问题是最底层的包包含其他类
  • 如果它是一个单一的类,为什么要对它进行组件扫描。为什么不简单地将它作为 bean 添加到上下文中...
  • 试试@Import(my.package.MyClass.class)

标签: spring spring-mvc component-scan


【解决方案1】:

@Bart 对 XML 的评价。

如果您需要使用注释引入该类,请将以下内容添加到您的 @Configuration 类之一

@ComponentScan(
    basePackageClasses = YourClass.class, 
    useDefaultFilters = false,
    includeFilters = {
        @ComponentScan.Filter(type = ASSIGNABLE_TYPE, value = YourClass.class)
    })

【讨论】:

  • 如果我需要从不同的包中拉出一堆单独的类怎么办?
  • 将包添加到basePackages 并将类添加到value 属性,使用大括号使其成为数组。
  • 它有效,但我想知道是否有什么不那么“冗长”
  • 例如,我正在尝试使用 AnnotationConfigWebApplicationContext.register 方法,指定一个单独的 @RestController 类,但它似乎不起作用:(其余控制器在指定路径上没有响应
  • 似乎上面链接的单独问题已被模组删除-希望那里没有任何有用的东西:(
【解决方案2】:

只需将 is 作为 bean 添加到您的上下文中,例如

<bean class="my.package.MyClass" />

【讨论】:

  • 有没有办法在纯 Java 中做到这一点?我知道@Bean,但我总是必须返回 bean 的实例而不仅仅是类,并让 spring 实例化它......
  • 默认情况下,spring 不使用 args 构造函数来实例化 bean。所以我看不到使用“@Bean public MyClass myClass() {return new MyClass();}”在 java 配置中实例化 bean 有任何问题。即使您多次调用 myClass() 方法,您也会得到相同的实例,除非您将 bean 范围从默认的“单例”更改。
  • @Alexander 有问题。如果您有 Postconstruct 或 Predestroy 方法,它们将不会被调用。
  • @FlorianWicher,AFAIK 当我们在配置类中用@Bean 注释某些方法时,Spring 负责管理 bean 的生命周期。即使您直接调用该方法,您实际上也调用了代理的方法(代理包装配置类)。因此,如果 Bean 的作用域是Prototype,那么 Spring 能够为每个调用执行初始化和销毁​​回调。唯一的例外是当您在 Configuration 类中调用 myClass() 方法时。但这不是主题启动案例,我认为......
【解决方案3】:

除了 Emerson Farrugia 描述的方法之外,还有一个从 Spring Framework 4.2 as mentioned in the documentation here 开始支持的不太冗长的解决方案。

从 Spring Framework 4.2 开始,@Import 也支持正则引用 组件类,类似于 AnnotationConfigApplicationContext.register 方法。这是 如果您想避免组件扫描,则特别有用,通过使用 一些配置类作为显式定义所有的入口点 你的组件。

所以你的例子会变成:

@Import(YourClass.class)

【讨论】:

  • 使用 Junit 对单个组件进行单元测试非常方便。谢谢罗伯特!
【解决方案4】:

您需要使用过滤器来过滤掉其他类,只包含您要扫描的类

<context:component-scan base-package="com.abc" >

    <context:include-filter type="regex" 
                   expression="com.abc.customer.dao.*DAO.*" /> 

</context:component-scan>

【讨论】:

  • 当他只需要一个类时,为什么还要包含多个类?它也不起作用,因为除非明确禁用,否则 use-default-filters 仍然是 true,而您还没有这样做。
猜你喜欢
  • 1970-01-01
  • 2011-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-11
  • 2017-02-04
  • 1970-01-01
相关资源
最近更新 更多