還只會用 @Service 註冊 Bean 嗎? | 七日打卡

前言

衆所周知,在咱們平時的開發中,Spring這個框架已經環繞了整個項目,不是說咱們不能不用Spring,而是這樣作的代價太大了。每次面試,老是會問道Spring IOC、AOP、事務等等,今天這篇的話是猛男我剛工做碰到的一個面試真題,可憐我那時只知道@Service。而後就回去等通知了,到如今尚未給我通知。面試

另外的話,今天這篇會講幾種注入方式,至於原理好哥哥們就先別想了(別打我臉就行),這隨便拿一個出來都的講源碼講一遍,主要須要依賴的東西優勢多,因此找個機會將Spring IOC 那一塊的源碼弄出來講說,這一篇的話主要是講個大概。
打臉spring

正題

1 @Service、@Component、@Repository、@Controller

這種方式就很簡單,像@Service、@Repository其實仍是用的@Component,在註解裏面點擊去看就知道了,須要注意的點是這種方式須要用@ComponentScan配置一個一個掃包範圍。爲何不用@Component這一個呢,主要是Spring爲了區分Bean的類型。@Repository做用於持久層,@Service 做用於業務邏輯層,@Controller做用於表現層(spring-mvc的註解)數組

@Componentpublic class ApproveCenterServiceImpl implements ApproveCenterService {
}@Servicepublic class ApproveCenterServiceImpl implements ApproveCenterService {
}@Repositorypublic class ApproveCenterServiceImpl implements ApproveCenterService {
}複製代碼

2 @Bean 和@Configuration

這種方式是否是很熟悉,經常使用於標註配置類,最簡單的一個例子就是咱們使用SpringBoot 的時候須要手動註冊一個Bean``叫作RestTemplate`spring-mvc

@Configurationpublic class RestTemplateConfig {@Beanpublic RestTemplate restTemplate() {return new RestTemplate();
    }
}複製代碼

3 使用@Import

@Import 註解能夠註冊三種類型的Bean,第一種就是普通類,第二種DefinitionRegistrar類,第三種就是ImportSelectormvc

3.1 普通類

/**
 * @author xiejianwei
 */@Import(MessageRecord.class)public @interface ImportBean {
}複製代碼

3.2 DefinitionRegistrar

實現了ImportBeanDefinitionRegistrar,這種方式在實現類中提供了一個註冊器,有一個很熟悉的註解@MapperScan好哥哥們點進去看看就明白了。app

@Import(MapperScannerRegistrar.class)public @interface MapperScan {
}public class MapperScannerRegistrar implements ImportBeanDefinitionRegistrar, ResourceLoaderAware {  /**
   * 主要是這個方法,在參數中提供了BeanDefinitionRegistry這個註冊器,能夠手動向容器中注入bean
   */
  @Override
  public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    AnnotationAttributes mapperScanAttrs = AnnotationAttributes
        .fromMap(importingClassMetadata.getAnnotationAttributes(MapperScan.class.getName()));if (mapperScanAttrs != null) {
      registerBeanDefinitions(mapperScanAttrs, registry);
    }
  }
}複製代碼

3.3 ImportSelector

不少想Springboot starter中要開啓某個功能時就會用到ImportSelector,好比像開啓服務註冊與發現的註解@EnableDiscoveryClient,主要原理是ImportSelector中的selectImports方法會返回一個字符串的數組,這裏的字符串其實是一個個咱們須要註冊類的全路徑,相似於com.xjw.entity.pojo.MessageRecord,Spring會根據全路徑反射生成Bean。源碼這一塊就先不講了(手動狗頭)。框架

public class CommonModelSelector implements ImportSelector {public CommonModelSelector() {
    }public String[] selectImports(AnnotationMetadata annotationMetadata) {return new String[]{MessageRecord.class.getName()};
    }
}複製代碼

4 FactoryBean

FactoryBean是一個特殊的Bean,是否不少好哥哥在面試時被問到過FactoryBean和BeanFactry的區別呢,說道這個個人眼眶溼潤了(講道理,這個在面所謂高級工程師的時候常常被問到)。FactoryBean是一個特殊Bean,當咱們實現這個接口時,會生成兩個Bean對象,第一個就是實現類自己,須要用在Bean名稱前(正常是類名首字母小寫)加&來獲取Bean,第二個Bean的話實際上就是getObject方法返回的bean,須要注意的是這種方式須要配合@Component或者@Configuration來實現。BeanFactry簡單點來講就是Spring上下文的容器。
溼了ide

實例代碼以下:rest

@Componentpublic class FactoryBeanLearn implements FactoryBean {@Overridepublic Object getObject() throws Exception {//這個Bean是咱們本身new的,這裏咱們就能夠控制Bean的建立過程了return new MessageRecord();
    }	/**
	 * bean的類型
	 *
	 **/@Overridepublic Class<?> getObjectType() {return MessageRecord.class;
    }	/**
	 * 是不是單例的
	 *
	 **/@Overridepublic boolean isSingleton() {return true;
    }
}複製代碼
相關文章
相關標籤/搜索