Java @Import 注释的用例是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35502164/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 16:44:35  来源:igfitidea点击:

What is the use case of @Import annotation?

javaspringspring-mvc

提问by enzo

According to official doc:

根据官方文档

Annotation Type Configuration

Indicates that a class declares one or more @Bean methods and may be processed by the Spring container to generate bean definitions...

@Configuration classes may be composed using the @Import annotation, not unlike the way that works in Spring XML. Because @Configuration objects are managed as Spring beans within the container..

注解类型配置

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

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

But i can also use @Configuration annotation without @Import. I have tested the code listed below and it works as expected. So what is the purpose to use @Import?

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

DispatcherServletInitializer

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

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

服务

@Service
public class MyServiceImpl implements MyService {

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

    // ...
}

采纳答案by Marcel

Thus far, we've seen how to break up bean definitions into multiple @Configurationclasses and how to reference those beans across @Configurationboundaries. These scenarios have required providing all @Configurationclasses to the constructor of a JavaConfigApplicationContext, and this is not always ideal. Often it is preferable to use an aggregation approach, where one @Configurationclass logically imports the bean definitions defined by another.

The @Importannotation provides just this kind of support, and it is the direct equivalent of the <import/>element found in Spring beans XML files.

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

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

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

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

回答by yixiang

If component scanningis enabled, you can split bean definitions in multi @Configurationclasses without using @Import.

如果启用了组件扫描,您可以在多个@Configuration类中拆分 bean 定义,而无需使用@Import.

You don't need to provide all of them to the application context constructor. I think the main purpose for @Importis to provide you a way to simplify multi configuration registration if you'd like to avoid component scanning (as of Spring Framework 4.2, per reference manual).

您不需要将所有这些都提供给应用程序上下文构造函数。我认为主要目的@Import为您提供一种方法来简化多配置注册,如果您想避免组件扫描(从 Spring Framework 4.2 开始,根据参考手册)。

There's a note in Spring Reference Documentation about @Importusage:

Spring 参考文档中有一个关于用法的注释@Import

As of Spring Framework 4.2, @Importalso supports references to regular component classes, analogous to the AnnotationConfigApplicationContext.registermethod. This is particularly useful if you'd like to avoid component scanning, using a few configuration classes as entry points for explicitly defining all your components.

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

回答by Andy Brown

With component scanning enabled it's difficult to immediately see where @Importadds value if your view of the world is limited to your own application and its packages. Where it can help is if you are importing bean libraries with their own package structure that you don't want to component scan.

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

You can place such libraries on your classpath and use @Importto cherry-pick @Configurationclasses from within them. That's why it's often referred to as compositionbecause you are composing your @Configurationclass from multiple sources.

您可以将此类库放在类路径中,并用于从其中@Import挑选@Configuration类。这就是为什么它通常被称为组合,因为您正在@Configuration从多个来源组合您的类。

回答by riccardo.cardin

I found ause of using the @Importannotation. I don't think it's theuse case. If you are developing a set of libraries using Spring, probably you don't have a SpringBootApplication. So, you have not enabled any auto-scanto resolve beans.

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

If a bean declared in a configuration file in the library library-ais referred through dependency injection in library-byou need to use @Importto tell Spring how to resolve the bean.

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

As we said, in library-ayou have this configuration file.

正如我们所说,library-a你有这个配置文件。

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

In library-byou must have this configuration file if you want to use BeanA

library-b如果你想使用你必须有这个配置文件BeanA

@Configuration
@Import(ConfigurationA.class)
public class ConfigurationB {
    @Bean
    public BeanB beanB(BeanA beanA) {
       return new BeanB(beanA);
    }
}

Hope it helps.

希望能帮助到你。

回答by PA Lemire

A typical use case of @Importis when teams develop REST services and realize they need some common configuration.

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

Every service will have its own namespace i.e. org.mybusiness.specificand will have its @SpringBootApplication(and therefore component scan root) start at this package.

每个服务都有它自己的命名空间,即org.mybusiness.specific,它的@SpringBootApplication(因此组件扫描根)从这个包开始。

On the other hand, the common library will have its namspace set to org.mybusiness.commonand will therefore be out of reach for component scanning.

另一方面,公共库将其 namspace 设置为org.mybusiness.common,因此无法进行组件扫描。

Thus the need to reference the common configuration class using @Import(CommonConfig.class)

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