First is the entry application class code springboot
@SpringBootApplication public class HelloApplication { public static void main(String[] args) { SpringApplication.run(HelloApplication.class,args); } }
@SpringBootApplication annotated source code
/ **
* This class is a current project springboot
* /
target // standard used by the comment, classes, interfaces, abstract classes and other
@Target (ElementType.TYPE)
// declare the comment period for the run-
@Retention (RetentionPolicy .RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan (excludeFilters @Filter = {(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter (type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class)})
@interface SpringBootApplication {public
......
}
It can be seen that the comment is a combination of notes, mainly by @ SpringBootConfiguration, @ EnableAutoConfiguration, @ ComponentScan consisting of three notes, let's analyze one by one the three notes.
@SpringBootConfiguration
/ ** * indicates a current class SpringBoot application * / @Target (ElementType.TYPE) @Retention (RetentionPolicy.RUNTIME) @Documented @Configuration public @interface SpringBootConfiguration { @AliasFor (Annotation = Configuration.class) Boolean proxyBeanMethods () to true default; }
It can be seen from the annotation function is denoted @SpringBootConfiguration current class is a SpringBoot configuration, the main method in class so SpringBoot project bean can be injected by way of @Bean.
@EnableAutoConfiguration
/ ** * Spring Application Context starts automatically configured by introducing a jar (to starter mode), automatic configuration needs to guess * of the bean * use @SpringBootApplication annotations will automatically open configuration context * / @Target (the ElementType .TYPE) @Retention (RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import (AutoConfigurationImportSelector.class) public @interface EnableAutoConfiguration { String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; / ** * Auto-Configuration Exclude specific classes SUCH . that they will never be applied to exclude certain classes of automatic configuration, so that it never applied * the classes to the exclude @return * / class [] the exclude () {} default <?>; / ** * Exclude specific auto-configuration class names such that they will never be automatically configured to exclude a specific class name, so that it never applied * Applied. * @Return at The class names to the exclude * @Since 1.3.0 * / String [] excludeName () {} default; }
The Spring annotation is similar to other common annotations, like literally automatically configured to open, but the comment still is a combination of notes, consisting of two notes one @ AutoConfigurationPackage, @ Import
@AutoConfigurationPackage
/ ** * indicates automatic configuration packet * @Import annotation indicating the import container AutoConfigurationPackages.Registrar * / @Target (ElementType.TYPE) @Retention (RetentionPolicy.RUNTIME) @Documented @Inherited @Import (AutoConfigurationPackages.Registrar.class) @interface AutoConfigurationPackage {public }
AutoConfigurationPackages source See blog ( https://blog.csdn.net/andy_zhang2007/article/details/78652907 )
/ ** * Class for Storing Auto-Configuration Reference Packages for later * (EG by JPA Entity Scanner). * Automatically configured for storing packets for later reference abstract class (e.g., JPA entity scanner) * / public abstract AutoConfigurationPackages {class // log slfj Private static Logger = Final LogFactory.getLog the log (AutoConfigurationPackages.class); Private static String BEAN = Final AutoConfigurationPackages.class.getName (); / ** * The IF the Determine Base Packages for Auto-Configuration The gIVEN * bean factory are available. * determined automatically given configuration bean plants basic package is available * @param bean factory beanFactory the Source * @return to true iF there are Auto-config packages available * / public static boolean has(BeanFactory beanFactory) { return beanFactory.containsBean(BEAN) && !get(beanFactory).isEmpty(); } /** * Return the auto-configuration base packages for the given bean factory. * 返回给定bean工厂的自动配置基本包 * @param beanFactory the source bean factory * @return a list of auto-configuration packages * @throws IllegalStateException if auto-configuration is not enabled */ public static List<String> get(BeanFactory beanFactory) { try { return beanFactory.getBean(BEAN, BasePackages.class).get(); } catch (NoSuchBeanDefinitionException ex) { throw new IllegalStateException("Unable to retrieve @EnableAutoConfiguration base packages"); } } /** * Programmatically registers the auto-configuration package names. Subsequent * invocations will add the given package names to those that have already been * registered. You can use this method to manually define the base packages that will * be used for a given {@link BeanDefinitionRegistry}. Generally it's recommended that * you don't call this method directly, but instead rely on the default convention * where the package name is set from your {@code @EnableAutoConfiguration} * configuration class or classes. * @param registry the bean definition registry * @param packageNames the package names to set */ public static void register(BeanDefinitionRegistry registry, String... packageNames) { if (registry.containsBeanDefinition(BEAN)) { BeanDefinition beanDefinition = registry.getBeanDefinition(BEAN); ConstructorArgumentValues constructorArguments = beanDefinition.getConstructorArgumentValues(); constructorArguments.addIndexedArgumentValue(0, addBasePackages(constructorArguments, packageNames)); } else { GenericBeanDefinition beanDefinition = new GenericBeanDefinition(); beanDefinition.setBeanClass(BasePackages.class); beanDefinition.getConstructorArgumentValues().addIndexedArgumentValue(0, packageNames); beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); registry.registerBeanDefinition(BEAN, beanDefinition); } } private static String[] addBasePackages(ConstructorArgumentValues constructorArguments, String[] packageNames) { String[] existing = (String[]) constructorArguments.getIndexedArgumentValue(0, String[].class).getValue(); Set<String> merged = new LinkedHashSet<>(); merged.addAll(Arrays.asList(existing)); merged.addAll(Arrays.asList(packageNames)); return StringUtils.toStringArray(merged); } /** * {@link ImportBeanDefinitionRegistrar} to store the base package from * the importing configuration. * 用于存储导入配置的基本包 */ static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports { @Override public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) { register(registry, new PackageImport(metadata).getPackageName()); } @Override public Set<Object> determineImports(AnnotationMetadata metadata) { return Collections.singleton(new PackageImport(metadata)); } } /** * Wrapper for a package import. * 包装导入的包 */ private static final class PackageImport { private final String packageName; PackageImport(AnnotationMetadata metadata) { this.packageName = ClassUtils.getPackageName(metadata.getClassName()); } String getPackageName() { return this.packageName; } @Override public boolean equals(Object obj) { if (obj == null || getClass() != obj.getClass()) { return false; } return this.packageName.equals(((PackageImport) obj).packageName); } @Override public int hashCode() { return this.packageName.hashCode(); } @Override public String toString() { return "Package Import " + this.packageName; } } /** * Holder for the base package (name may be null to indicate no scanning). */ static final class BasePackages { private final List<String> packages; private boolean loggedBasePackageInfo; BasePackages(String... names) { List<String> packages = new ArrayList<>(); for (String name : names) { if (StringUtils.hasText(name)) { packages.add(name); } } this.packages = packages; } List<String> get() { if (!this.loggedBasePackageInfo) { if (this.packages.isEmpty()) { if (logger.isWarnEnabled()) { logger.warn("@EnableAutoConfiguration was declared on a class " + "in the default package. Automatic @Repository and " + "@Entity scanning is not enabled."); } } else { if (logger.isDebugEnabled()) { String packageNames = StringUtils.collectionToCommaDelimitedString(this.packages); logger.debug("@EnableAutoConfiguration was declared on a class in the package '" + packageNames + "'. Automatic @Repository and @Entity scanning is enabled."); } } this.loggedBasePackageInfo = true; } return this.packages; } } }
@Import(AutoConfigurationImportSelector.class)
@Import represents import element AutoConfigurationImportSelector class.
AutoConfigurationImportSelector represents the vessel is introduced a lot of automatic configuration class (xxxAutoConfiguration), all the components introduced into the container to the desired scene, and these components configure
@ComponentScan range scan package configuration, the default scan package and its sub-packets of the current class is.
Summary: @SpringBootApplication comment springboot is the core of the project, which is a combination of annotation notes, a combination of @ SpringBootConfiguration, @ EnableAutoConfiguration, @ ComponentScan three notes together, @ SpringBootConfiguration notes that the current class as a SpringBoot class configuration, it is possible in the current class injecting assembly into the container by way @Bean, @ EnableAutoConfiguration comment is automatically turned showing configuration, SpringBoot our guess we import the necessary components according to the initiator, and help us to automatically import configuration, @ ComponentScan scan showing the configuration package range, the current class is the default scan package, as well as its sub-packets.
(Due to the limited level of the author's understanding of SpringBoot's not impressive enough, with the future of learning, we will continue to modify the contents of the blog, perfect.)