spring boot 註解@Component
@Component。
Spring提供進一步典型的註解:@Component,@Service,和 @Controller。@Component是任何Spring託管元件的通用註解。 而@Repository,@Service和@Controller是@Component針對更特定用例的專業化(分別在永續性,服務和表示層)。因此可以用他們來註解你的元件類與@Component具有同樣作用,通過與註解它們@Repository,@Service或者@Controller ,你能更好的區分資料,業務,控制層
這些註解也是aspect的理想切入點,例如,這些構造型註釋成為切入點的理想目標。@Repository,@Service和,並且@Controller在Spring框架的將來版本中還可以包含其他語義。因此,如果您選擇使用@Component或@Service對於您的服務層,@Service顯然是更好的選擇。同樣,如前所述,@Repository在持久層中已經支援將其作為自動異常轉換的標記。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component {
String value() default "";
}
SpringApplication, 掉用this.refreshContext(context)時候會將掉用bean 定義,根據這些RootBeanDefinition將bean例項注入到IOC中
SpringApplication:
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
this.configureHeadlessProperty();
SpringApplicationRunListeners listeners = this.getRunListeners(args);
listeners.starting();
Collection exceptionReporters;
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
this.configureIgnoreBeanInfo(environment);
Banner printedBanner = this.printBanner(environment);
context = this.createApplicationContext();
exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
this.refreshContext(context);
this.afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
}
listeners.started(context);
this.callRunners(context, applicationArguments);
} catch (Throwable var10) {
this.handleRunFailure(context, var10, exceptionReporters, listeners);
throw new IllegalStateException(var10);
}
try {
listeners.running(context);
return context;
} catch (Throwable var9) {
this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
throw new IllegalStateException(var9);
}
}
SpringApplication掉用ClassPathBeanDefinitionScanner通過basePackage掃描bean,生成bean 定義。
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet();
String[] var3 = basePackages;
int var4 = basePackages.length;
for(int var5 = 0; var5 < var4; ++var5) {
String basePackage = var3[var5];
Set<BeanDefinition> candidates = this.findCandidateComponents(basePackage);
Iterator var8 = candidates.iterator();
while(var8.hasNext()) {
BeanDefinition candidate = (BeanDefinition)var8.next();
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
candidate.setScope(scopeMetadata.getScopeName());
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
if (candidate instanceof AbstractBeanDefinition) {
this.postProcessBeanDefinition((AbstractBeanDefinition)candidate, beanName);
}
if (candidate instanceof AnnotatedBeanDefinition) {
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition)candidate);
}
if (this.checkCandidate(beanName, candidate)) {
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
this.registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}
private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
LinkedHashSet candidates = new LinkedHashSet();
try {
String packageSearchPath = "classpath*:" + this.resolveBasePackage(basePackage) + '/' + this.resourcePattern;
Resource[] resources = this.getResourcePatternResolver().getResources(packageSearchPath);
boolean traceEnabled = this.logger.isTraceEnabled();
boolean debugEnabled = this.logger.isDebugEnabled();
Resource[] var7 = resources;
int var8 = resources.length;
for(int var9 = 0; var9 < var8; ++var9) {
Resource resource = var7[var9];
if (traceEnabled) {
this.logger.trace("Scanning " + resource);
}
if (resource.isReadable()) {
try {
MetadataReader metadataReader = this.getMetadataReaderFactory().getMetadataReader(resource);
if (this.isCandidateComponent(metadataReader)) {
ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
sbd.setSource(resource);
if (this.isCandidateComponent((AnnotatedBeanDefinition)sbd)) {
if (debugEnabled) {
this.logger.debug("Identified candidate component class: " + resource);
}
candidates.add(sbd);
} else if (debugEnabled) {
this.logger.debug("Ignored because not a concrete top-level class: " + resource);
}
} else if (traceEnabled) {
this.logger.trace("Ignored because not matching any filter: " + resource);
}
} catch (Throwable var13) {
throw new BeanDefinitionStoreException("Failed to read candidate component class: " + resource, var13);
}
} else if (traceEnabled) {
this.logger.trace("Ignored because not readable: " + resource);
}
}
return candidates;
} catch (IOException var14) {
throw new BeanDefinitionStoreException("I/O failure during classpath scanning", var14);
}
}
ClassPathBeanDefinitionScanner將掃描到的bean通過ClassPathScanningCandidateComponentProvider.includeFilters進行篩選,找到帶@Compnent的bean
ClassPathScanningCandidateComponentProvider:
protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
Iterator var2 = this.excludeFilters.iterator();
TypeFilter tf;
do {
if (!var2.hasNext()) {
var2 = this.includeFilters.iterator();
do {
if (!var2.hasNext()) {
return false;
}
tf = (TypeFilter)var2.next();
} while(!tf.match(metadataReader, this.getMetadataReaderFactory()));
return this.isConditionMatch(metadataReader);
}
tf = (TypeFilter)var2.next();
} while(!tf.match(metadataReader, this.getMetadataReaderFactory()));
return false;
}
AnnotationTypeFilter 是ClassPathBeanDefinitionScanner的一個filter,用來篩選@Compnent bean.
protected boolean matchSelf(MetadataReader metadataReader) {
AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
return metadata.hasAnnotation(this.annotationType.getName()) || this.considerMetaAnnotations && metadata.hasMetaAnnotation(this.annotationType.getName());
}
AnnotationMetadata:
public interface AnnotationMetadata extends ClassMetadata, AnnotatedTypeMetadata {
default Set<String> getAnnotationTypes() {
return (Set)this.getAnnotations().stream().filter(MergedAnnotation::isDirectlyPresent).map((annotation) -> {
return annotation.getType().getName();
}).collect(Collectors.toCollection(LinkedHashSet::new));
}
default Set<String> getMetaAnnotationTypes(String annotationName) {
MergedAnnotation<?> annotation = this.getAnnotations().get(annotationName, MergedAnnotation::isDirectlyPresent);
return !annotation.isPresent() ? Collections.emptySet() : (Set)MergedAnnotations.from(annotation.getType(), SearchStrategy.INHERITED_ANNOTATIONS).stream().map((mergedAnnotation) -> {
return mergedAnnotation.getType().getName();
}).collect(Collectors.toCollection(LinkedHashSet::new));
}
default boolean hasAnnotation(String annotationName) {
return this.getAnnotations().isDirectlyPresent(annotationName);
}
default boolean hasMetaAnnotation(String metaAnnotationName) {
return this.getAnnotations().get(metaAnnotationName, MergedAnnotation::isMetaPresent).isPresent();
}
default boolean hasAnnotatedMethods(String annotationName) {
return !this.getAnnotatedMethods(annotationName).isEmpty();
}
Set<MethodMetadata> getAnnotatedMethods(String var1);
static AnnotationMetadata introspect(Class<?> type) {
return StandardAnnotationMetadata.from(type);
}
}
ApplicationContext使用DefaultListableBeanFactory通過RootBeanDefinition將bean注入到IOC中。
相關文章
- Spring boot註解Spring Boot
- Spring典型註解-@Controller,@Component,@SpringController
- 山寨一個Spring的@Component註解Spring
- Spring Boot註解 之 @RequestXSpring Boot
- Spring Boot 自定義註解Spring Boot
- Spring Boot 自定義註解失效Spring Boot
- Spring Boot配置類的註解Spring Boot
- Spring Boot系列十八 Spring AOP + 註解實現統一註解Spring Boot
- spring boot的常用註解有哪些?Spring Boot
- Spring Boot開發(Gradle+註解)Spring BootGradle
- MyBatis 註解版(五)Spring boot 註解系列 插入物件返回 idMyBatisSpring Boot物件
- Spring Boot 自動配置之條件註解Spring Boot
- Spring Boot 自動配置之組合註解Spring Boot
- spring boot使用註解的方式整合mybaitsSpring BootAI
- spring boot 註解物件的問題 待研究Spring Boot物件
- Spring Boot註解@Transactional結合實際例子講解Spring Boot
- Spring / Spring boot 基於註解非同步程式設計@AsyncSpring Boot非同步程式設計
- Spring Boot 自動配置之@Enable* 與@Import註解Spring BootImport
- spring boot使用@Async非同步註解,原理+原始碼Spring Boot非同步原始碼
- spring boot啟動掃描不到自定義註解Spring Boot
- Spring Boot 最核心的 25 個註解,都是乾貨!Spring Boot
- spring boot @Async非同步註解上下文透傳Spring Boot非同步
- Spring Boot Transactional註解原始碼閱讀筆記(二)Spring Boot原始碼筆記
- spring boot 利用註解實現許可權驗證Spring Boot
- Spring Boot Transactional註解原始碼閱讀筆記(一)Spring Boot原始碼筆記
- Spring-Boot專案中配置redis註解快取SpringbootRedis快取
- Spring Boot 動態資料來源(Spring 註解資料來源)Spring Boot
- Spring Boot @Condition 註解,組合條件你知道嗎Spring Boot
- Spring Boot之使用Scheduled註解實現定時任務Springboot
- Spring註解Spring
- Spring Boot最常用的25個註解,乾貨瞭解一下Spring Boot
- 精盡Spring Boot原始碼分析 - 剖析 @SpringBootApplication 註解Spring Boot原始碼APP
- Spring Boot 基於註解驅動原始碼分析--自動配置Spring Boot原始碼
- 【Spring註解】事務註解@TransactionalSpring
- Spring註解詳解Spring
- Spring5:@Autowired註解、@Resource註解和@Service註解Spring
- Spring Boot Security 詳解Spring Boot
- 搞懂分散式技術14:Spring Boot使用註解整合Redis快取分散式Spring BootRedis快取