@Import注解详解

作用

@Import 注解提供了类似 @Bean 注解的功能,向Spring容器中注入bean。

源码

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
    Class<?>[] value();
}

可用在类、接口、枚举上。

三种用法

  1. @Import一个普通类 spring会将该类加载到spring容器中
  2. @Import实现了ImportBeanDefinitionRegistrar接口的类,手工往beanDefinitionMap中注册 beanDefinition
  3. @Import实现了ImportSelector接口的类,会导入selectImports返回包含了类全限定名的数组注入IOC容器。

与@bean区别

@Import 的beanName默认为全限定类名,@Bean注入的默认为方法名。

Import普通类

public class MyClass {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "MyClass{" +
                "name='" + name + '\'' +
                '}';
    }
}


//用import向容器中注入MyClass对象
@Component
@Import(MyClass.class)
public class MyConfig {
}

@SpringBootApplication
public class Application {

	public static void main(String[] args) {
		ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
		//向容器中获取MyClass bean
		MyClass myBean = context.getBean(MyClass.class);
		System.out.println(myBean);
	}
}

@Import注解详解_第1张图片

实现ImportBeanDefinitionRegistrar接口

@Component
@Import(Select.class)
public class MyConfig {
}

package com.example.springtest.Import;

import com.example.springtest.Inherited.ChildH;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;

public class Select implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(ChildH.class);
        AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();
        registry.registerBeanDefinition("ChildH", beanDefinition);
    }
}

package com.example.springtest.Inherited;

public class ChildH extends FatherClass_HasInherited{
    public ChildH() {
        System.out.println("ChildH实例化");
    }
}

MyConfig 导入了一个Select 类,Select 类实现了ImportBeanDefinitionRegistrar接口,并注册了一个ChildH的bean。
@Import注解详解_第2张图片

实现ImportSelector接口

package com.example.springtest.Import;

import org.springframework.context.annotation.Import;
import org.springframework.stereotype.Component;

@Component
@Import(Select.class)
public class MyConfig {
}
package com.example.springtest.Import;

import com.example.springtest.Inherited.ChildH;
import com.example.springtest.Inherited.ChildHI;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;

public class Select implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        return new String[]{ChildH.class.getName(), ChildHI.class.getName()};
    }
}
package com.example.springtest.Inherited;

public class ChildH extends FatherClass_HasInherited{
    public ChildH() {
        System.out.println("ChildH实例化");
    }
}
package com.example.springtest.Inherited;

public class ChildHI implements FatherInterface_HasInherited{

    public ChildHI() {
        System.out.println("ChildHI实例化");
    }
}

MyConfig 导入了一个Select 类,Select 类实现了ImportSelector 接口并返回了类名数组,所以会实例化ChildHI 和ChildH。

结果:
@Import注解详解_第3张图片

你可能感兴趣的:(java,spring,boot)