1. spring原生的xml 配置bean 现在几乎淘汰,忽略!!
2. @Component 及其衍生注解 (@Controller、@Service、@Repository)
@Component
public class Cat {
}
3. @Configuration + @Bean
@Configuration
public class AnimalConfig {
@Bean
public Dog dog() {
return new Dog();
}
}
4. 直接使用@Import
public class Bird {
}
4.1 实现 ImportSelector接口
package com.ldj.springboot.importbean.selector;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.util.CollectionUtils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.List;
/**
* User: ldj
* Date: 2024/8/24
* Time: 23:54
* Description: No Description
*/
public class MyBeanSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
List<String> springBeanPaths = SpringFactoriesLoader.getSpringBeanPaths("spring.factories");
if (CollectionUtils.isEmpty(springBeanPaths)) {
throw new RuntimeException("spring.factories文件 缺少配置!");
}
// 这个路径数组你也可以直接写,不需要专门读取配置文件,这里是为了演示springboot读取META-INF 里的spring.factories
return springBeanPaths.toArray(new String[0]);
}
}
// 读取要注入容器的类所在路径的配置文件
class SpringFactoriesLoader {
public static List<String> getSpringBeanPaths(String path) {
List<String> classPaths = new LinkedList<>();
InputStreamReader inputStreamReader = null;
BufferedReader bufferedReader = null;
InputStream inputStream = null;
String str;
try {
ClassPathResource classPathResource = new ClassPathResource(path);
inputStream = classPathResource.getInputStream();
inputStreamReader = new InputStreamReader(inputStream);
bufferedReader = new BufferedReader(inputStreamReader);
while ((str = bufferedReader.readLine()) != null) {
System.out.println(str);
classPaths.add(str);
}
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
try {
if (inputStream != null) {
inputStream.close();
}
if (bufferedReader != null) {
bufferedReader.close();
}
if (inputStreamReader != null) {
inputStreamReader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return classPaths;
}
}
4.2 实现 ImportBeanDefinitionRegistrar 接口
package com.ldj.springboot.importbean.registrar;
import com.ldj.springboot.importbean.config.OrderConfig;
import com.ldj.springboot.importbean.config.UserConfig;
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;
/**
* User: ldj
* Date: 2024/8/24
* Time: 22:22
* Description: No Description
*/
public class MyBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AbstractBeanDefinition userConfigBeanDefinition = BeanDefinitionBuilder.genericBeanDefinition(UserConfig.class).getBeanDefinition();
AbstractBeanDefinition orderConfigBeanDefinition = BeanDefinitionBuilder.genericBeanDefinition(OrderConfig.class).getBeanDefinition();
// 以定义态方式注册到容器
registry.registerBeanDefinition("userConfig", userConfigBeanDefinition);
registry.registerBeanDefinition("orderConfig", orderConfigBeanDefinition);
}
}
package com.ldj.springboot.importbean;
import com.ldj.springboot.importbean.config.*;
import com.ldj.springboot.importbean.registrar.MyBeanDefinitionRegistrar;
import com.ldj.springboot.importbean.selector.MyBeanSelector;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Import;
@SpringBootApplication
@Import(value = {Bird.class, MyBeanSelector.class, MyBeanDefinitionRegistrar.class,})
public class ImportBeanApplication {
public static void main(String[] args) {
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(ImportBeanApplication.class);
for (String beanDefinitionName : annotationConfigApplicationContext.getBeanDefinitionNames()) {
System.out.println("beanDefinitionName: " + beanDefinitionName);
}
System.out.println("==========================");
// @Component
System.out.println(annotationConfigApplicationContext.getBean(Cat.class));
// @Configuration + @Bean
System.out.println(annotationConfigApplicationContext.getBean(Dog.class));
// @Import
System.out.println(annotationConfigApplicationContext.getBean(Bird.class));
// @Import + ImportSelector
System.out.println(annotationConfigApplicationContext.getBean(UserConfig.class));
System.out.println(annotationConfigApplicationContext.getBean(OrderConfig.class));
// @Import + ImportBeanDefinitionRegistrar --> (beanDefinition)
System.out.println(annotationConfigApplicationContext.getBean(ProductConfig.class));
System.out.println(annotationConfigApplicationContext.getBean(StoreConfig.class));
// BeanFactoryPostProcessor --> (beanDefinition)
System.out.println(annotationConfigApplicationContext.getBean("carService"));
}
}