前言
前段事件分别学习了,系统初始化器、监听器。从现在开始进入到核心中的核心 -- Bean 相关内容。
本部分核心内容就是探究,Bean 是如何被加载到 Spring Ioc 容器中的。
本小节,是 Bean 解析的第一小节,我们先来学习一下,Bean 有哪几种注册方式。
配置 Bean 的 N 种姿势
最原始的当然是 Xml 配置的方式了,但是因为本系列核心在于 Spring Boot ,所以 Spring 时代 Xml 的配置方式就不过多介绍了。
注解 @Component
这是我们最常用的方式了。用在类上,将此类注入到 Spring Ioc 容器中。
这里的 @Component 指得是所有包含 @Component 的注解,例如 @Controller 、@Service等等。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
@AliasFor(annotation = Component.class)
String value() default "";
}
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {
@AliasFor(annotation = Component.class)
String value() default "";
}
我们可以看到,@Controller 、@Service 这类注解,都是包含了 @Component 的。
注解 @Bean
这也是我们比较常用的方式。用在方法上,将方法返回值作为 Bean 注册。
以上两种,都是比较常用的方式,不做演示了。
实现 FactoryBean
-
抽象接口 MyBean
public interface MyBean { String getName(); }
-
实现类 MyOneBean
public class MyOneBean implements MyBean{ @Override public String getName() { return "MyOneBean"; } }
-
MyFactoryBean
需要注意的是,这里也需要 @Component 加持。
@Component public class MyFactoryBean implements FactoryBean<MyBean> { @Override public MyBean getObject() throws Exception { return new MyOneBean(); } @Override public Class<?> getObjectType() { return MyBean.class; } }
-
测试
@Test public void one() { System.out.println(myBean.getName()); } // MyOneBean
实现 BeanDefinitionRegistryPostProcessor
-
MyTwoBean
public class MyTwoBean implements MyBean{ @Override public String getName() { return "MyTwoBean"; } }
-
MyBeanDefinitionRegistryPostProcessor
@Component public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor { @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException { RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(); rootBeanDefinition.setBeanClass(MyTwoBean.class); beanDefinitionRegistry.registerBeanDefinition("myTwoBean",rootBeanDefinition); } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException { } }
-
测试
@Testpublic void one() { System.out.println(myBean.getName());} // MyTwoBean
实现 ImportBeanDefinitionRegistrar
-
MyThreeBean
public class MyThreeBean implements MyBean{ @Override public String getName() { return "myThreeBean"; }}
-
MyImportBeanDefinitionRegistrar
注意这个没有 @Component 注解
public class MyImportBeanDefinitionRefistart implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(); rootBeanDefinition.setBeanClass(MyThreeBean.class); registry.registerBeanDefinition("myThreeBean",rootBeanDefinition); }}
-
启动类上加 @Import(MyImportBeanDefinitionRefistart.class)
-
测试
@Testpublic void one() { System.out.println(myBean.getName());}// myThreeBean
总结
本小节,了解了几种注册 Bean 的方式。
主要是为后面 Bean 加载内容做铺垫。