本文共 6038 字,大约阅读时间需要 20 分钟。
@Configuration注解用于将一个类定义为Spring Boot的IOC容器入口。类中的某个方法如果使用@Bean注解,则该方法返回的对象会被注册为IOC容器中的Bean。需要注意的是,@Configuration注解本身并不影响Bean的注册,它主要是标记作用,配合@Bean注解使用。
@Configurationpublic class MyConfig { @Bean("person2") public Person person() { return new Person(); }}public class MyTest { @Test public void test() { ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class); Object obj = context.getBean("person2"); System.out.println(obj.toString()); }}public class Person { private String name; private String age; public Person() {} public Person(String name, String age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age='" + age + '\'' + '}'; }}
@ComponentScan注解用于启用组件扫描功能,它可以自动发现包路径下所有标有@Component、@Service等注解的类。默认情况下,@ComponentScan会扫描当前类所在包及子包中的所有类。
@ComponentScan(value = "com.example.springbootapp")public class MyConfig {}public class MyTest { @Test public void test() { ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class); System.out.println(context.getBeanDefinitionCount()); String[] beanNames = context.getBeanDefinitionNames(); System.out.println(Arrays.toString(beanNames).replaceAll("[|]", "").replaceAll(",", "\n")); }}
@Scope注解用于定义Bean的作用域。Spring Boot默认的作用域包括:
@Configurationpublic class MyConfig { @Scope("singleton") @Bean("person2") public Person person() { return new Person(); }}public class MyTest { @Test public void test() { ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class); Object obj1 = context.getBean("person2"); Object obj2 = context.getBean("person2"); System.out.println(obj1 == obj2); // 加了@Scope("prototype")表示原型,会重新拷贝 }}
@Lazy注解用于延迟初始化Bean。与@Lazy配合使用时,Bean在IOC容器初始化时不会立即加载,只有在首次通过context.getBean()获取时,才会进行初始化。
@Configurationpublic class MyConfig { @Lazy @Bean public Person person() { System.out.println("将对象添加到IOC容器中"); return new Person(); }}public class MyTest { @Test public void test() { ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class); System.out.println("IOC容器创建完成"); context.getBean("person"); }}
@Conditional注解用于根据条件注册Bean。从Spring Boot 4开始引入,通过实现Condition接口,可以根据特定的条件判断来决定是否注册Bean。
@Configurationpublic class MyConfig { @Conditional(WinConditional.class) @Bean public Person jason() { System.out.println("将jason 添加到容器"); return new Person("jason", "18"); } @Conditional(LinuxConditional.class) @Bean public Person jerry() { System.out.println("jerry 添加到容器"); return new Person("jerry", "18"); } @Bean @Conditional(WinConditional.class) public Person tom() { System.out.println("tom 添加到容器"); return new Person("tom", "18"); }}public class LinuxConditional implements Condition { @Override public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) { ConfigurableListableBeanFactory beanFactory = conditionContext.getBeanFactory(); Environment environment = conditionContext.getEnvironment(); String osName = environment.getProperty("os.name"); System.out.println(osName); return osName.contains("Linux"); }}public class WinConditional implements Condition { @Override public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) { ConfigurableListableBeanFactory beanFactory = conditionContext.getBeanFactory(); Environment environment = conditionContext.getEnvironment(); String osName = environment.getProperty("os.name"); System.out.println("-----------------------------------------" + osName); return osName.contains("Win"); }}
@Import注解用于导入外部资源,支持导入XML文件、Properties文件、Excel文件等。可以通过指定value属性导入多个Bean。
@Configuration@Import(value = {Cat.class, MyImportSelector.class, MyImportDefinitionRegistrar.class})public class MyConfig { @Bean public Person person() { return new Person(); } @Bean public MyFactoryBean monkey() { return new MyFactoryBean(); }}public class MyFactoryBean implements FactoryBean { @Override public Monkey getObject() throws Exception { return new Monkey(); } @Override public Class getObjectType() { return Monkey.class; } @Override public boolean isSingleton() { return true; }}
通过@Import注解直接指定Bean:
@Import(value = {MyImportDefinitionRegistrar.class})public class MyConfig {}
通过实现ImportSelector接口:
public class MyImportSelector implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata annotationMetadata) { return new String[]{"com.example.springbootapp.entity.Company", "com.example.springbootapp.entity.Member"}; }}
通过自定义过滤器:
public class MyTypeFilter implements TypeFilter { @Override public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException { SetannotationTypes = metadataReader.getAnnotationTypes(); boolean flag = false; for (String str : annotationTypes) { if (str.contains(Controller.class.getName()) || str.contains(Service.class.getName())) { flag = true; break; } } return flag; }}
通过这些注解的合理组合,可以实现对Spring Boot应用的精细化配置和管理。
转载地址:http://upsn.baihongyu.com/