@Import注释的用例是什么?

时间:2016-02-19 09:48:06

标签: java spring spring-mvc

根据official doc

  

注释类型配置

     

表示一个类声明了一个或多个@Bean方法,可能是   由Spring容器处理以生成bean定义...

     

@Configuration类可以使用@Import注释组成,   与Spring XML中的工作方式不同。因为   @Configuration对象在其中作为Spring bean进行管理   容器..

但是我也可以在没有@Import的情况下使用@Configuration注释。我已经测试了下面列出的代码,它按预期工作。那么使用@Import的目的是什么?

DispatcherServletInitializer

public class ApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[] { WebConfig.class };
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return null;
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }

 }

WebMvcConfigurerAdapter

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = { "package.name" })
// @Import(OptionalConfig.class) 
public class WebConfig extends WebMvcConfigurerAdapter {
    // ...
}

OptionalConfig

@Configuration
public class OptionalConfig {

    @Bean(name = "myClass")
    public MyClass myClass() {
        return new MyClass();
    }
}

服务

@Service
public class MyServiceImpl implements MyService {

    @Autowired
    private MyClass myClass;    // yes, it works

    // ...
}

6 个答案:

答案 0 :(得分:16)

  

到目前为止,我们已经了解了如何将bean定义分解为多个@Configuration类以及如何跨@Configuration边界引用这些bean。这些场景需要将所有@Configuration类提供给JavaConfigApplicationContext的构造函数,这并不总是理想的。通常最好使用聚合方法,其中一个@Configuration类在逻辑上导入由另一个定义的bean定义。

     

@Import注释提供了这种支持,它直接等同于Spring bean XML文件中的<import/>元素。

http://docs.spring.io/spring-javaconfig/docs/1.0.0.M4/reference/html/ch04s03.html

答案 1 :(得分:9)

如果启用了组件扫描,则可以在不使用@Import的情况下在多个@Configuration类中拆分bean定义。您无需将所有这些都提供给应用程序上下文构造函数。我认为@Import的主要目的是为您提供一种简化多配置注册的方法,如果您希望避免组件扫描(根据参考手册,从Spring Framework 4.2开始)。

spring reference documentation about @Import usage:

中有一个注释
  

从Spring Framework 4.2开始,@ Import还支持对常规组件类的引用,类似于AnnotationConfigApplicationContext.register方法。如果要避免组件扫描,请使用一些配置类作为显式定义所有组件的入口点,这特别有用。

答案 2 :(得分:3)

@Import的典型用例是团队开发REST服务并意识到他们需要一些通用配置。

每个服务都将具有其自己的名称空间,即org.mybusiness.specific,并将其@SpringBootApplication(并因此是组件扫描根目录)从此程序包开始。

另一方面,公共库的命名空间将设置为org.mybusiness.common,因此组件扫描将无法使用。

因此需要使用@Import(CommonConfig.class)引用公共配置类

答案 3 :(得分:2)

我发现 a 使用了@Import注释。我认为这不是 the 用例。 如果您正在使用Spring开发一组库,则可能没有SpringBootApplication。因此,您尚未启用任何自动扫描来解析bean。

如果在library-a中通过依赖注入引用了在库library-b中的配置文件中声明的bean,则需要使用@Import告诉Spring如何解析该bean。

正如我们所说,在library-a中,您具有此配置文件。

@Configuration
public class ConfigurationA {
    @Bean
    public BeanA beanA() {
       return new BeanA();
    }
}

library-b中,如果要使用BeanA

,则必须具有此配置文件。
@Configuration
@Import(ConfigurationA.class)
public class ConfigurationB {
    @Bean
    public BeanB beanB(BeanA beanA) {
       return new BeanB(beanA);
    }
}

希望有帮助。

答案 4 :(得分:0)

启用组件扫描后,如果您对世界的看法仅限于您自己的应用程序及其程序包,则很难立即看到@Import在何处增加价值。可以帮助您的地方是,如果要导入具有自己的包结构且不想进行组件扫描的bean库。

您可以将此类库放置在类路径上,并使用@Import从它们中挑选@Configuration类。这就是为什么它通常被称为 composition 的原因,因为您是从多个来源组成@Configuration类的。

答案 5 :(得分:0)

@Import非常有用,因为某些原因您需要从软件包中注册并非全部,而是 some 个组件。在这种情况下,@ComponentScan太复杂了。

查看Spring boot component scan include a single class问题中的详细信息。