文章目录
1.@Component
注解
@Configuration
、@Repository
、@Service
、@Controller
等注解被标注为@Component
2.@Bean
注解
package com.example.demo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author :ouruyi
* @version 1.0
* @date :Created in 2021/5/29 20:12
* 功能描述:
*/
@Configuration
public class ResourceConfiguration {
@Bean(initMethod = "init", destroyMethod = "cleanup")
public Person person() {
return new Person();
}
}
3.@Import
注解
Spring源码
@Enable
就是采用此方式导入bean
重点说明下
@Import
注解,可用于导入普通类、@Configuration
类、ImportSelector
接口实现类返回的全限类名、ImportBeanDefinitionRegistrar
类。
3.1 导入普通类到Spring容器
package com.example.demo;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/**
* @author :ouruyi
* @version 1.0
* @date :Created in 2021/5/29 20:12
* 功能描述:
*/
@Configuration
@Import(Person.class)
public class ResourceConfiguration {
}
3.2 导入@Configuration类
注意:MyConfiguration类可以不用加
@Configuration
注解
package com.example.demo;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/**
* @author :ouruyi
* @version 1.0
* @date :Created in 2021/5/29 20:12
* 功能描述:
*/
@Configuration
@Import(MyConfiguration.class)
public class ResourceConfiguration {
}
package com.example.demo;
import org.springframework.context.annotation.Bean;
/**
* @author :ouruyi
* @version 1.0
* @date :Created in 2021/5/29 20:24
* 功能描述:
*/
public class MyConfiguration {
@Bean(initMethod = "init", destroyMethod = "cleanup")
public Person person() {
return new Person();
}
}
3.3 导入ImportSelector
接口实现类返回的全限类名
package com.example.demo;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/**
* @author :ouruyi
* @version 1.0
* @date :Created in 2021/5/29 20:12
* 功能描述:
*/
@Configuration
@Import(MyImportSelector.class)
public class ResourceConfiguration {
}
package com.example.demo;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
import java.util.function.Predicate;
/**
* @author :ouruyi
* @version 1.0
* @date :Created in 2021/5/29 20:28
* 功能描述:
*/
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{Person.class.getName()};
}
@Override
public Predicate<String> getExclusionFilter() {
return null;
}
}
3.4 导入ImportBeanDefinitionRegistrar
类。
package com.example.demo;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/**
* @author :ouruyi
* @version 1.0
* @date :Created in 2021/5/29 20:12
* 功能描述:
*/
@Configuration
@Import(MyImportBeanDefinitionRegistrar.class)
public class ResourceConfiguration {
}
package com.example.demo;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
/**
* @author :ouruyi
* @version 1.0
* @date :Created in 2021/5/29 20:38
* 功能描述:
*/
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(Person.class.getName());
registry.registerBeanDefinition("person", beanDefinitionBuilder.getBeanDefinition());
}
}
3.5 总结
说明:从以下@Import源码处理过程看出“导入普通类到Spring容器”和“导入@Configuration类”其实是一个东西。
org.springframework.context.annotation.ConfigurationClassParser#processImports
// Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
// process it as an @Configuration class
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
Collection<SourceClass> importCandidates, Predicate<String> exclusionFilter,
boolean checkForCircularImports) {
if (importCandidates.isEmpty()) {
return;
}
if (checkForCircularImports && isChainedImportOnStack(configClass)) {
this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
}
else {
this.importStack.push(configClass);
try {
for (SourceClass candidate : importCandidates) {
if (candidate.isAssignable(ImportSelector.class)) {
// Candidate class is an ImportSelector -> delegate to it to determine imports
Class<?> candidateClass = candidate.loadClass();
ImportSelector selector = ParserStrategyUtils.instantiateClass(candidateClass, ImportSelector.class,
this.environment, this.resourceLoader, this.registry);
Predicate<String> selectorFilter = selector.getExclusionFilter();
if (selectorFilter != null) {
exclusionFilter = exclusionFilter.or(selectorFilter);
}
if (selector instanceof DeferredImportSelector) {
this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector) selector);
}
else {
String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames, exclusionFilter);
processImports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false);
}
}
else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
// Candidate class is an ImportBeanDefinitionRegistrar ->
// delegate to it to register additional bean definitions
Class<?> candidateClass = candidate.loadClass();
ImportBeanDefinitionRegistrar registrar =
ParserStrategyUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class,
this.environment, this.resourceLoader, this.registry);
configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
}
else {
// Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
// process it as an @Configuration class
this.importStack.registerImport(
currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
processConfigurationClass(candidate.asConfigClass(configClass), exclusionFilter);
}
}
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to process import candidates for configuration class [" +
configClass.getMetadata().getClassName() + "]", ex);
}
finally {
this.importStack.pop();
}
}
}