作用
@Import 注解提供了类似 @Bean 注解的功能,向Spring容器中注入bean。
源码
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
Class<?>[] value();
}
可用在类、接口、枚举上。
三种用法
- @Import一个普通类 spring会将该类加载到spring容器中
- @Import实现了ImportBeanDefinitionRegistrar接口的类,手工往beanDefinitionMap中注册 beanDefinition
- @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);
}
}
实现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。
实现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。
结果: