SpringBoot 的 @Import 用于将指定的类实例注入之Spring IOC Container中。
SpringBoot 提供了 三种使用 @Import 将 类实例注入至 Spring IOC Container中 的实例。
一、 直接注入
Broker.java(无任何属性和实现)
package com.springBoot.entrance.importBean.direct;
public class Broker {
}
Customer.java(无任何属性和实现)
package com.springBoot.entrance.importBean.direct;
public class Customer {
}
ImportDirect.java
package com.springBoot.entrance.importBean.direct;
import org.springframework.context.annotation.Import;
import org.springframework.stereotype.Component;
@Component
@Import({Customer.class,Broker.class})
/**
*使用Import 将指定的类的实例注入至Spring 容器中
*/
public class ImportDirect {
}
代码解读:使用 @Import({Customer.class,Broker.class}) 后 Customer 和 Broker类的实例将会被注入之Spring IOC Container中
App.java
//import Direct 使用import 直接将指定的类实例注入至Spring 容器中
System.out.println(context.getBean(ImportDirect.class));
System.out.println(context.getBean(Customer.class));
System.out.println(context.getBean(Broker.class));
结果
二、实现 ImportBeanDefinitionRegistrar 接口 注入
Forwards.java(无任何属性和实现)
package com.springBoot.entrance.importBean.indirectImportBeanDefinitionRegistrar;
public class Forwards {
}
Security.java(无任何属性和实现)
package com.springBoot.entrance.importBean.indirectImportBeanDefinitionRegistrar;
public class Security {
}
MyImportBeanDefinitionRegistrar.java
package com.springBoot.entrance.importBean.indirectImportBeanDefinitionRegistrar;
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;
/**
* registerBeanDefinitions 方法中的参数 BeanDefinitionRegistry 可以往Spring IOC Container 中动态地装配Bean
*/
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//手动注入 Forwards 类的实例
BeanDefinitionBuilder beanDef_forwards = BeanDefinitionBuilder.rootBeanDefinition(Forwards.class);
registry.registerBeanDefinition("forwards", beanDef_forwards.getBeanDefinition());
//手动注入 Security类的实例
BeanDefinitionBuilder beanDef_security = BeanDefinitionBuilder.rootBeanDefinition(Security.class);
registry.registerBeanDefinition("security", beanDef_security.getBeanDefinition());
}
}
App.java
@Import(MyImportBeanDefinitionRegistrar.class)
@Configuration
public class App {
public static void main(String[] args) throws Exception {
ConfigurableApplicationContext context = SpringApplication.run(App.class, args);
//实现ImportBeanDefinitionRegistrar 实现Bean的注入
System.out.println(context.getBean(MyImportBeanDefinitionRegistrar.class));
System.out.println(context.getBean(Forwards.class));
System.out.println(context.getBean(Security.class));
}
}
三、 实现 ImportSelector 注入
Market.java(无任何属性或实现)
package com.springBoot.entrance.importBean.indirectImportSelector;
public class Market {
}
Sales.java(无任何属性或实现)
package com.springBoot.entrance.importBean.indirectImportSelector;
public class Sales {
}
EnableLogInfo.java
package com.springBoot.entrance.importBean.indirectImportSelector;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Import;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(MyImportSelector.class)
/**
*自定义Enable*
*1.
*/
public @interface EnableLogInfo {
String[] name();
}
MyImportSelector.java
package com.springBoot.entrance.importBean.indirectImportSelector;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.stereotype.Component;
@Component
@Import(value = { MyImportSelector.class })
@EnableLogInfo(name="onlySale")
/**
* Bean的批量注入 使用自定义 ImportSelector 须实现 ImportSelector
* 接口,返回值必须是class全称测集合,该集合内的所有类都将被Spring IOC容器统一管理
*/
public class MyImportSelector implements ImportSelector {
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
System.out.println(importingClassMetadata.getAnnotationAttributes(EnableLogInfo.class.getName()).toString().contains("onlySale"));
//获取自定的@EnableLogInfo 信息 如果包含 onlySale 则只注入Sales class 否则 注入 Sales 和 Market 两个类
if (importingClassMetadata.getAnnotationAttributes(EnableLogInfo.class.getName()) != null
&& importingClassMetadata.getAnnotationAttributes(EnableLogInfo.class.getName()).toString().contains("onlySale")) {
return new String[] {Sales.class.getName() };
}
// 将指定的类
return new String[] { Market.class.getName(), Sales.class.getName() };
}
}
代码解读:此处使用了@Import注解和实现了 ImportSelector 来注入Bean
代码逻辑:通过 实现 ImportSelector 获得 importingClassMetadata 对象,然后再由 importingClassMetadata 获得 我们自定的@EnableLogInfo 中的 值,如果 该值包含 onlySale 则 我们只装配Sale 类实例,否则 装配 Sale 和Market 两个类的实例。