將 Bean 放入 Spring 容器中的五種方式
閱讀本文大概需要 5 分鐘。
來(lái)自:blog.csdn.net/weixin_43741092/article/details/120176466
1、@Configuration + @Bean
@Configurationpublic class MyConfiguration { @Bean public Person person() { Person person = new Person(); person.setName("spring"); return person; }}
2、@Componet + @ComponentScan
@Componentpublic class Person { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + '}'; }} @ComponentScan(basePackages = "com.springboot.initbean.*")public class Demo1 { public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Demo1.class); Person bean = applicationContext.getBean(Person.class); System.out.println(bean); }}
Person{name='null'}
3、@Import注解導(dǎo)入
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface Import { /** * 用于導(dǎo)入一個(gè)class文件 * {@link Configuration @Configuration}, {@link ImportSelector}, * {@link ImportBeanDefinitionRegistrar}, or regular component classes to import. */ Class<?>[] value(); }
3.1 @Import直接導(dǎo)入類
public class Person { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + '}'; }}/*** 直接使用@Import導(dǎo)入person類,然后嘗試從applicationContext中取,成功拿到**/@Import(Person.class)public class Demo1 { public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Demo1.class); Person bean = applicationContext.getBean(Person.class); System.out.println(bean); }}
注意:我們的Person類上 就不需要任何的注解了,直接導(dǎo)入即可。
3.2 @Import + ImportSelector
@Import(MyImportSelector.class)public class Demo1 { public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Demo1.class); Person bean = applicationContext.getBean(Person.class); System.out.println(bean); }} class MyImportSelector implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { return new String[]{"com.springboot.pojo.Person"}; }}
3.3 @Import + ImportBeanDefinitionRegistrar
@Import(MyImportBeanDefinitionRegistrar.class)public class Demo1 { public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Demo1.class); Person bean = applicationContext.getBean(Person.class); System.out.println(bean); }} class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { // 構(gòu)建一個(gè)beanDefinition, 關(guān)于beanDefinition我后續(xù)會(huì)介紹,可以簡(jiǎn)單理解為bean的定義. AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Person.class).getBeanDefinition(); // 將beanDefinition注冊(cè)到Ioc容器中. registry.registerBeanDefinition("person", beanDefinition); }}
3.4 @Import + DeferredImportSelector
@Import(MyDeferredImportSelector.class)public class Demo1 { public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Demo1.class); Person bean = applicationContext.getBean(Person.class); System.out.println(bean); }}class MyDeferredImportSelector implements DeferredImportSelector { @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { // 也是直接將Person的全限定名放進(jìn)去 return new String[]{Person.class.getName()}; }}
4、使用FactoryBean接口
@Configurationpublic class Demo1 { @Bean public PersonFactoryBean personFactoryBean() { return new PersonFactoryBean(); } public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Demo1.class); Person bean = applicationContext.getBean(Person.class); System.out.println(bean); }} class PersonFactoryBean implements FactoryBean<Person> { /** * 直接new出來(lái)Person進(jìn)行返回. */ @Override public Person getObject() throws Exception { return new Person(); } /** * 指定返回bean的類型. */ @Override public Class<?> getObjectType() { return Person.class; }}
5、使用 BeanDefinitionRegistryPostProcessor
public class Demo1 { public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(); MyBeanDefinitionRegistryPostProcessor beanDefinitionRegistryPostProcessor = new MyBeanDefinitionRegistryPostProcessor(); applicationContext.addBeanFactoryPostProcessor(beanDefinitionRegistryPostProcessor); applicationContext.refresh(); Person bean = applicationContext.getBean(Person.class); System.out.println(bean); }} class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor { @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Person.class).getBeanDefinition(); registry.registerBeanDefinition("person", beanDefinition); } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { }}
小結(jié)
-
@Configuration + @Bean -
@ComponentScan + @Component -
@Import 配合接口進(jìn)行導(dǎo)入 -
使用FactoryBean。 -
實(shí)現(xiàn)BeanDefinitionRegistryPostProcessor進(jìn)行后置處理。
推薦閱讀:
面試 Dubbo ,卻問(wèn)我和 SpringCloud 有什么區(qū)別?
互聯(lián)網(wǎng)初中高級(jí)大廠面試題(9個(gè)G) 內(nèi)容包含Java基礎(chǔ)、JavaWeb、MySQL性能優(yōu)化、JVM、鎖、百萬(wàn)并發(fā)、消息隊(duì)列、高性能緩存、反射、Spring全家桶原理、微服務(wù)、Zookeeper......等技術(shù)棧!
?戳閱讀原文領(lǐng)取! 朕已閱

