@Import
@Import 注解支持导入普通 java 类,并将其声明成一个bean。主要用于将多个分散的 java config 配置类融合成一个更大的 config 类。
- @Import 注解在 4.2 之前只支持导入配置类。
- 在4.2之后 @Import 注解支持导入普通的 java 类,并将其声明成一个 bean。
@Import 三种使用方式
- 直接导入普通的 Java 类。
- 配合自定义的 ImportSelector 使用。
- 配合 ImportBeanDefinitionRegistrar 使用。
假如我们已经建好了一个简单springboot项目
Configuration方式
- 创建一个普通的 Circle类
public class Circle {
public void sayHi() {
System.out.println("Circle");
}
}
- 创建一个配置类,里面没有显式声明任何的 Bean,然后将刚才创建的 Circle 导入
@Import({Circle.class})
@Configuration
public class MainConfig {
}
- 创建controller
@RestController
public class testController {
@Autowired
private Circle circle;
@RequestMapping("/index")
public String hello() {
circle.sayHi();
return "我真帅";
}
}
- 访问http://127.0.0.1:8080/index
控制打印出
Circle
annotation方式
- 创建TUserRole
public class TUserRole {
public void sayHi(){
System.out.println("----------TUserRole---------");
}
}
- 创建EnableTUserTRole
要让该配置类生效,我们可以定义一个@Enable注解来驱动它。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({TUserRole.class})
public @interface EnableTUserTRole {
}
- 将注解加到main
@EnableTUserTRole
@SpringBootApplication
public class KaleldoApplication {
public static void main(String[] args) {
SpringApplication.run(KaleldoApplication.class, args);
}
}
- 添加到控制器
@RestController
public class testController {
@Autowired
private TUserRole tUserRole;
@Autowired
private Circle circle;
@RequestMapping("/index")
public String hello() {
tUserRole.sayHi();
circle.sayHi();
return "我真帅";
}
}
- 访问http://127.0.0.1:8080/index
打印出
----------TUserRole---------
Circle
ImportSelector
如果定义太多注解,那么在main方法上要添加太多注解…因此使用ImportSelector
ImportSelector 是一个接口,该接口中只有一个 selectImports 方法,用于返回全类名数组。所以利用该特性我们可以给容器动态导入 N 个 Bean。
因为这两个bean都是通过@Enable类型注解来将配置类注册到IOC容器中,所以我们现在要做的就是将这两个bean一次性都注册到IOC容器中。在Spring中,要将多个类进行注册,可以使用selector的方式。
- 创建TRole,TUser
public class TUser {
public void sayHi(){
System.out.println("-------------TUser-------------");
}
}
public class TRole {
public void sayHi() {
System.out.println("------------TRole------------");
}
}
- 创建ApplicationSelector
public class ApplicationSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
return new String[]{
TRole.class.getName(),
TUser.class.getName()
};
}
}
- 创建EnableApplicationSelector
通过selectImports方法,我们一次性导入了TRole、TUser这两个类。
要让上面的代码生效,我们还需将ApplicationSelector 注册到IOC容器中。同之前的做法,我们可以通过注解的方式来实现。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({ApplicationSelector.class})
public @interface EnableApplicationSelector {
}
- 试验
添加到main
@EnableApplicationSelector
@EnableTUserTRole
@SpringBootApplication
public class KaleldoApplication {
public static void main(String[] args) {
SpringApplication.run(KaleldoApplication.class, args);
}
}
Controller
@RestController
public class testController {
@Autowired
private TUserRole tUserRole;
@Autowired
private TUser tUser;
@Autowired
private TRole tRole;
@Autowired
private Circle circle;
@RequestMapping("/index")
public String hello() {
tUserRole.sayHi();
tUser.sayHi();
tRole.sayHi();
circle.sayHi();
return "我真帅";
}
}
访问http://127.0.0.1:8080/index
打印
----------TUserRole---------
-------------TUser-------------
------------TRole------------
Circle
ImportBeanDefinitionRegistrar
ImportBeanDefinitionRegistrar 是一个接口,它可以手动注册bean到容器中,从而可以对类进行个性化的定制。
- 创建TMenu
public class TMenu {
public void sayHi(){
System.out.println("-----------Kaleldo太帅了---------");
}
}
- 创建EImportBeanDefinitionRegistrar
public class EImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(TMenu.class);
// 注册一个名字叫做 kaleldo 的 bean
beanDefinitionRegistry.registerBeanDefinition("kaleldo", rootBeanDefinition);
}
}
- 注入ioc
@Import({Circle.class, EImportBeanDefinitionRegistrar.class})
@Configuration
public class MainConfig {
}
- 试验
@RestController
public class testController {
@Autowired
private TUserRole tUserRole;
@Autowired
private TUser tUser;
@Autowired
private TRole tRole;
@Autowired
private Circle circle;
@Resource(name = "kaleldo")
private TMenu tMenu;
@RequestMapping("/index")
public String hello() {
tUserRole.sayHi();
tUser.sayHi();
tRole.sayHi();
circle.sayHi();
tMenu.sayHi();
return "我真帅";
}
}
访问http://127.0.0.1:8080/index
----------TUserRole---------
-------------TUser-------------
------------TRole------------
Circle
-----------Kaleldo太帅了---------
欧耶