总括:
@Import
1,引入具有@configure注解的配置类---相当于xml的include
2,引入实现了importSelector,或importBeanDefintionRegister的子类返回的类实例,这种类的顺序前于配置类的顺序---用于初始化前置条件的类
一般在@Enable***注解使用,就是在这个功能的所有配置加载之前,先加载importEslector中的前置配置
例子1:
@Import(feignClientsRegister.class)
punlic @interface EnableFeignClients
feignClientsRegister 中的registerBeanDefinitions就初始化类
例子2:
public static class MyImportSelector implements ImportSelector {
/**
* AnnotationMetadata表示了使用@Import引入MyImportSelector的类的注解meta信息。
* 在这个例子中,annotationMetadata可以获取到Config类上的注解详细信息。
*/
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
/*System.out.println("class name --> " + annotationMetadata.getClass().getSimpleName());
System.out.println("className --> " + annotationMetadata.getClassName());
Set<String> annotationTypes = annotationMetadata.getAnnotationTypes();
System.out.println(annotationTypes);*/
// System.out.println("" + annotationMetadat);
System.out.println("----MyImportSelector-----");
return new String[] {"cn.xtt.study.spring.imports.Main.Config_1"};---------将被引入的实例
}
原文:https://blog.csdn.net/xt8469/article/details/82260091
@ImportResource
直接引入xml方式的配置文件
@PropertySource
属性文件
前言
为什么研究这两个注解,是因为在看Spring Boot源码的时候,对于其中大量的EnableXXX都使用了@Import注解,所以决定研究下这个注解,顺便写了一点关于@ImportRescource注解的东西,希望对大家有帮助。
@Import
简介:功能类似XML配置的,用来导入配置类,可以导入带有@Configuration注解的配置类或实现了ImportSelector/ImportBeanDefinitionRegistrar,或者导入普通的POJO(Spring会将其注册成Spring Bean,导入POJO需要使用Spring 4.2以上)。
下面注解源码,源码有比较详细的英文解释:
/**
* Indicates one or more {@link Configuration @Configuration} classes to import.
*
* <p>Provides functionality equivalent to the {@code <import/>} element in Spring XML.
* Allows for importing {@code @Configuration} classes, {@link ImportSelector} and
* {@link ImportBeanDefinitionRegistrar} implementations, as well as regular component
* classes (as of 4.2; analogous to {@link AnnotationConfigApplicationContext#register}).
*
* <p>{@code @Bean} definitions declared in imported {@code @Configuration} classes should be
* accessed by using {@link org.springframework.beans.factory.annotation.Autowired @Autowired}
* injection. Either the bean itself can be autowired, or the configuration class instance
* declaring the bean can be autowired. The latter approach allows for explicit, IDE-friendly
* navigation between {@code @Configuration} class methods.
*
* <p>May be declared at the class level or as a meta-annotation.
*
* <p>If XML or other non-{@code @Configuration} bean definition resources need to be
* imported, use the {@link ImportResource @ImportResource} annotation instead.
*
* @author Chris Beams
* @author Juergen Hoeller
* @since 3.0
* @see Configuration
* @see ImportSelector
* @see ImportResource
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
/**
* {@link Configuration}, {@link ImportSelector}, {@link ImportBeanDefinitionRegistrar}
* or regular component classes to import.
*/
Class<?>[] value();
}
关于Configuration和POJO,没什么好说的,就是简单的配置。这里说下ImportSelector和ImportBeanDefinitionRegistrar的作用(虽然开发过程中很少会使用到,但是Spring和Spring Boot的源码大面积使用了这个功能)。
ImportSelector
根据AnnotationMetadata(实质上是引入@Import注解的类的注解信息),来判断是否引入哪些配置类,通过字符串数组的方式返回配置类的全限定名。
DeferredImportSelector
ImportSelector的子接口,区别是,他会在所有的@Configuration类加载完成之后再加载返回的配置类。ImportSelector会在当前Configuration类加载之前去加载返回的配置类。
可以使用@Order注解或者Ordered接口来指定DeferredImportSelector的加载顺序。
并且提供了新的方法getImportGroup()用来跨DeferredImportSelector实现自定义Configuration的加载顺序。
ImportBeanDefinitionRegistrar
根据AnnotationMetadata(实质上是引入@Import注解的类的注解信息), 来注册BeanDenfinition,通过BeanDefinitionRegistry实例的register可以注册BeanDefinition。
三个接口的使用例子在文章最后面。
@ImportResource
和@Import类似,区别就是@ImportResource导入的是配置文件。
同样源码如下
/**
* Indicates one or more resources containing bean definitions to import.
*
* <p>Like {@link Import @Import}, this annotation provides functionality similar to
* the {@code <import/>} element in Spring XML. It is typically used when designing
* {@link Configuration @Configuration} classes to be bootstrapped by an
* {@link AnnotationConfigApplicationContext}, but where some XML functionality such
* as namespaces is still necessary.
*
* <p>By default, arguments to the {@link #value} attribute will be processed using a
* {@link org.springframework.beans.factory.groovy.GroovyBeanDefinitionReader GroovyBeanDefinitionReader}
* if ending in {@code ".groovy"}; otherwise, an
* {@link org.springframework.beans.factory.xml.XmlBeanDefinitionReader XmlBeanDefinitionReader}
* will be used to parse Spring {@code <beans/>} XML files. Optionally, the {@link #reader}
* attribute may be declared, allowing the user to choose a custom {@link BeanDefinitionReader}
* implementation.
*
* @author Chris Beams
* @author Juergen Hoeller
* @author Sam Brannen
* @since 3.0
* @see Configuration
* @see Import
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
public @interface ImportResource {
/**
* Alias for {@link #locations}.
* @see #locations
* @see #reader
*/
@AliasFor("locations")
String[] value() default {};
/**
* Resource locations from which to import.
* <p>Supports resource-loading prefixes such as {@code classpath:},
* {@code file:}, etc.
* <p>Consult the Javadoc for {@link #reader} for details on how resources
* will be processed.
* @since 4.2
* @see #value
* @see #reader
*/
@AliasFor("value")
String[] locations() default {};
/**
* {@link BeanDefinitionReader} implementation to use when processing
* resources specified via the {@link #value} attribute.
* <p>By default, the reader will be adapted to the resource path specified:
* {@code ".groovy"} files will be processed with a
* {@link org.springframework.beans.factory.groovy.GroovyBeanDefinitionReader GroovyBeanDefinitionReader};
* whereas, all other resources will be processed with an
* {@link org.springframework.beans.factory.xml.XmlBeanDefinitionReader XmlBeanDefinitionReader}.
* @see #value
*/
Class<? extends BeanDefinitionReader> reader() default BeanDefinitionReader.class;
}
default和locations作用相同,都是用来指定配置文件的位置。
关于reader,一般情况下们不需要指定这个属性,默认情况,如果配置文件是.groovy结尾的将会使用GroovyBeanDefinitionReader来进行解析,其他的将会使用XmlBeanDefinitionReader来进行解析。一般需要显示的指定reader的情况是开发者需要实现自己的配置文件方式,比如说自己实现了一个JSONBeanDefinitionReader用来解析JSON的配置文件以达到可以将Spring以JSON的方式进行配置(开发中使用较少)。
一般情下,Spring还是推荐使用@Import而不是@ImportResource。
附页-@Import的测试代码
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(Config.class, Config1.class);
context.refresh();
}
public static class BeanDemo0 {
private Integer id;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@Configuration
@Import({MyImportSelector.class, MyImportBeanDefinitionRegistrar.class, MyImportSelector1.class})
public static class Config {
@Bean
public BeanDemo0 beanDemo() {
System.out.println("----beanDemo----");
BeanDemo0 beanDemo0 = new BeanDemo0();
beanDemo0.setId(1);
beanDemo0.setName("123");
return beanDemo0;
}
}
@Configuration
public static class Config_1 {
@Bean
public BeanDemo0 beanDemo_1() {
System.out.println("----beanDemo_1----");
BeanDemo0 beanDemo0 = new BeanDemo0();
beanDemo0.setId(1);
beanDemo0.setName("123");
return beanDemo0;
}
}
@Configuration
public static class Config0 {
@Bean
public BeanDemo0 beanDemo0() {
System.out.println("----beanDemo0----");
BeanDemo0 beanDemo0 = new BeanDemo0();
beanDemo0.setId(1);
beanDemo0.setName("123");
return beanDemo0;
}
}
@Configuration
public static class Config00 {
@Bean
public BeanDemo0 beanDemo00() {
System.out.println("----beanDemo00----");
BeanDemo0 beanDemo0 = new BeanDemo0();
beanDemo0.setId(1);
beanDemo0.setName("123");
return beanDemo0;
}
}
@Configuration
public static class Config000 {
@Bean
public BeanDemo0 beanDemo000() {
System.out.println("----beanDemo000----");
BeanDemo0 beanDemo0 = new BeanDemo0();
beanDemo0.setId(1);
beanDemo0.setName("123");
return beanDemo0;
}
}
@Configuration
public static class Config0000 {
@Bean
public BeanDemo0 beanDemo0000() {
System.out.println("----beanDemo0000----");
BeanDemo0 beanDemo0 = new BeanDemo0();
beanDemo0.setId(1);
beanDemo0.setName("123");
return beanDemo0;
}
}
@Configuration
@Import({MyImportSelector2.class})
public static class Config1 {
@Bean
public BeanDemo0 beanDemo1() {
System.out.println("----beanDemo1----");
BeanDemo0 beanDemo0 = new BeanDemo0();
beanDemo0.setId(1);
beanDemo0.setName("123");
return beanDemo0;
}
}
@Configuration
public static class Config2 {
@Bean
public BeanDemo0 beanDemo2() {
System.out.println("----beanDemo2----");
BeanDemo0 beanDemo0 = new BeanDemo0();
beanDemo0.setId(1);
beanDemo0.setName("123");
return beanDemo0;
}
}
public static class MyImportSelector implements ImportSelector {
/**
* AnnotationMetadata表示了使用@Import引入MyImportSelector的类的注解meta信息。
* 在这个例子中,annotationMetadata可以获取到Config类上的注解详细信息。
*/
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
/*System.out.println("class name --> " + annotationMetadata.getClass().getSimpleName());
System.out.println("className --> " + annotationMetadata.getClassName());
Set<String> annotationTypes = annotationMetadata.getAnnotationTypes();
System.out.println(annotationTypes);*/
// System.out.println("" + annotationMetadat);
System.out.println("----MyImportSelector-----");
return new String[] {"cn.xtt.study.spring.imports.Main.Config_1"};
}
}
/**
* after all config
*/
public static class MyImportSelector1 implements DeferredImportSelector {
@Override
public Class<? extends Group> getImportGroup() {
return MyGroup.class;
}
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
System.out.println("----DeferredImportSelector1-----");
return new String[]{"cn.xtt.study.spring.imports.Main.Config0", "cn.xtt.study.spring.imports.Main.Config00"};
}
}
public static class MyImportSelector2 implements DeferredImportSelector {
@Override
public Class<? extends Group> getImportGroup() {
return MyGroup.class;
}
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
System.out.println("----DeferredImportSelector2-----");
return new String[]{"cn.xtt.study.spring.imports.Main.Config000", "cn.xtt.study.spring.imports.Main.Config0000"};
}
}
public static class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry registry) {
System.out.println("----MyImportBeanDefinitionRegistrar----");
/*System.out.println(annotationMetadata);
System.out.println("class name --> " + annotationMetadata.getClass().getSimpleName());
System.out.println("className --> " + annotationMetadata.getClassName());
System.out.println(registry);
System.out.println("registry name " + registry.getClass().getSimpleName());*/
registry.registerBeanDefinition("config2", new RootBeanDefinition(Config2.class));
}
}
private static class MyGroup implements DeferredImportSelector.Group {
private List<Entry> entries = new ArrayList<>(2);
@Override
public void process(AnnotationMetadata metadata, DeferredImportSelector selector) {
for (String configClassName : selector.selectImports(metadata)) {
entries.add(new Entry(metadata, configClassName));
}
entries.sort(new Comparator<Entry>() {
@Override
public int compare(Entry o1, Entry o2) {
//按照配置类,全限定名的长度,从名称长的开始加载
return o2.getImportClassName().length() - o1.getImportClassName().length();
// return o1.getImportClassName().length() - o2.getImportClassName().length();
}
});
}
@Override
public Iterable<Entry> selectImports() {
return entries;
}
}
}
运行结果:
----MyImportSelector-----
----DeferredImportSelector1-----
----DeferredImportSelector2-----
----MyImportBeanDefinitionReistrar----
----beanDemo_1----
----beanDemo----
----beanDemo1----
----beanDemo0000----
----beanDemo000----
----beanDemo00----
----beanDemo0----
----beanDemo2----
原文:https://blog.csdn.net/xt8469/article/details/82260091
相关推荐
它负责解析`@Configuration`、`@ComponentScan`、`@ImportResource`等注解,构建BeanDefinition,并将它们添加到BeanDefinitionRegistry中。 5. **内部类与元数据** `@Import`还可以用于导入内部类,这在处理复杂...
在Spring框架中,加载多个配置文件是常见的需求,特别是在大型项目中,为了保持代码的整洁和模块化,通常...通过理解并熟练运用这些加载机制,开发者可以更好地组织和管理项目中的配置,提高代码的可维护性和可扩展性。
- **用途**:与`@Import`类似,但`@ImportResource`用于导入XML配置文件到Spring容器中。这种方式使得在纯注解配置之外,仍然可以利用XML文件进行配置。 ##### 6、@Component - **用途**:`@Component`是一个通用的...
7. `@Import`和`@ImportResource`:`@Import`可以用来导入其他配置类,而`@ImportResource`则可以导入XML配置文件,这样你可以在注解配置和XML配置之间自由切换。 8. 配合JSR 330标准的注解,如`@Inject`和`@Named`...
15. `@Import`和`@ImportResource`:`@Import`用于导入其他配置类,`@ImportResource`用于导入XML配置文件。 通过理解并熟练运用这些注解,Spring开发者可以更加高效地构建应用程序,减少XML配置,提升代码可读性...
加载jar包中的Spring配置文件需要对Spring的类路径加载机制有深入理解。通过`ClassPathResource`,我们可以定位并加载jar包内的配置,然后应用到`ApplicationContext`。在SSM整合的项目中,正确地加载这些配置文件...
5. **@ImportResource**:与@Import类似,但导入的是XML配置文件,将XML配置中的bean定义加入到Spring容器。 6. **@Component**:这是Spring的一个元注解,可以标记其他类注解,如@Controller、@Service和@...
如果你使用了`quartz_test`目录下的测试资源,那么这个目录可能包含了用于测试的配置文件或代码示例,可以帮助你更好地理解和验证Quartz在Spring中的配置和运行情况。 总之,Spring与Quartz的集成提供了强大的定时...
- **装配注解**:@ImportResource用于导入XML配置,@Import可以导入Configuration类,@ComponentScan扫描指定包下的注解类。 - **依赖注入注解**:@Autowired自动装配bean,@Qualifier提供更精确的依赖选择。 3. ...
10. **@ImportResource**:用于加载XML配置文件,尽管Spring Boot提倡无XML配置,但在需要的情况下,仍可通过此注解引入XML配置。 11. **@Autowired**:自动装配bean,按照类型匹配并注入,可以用于字段、方法或...
- **文档**:清晰记录使用了哪些XML配置,以及它们在项目中的作用,便于其他开发者理解和维护。 总的来说,虽然Spring Boot推崇的是Java和YAML配置,但通过上述方法,我们仍然可以灵活地在项目中读取和使用XML配置...
首先,我们要理解SpringBoot和Dubbo的基本概念。SpringBoot简化了Spring应用的初始搭建以及开发过程,它提供了自动配置、起步依赖、内嵌Web服务器等特性,使得开发更加高效。而Dubbo是阿里巴巴开源的一款高性能、轻...
理解`@ImportResource`注解,它实际上是在Spring的`spring-context`模块中定义的,用于在Spring容器启动时加载XML配置文件。`ImportResource`内部实现了`BeanDefinitionReader`接口,该接口负责读取XML文件并将其...
若要使多模块项目中的其他模块能够识别并加载`common-config`模块的配置,可以使用`@ImportResource`注解或者`@Import`导入配置类。 - **配置类**:如果配置较多,可以创建一个配置类,通过`@...
### Spring框架概述与特点 #### 1. 什么是Spring框架? Spring框架是一个开源的企业级Java应用框架,也是目前最流行的Java EE开发框架之一。...希望这些内容能帮助您更好地理解和掌握Spring框架的相关知识。
文档还提到了一系列用于Code Config的属性,如`Configuration`、`Definition`、`DependsOn`、`Import`、`ImportResource`、`Lazy`和`Scope`属性,它们分别用于标记配置类、定义bean、指定依赖关系、导入其他配置、...
ApplicationContext支持通过`@ImportResource`注解或XML配置中的`<import>`标签将多个配置文件合并。此外,该视频可能还会讲解如何实现国际化,即I18N,Spring提供了MessageSource接口,可以加载不同语言的资源文件...