@Import可以导入bean或者@Configuration修饰的配置类。如果配置类在标准的springboot的包结构下,就是SpringbootApplication启动类在包的根目录下,配置类在子包下。就不需要使用@Import导入配置类,如果配置类在第三方的jar下,我们想要引入这个配置类,就需要@Import对其引入到工程中才能生效。因为这个时候配置类不再springboot默认的扫描范围内。
@Import 相当于Spring xml配置文件中的<import />
@Import的几种用法:
使用方法一:导入普通类
1.1 把普通的类用@Import导入之后成为一个bean。这个类并未使用@Service、@Component将其创建为bean。
@Getter
@Setter
public class MySqlConn {
private String driverClass = "xxxx";
private String url = "jdbc:mysql://localhost:3306/mydb";
private String userName = "root";
private String password = "root";
}
1.2 在springboot的启动类@Import这个类,这个类就可以被其他类当做bean来引用。
@SpringBootApplication
@Import({MySqlConn.class})
public class SpringBootApplication1 {
public static void main(String[] args) {
SpringApplication.run(SpringBootApplication1.class, args);
}
}
1.3 测试,定义一个controller来测试,调用这个通过@Import方式导入的bean
@RestController
@RequestMapping("test")
public class RestTestController {
@Autowired
private MySqlConn mySqlConn;
@GetMapping("common")
public String commonBean() {
String jsonResult = "";
ObjectMapper mapper = new ObjectMapper();
try {
jsonResult = mapper.writeValueAsString(mySqlConn);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return jsonResult;
}
}
使用方法二:和@Configuration搭配使用
@Import被用来整合@Configuration注解中定义的bean配置。
2.1 定义一个配置类@Configuration,配置类中定义了一些bean。下面的代码中可以看到我们定义的bean是MySqlServerBean。
@Configuration
public class MySqlConfig {
@Bean
public MySqlServerBean getBean() {
MySqlServerBean bean = new MySqlServerBean();
bean.setUserName("lyj");
return bean;
}
}
2.2 在启动类中@import这个配置类:
@SpringBootApplication
@Import(MySqlConfig.class)
public class SpringBootApplication3 {
public static void main(String[] args) {
SpringApplication.run(SpringBootApplication3.class, args);
}
}
2.3 测试,定义一个controller,我们看到在controller中就可以直接使用在MySqlConfig中定义MySqlServerBean了。
@RestController
@RequestMapping("test")
public class RestTestController {
@Autowired
private MySqlServerBean mySqlServerBean;
@GetMapping("mysql")
public String mysql() {
String jsonResult = "";
ObjectMapper mapper = new ObjectMapper();
try {
jsonResult = mapper.writeValueAsString(mySqlServerBean);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return jsonResult;
}
}
使用方法三:在配置类上导入
在配置类上通过@Import直接导入类,也可以被引用成bean。
3.1 定义一个普通的类
@Getter
@Setter
public class PoolBean {
private String redisHost = "127.0.0.1";
private String redisPort = "6379";
private String redisDb = "0";
}
3.2 在配置类上导入这个类
@Configuration
@Import({PoolBean.class})
public class RedisConfig {
@Bean
public RedisClusterBean getHost() {
return new RedisClusterBean();
}
}
3.3 测试,启动项目,在controller直接引用这个PoolBean。
@SpringBootApplication
public class SpringBootApplication2 {
public static void main(String[] args) {
SpringApplication.run(SpringBootApplication2.class, args);
}
}
@RestController
@RequestMapping("test")
public class RestTestController {
@Autowired
private PoolBean poolBean;
@GetMapping("pool")
public String poolBean() {
String jsonResult = "";
ObjectMapper mapper = new ObjectMapper();
try {
jsonResult = mapper.writeValueAsString(poolBean);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return jsonResult;
}
}
使用方法四:和ImportSelector搭配使用
新建一个Maven工程,pom.xml的类型是jar,我们写一个第三方的jar包,用来引用到我们的主工程中,进行ImportSelector的示例使用。工程结构大概如下图:
4.1 在third-part功能中,我们先定义一个config
@Configuration
public class AppConfig {
@Bean
public Student studentBean() {
Student student = new Student();
student.setId(10);
student.setName("王某");
return student;
}
}
4.2 自定义一个SpringStartSelector实现接口ImportSelector,BeanFactoryAware。重写selectImports()方法和setBeanFactory()方法。这里在程序启动的时候会先运行setBeanFactory()方法,我们可以在这里获取到beanFactory。selectImports()方法回了了AppCoinfig的全类名。
public class SpringStartSelector implements ImportSelector, BeanFactoryAware {
private BeanFactory beanFactory;
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
System.out.println("importingClassMetaData:" + importingClassMetadata);
System.out.println("beanFactory:" + beanFactory);
return new String[]{AppConfig.class.getName()};
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
}
4.3 自定义一个注解EnableSpringStudy,在这个注解使用@Import()导入4.2中自定义的SpringStartSelector
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target(ElementType.TYPE)
@Import(SpringStartSelector.class)
public @interface EnableSpringStudy {
}
4.4 完成之后我们把 third-part项目打成jar包,在主项目的pom文件中引入
<dependency>
<groupId>com.win.world</groupId>
<artifactId>third-part</artifactId>
<version>1.0.0</version>
</dependency>
4.5 主项目中在SpringBoot的启动类上使用我们4.3中自定义的注解。然后测试我们能否获取到AppConig中的bean。
@SpringBootApplication
@EnableSpringStudy
public class SpringBootApplication4 {
public static void main(String[] args) {
SpringApplication.run(SpringBootApplication4.class, args);
}
}
测试能否获取到AppConfig中的bean
@RestController
@RequestMapping("test")
public class RestTestController {
@Autowired
private Student student;
@GetMapping("selector")
public String selector() {
String jsonResult = "";
ObjectMapper mapper = new ObjectMapper();
try {
jsonResult = mapper.writeValueAsString(student);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return jsonResult;
}
}
使用方法五:和ImportBeanDefinitionRegistrar搭配使用
ImportBeanDefinitionRegistrar接口也是Spring的扩展点之一,它可以支持我们自己写的代码封装成BeanDefinition对象;实现此接口的类回调postProcessBeanDefinitionRegistry方法,注册到Spring容器中。把bean注入到Spring容器不止有@Service @Component
5.1 我们先定义一个MyImportBeanDefinitionRegistrar类实现ImportBeanDefinitionRegistrar接口,并通过重写registerBeanDefinitions()来定义一个bean
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar{
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
BeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClassName(PoolBean.class.getName());
MutablePropertyValues property = beanDefinition.getPropertyValues();
property.addPropertyValue("redisHost", "localhost");
property.addPropertyValue("redisPort", "6377");
//这里注册bean
registry.registerBeanDefinition("poolBean", beanDefinition);
}
}
5.2 定义一个配置类,@Import导入5.1的自定义类
@Configuration
@Import(MyImportBeanDefinitionRegistrar.class)
public class RegistrarConfig {
}
5.3 启动项目并测试自己在registerBeanDefinitions()方法中创建的bean PoolBean是否成功
@SpringBootApplication
public class SpringBootApplication5 {
public static void main(String[] args) {
SpringApplication.run(SpringBootApplication5.class, args);
}
}
@RestController
@RequestMapping("test")
public class RestTestController {
@Autowired
private PoolBean poolBean;
@GetMapping("registrar")
public String registrarTest() {
String jsonResult = "";
ObjectMapper mapper = new ObjectMapper();
try {
jsonResult = mapper.writeValueAsString(poolBean);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return jsonResult;
}
}
参考:
【1】一分钟学会Spring注解之@Import注解,https://blog.51cto.com/4247649/2118354