SpringBoot学习笔记1简单了解

SpringBoot学习笔记---Day01

  • SpringBoot主程序入口注解@SpringBootApplication
    • 1.@SpringBootConfiguration
    • 2. @EnableAutoConfiguration

SpringBoot主程序入口注解@SpringBootApplication

由多个注解组合而成
源码部分

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
		@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {

1.@SpringBootConfiguration

@SpringBootConfiguration 源码

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {

}

这里面最主要的注解@Configuration
从Spring3.0,@Configuration用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。
1.1@Configuration源码:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {

可以看到@Component
2.说明@Configuration注解下的类也会注册为bean,内部可以依赖注入(Bean能用的东西他都能用)
关于注解@Configuration的资料链接: https://blog.csdn.net/leoxyk/article/details/79800020.

2. @EnableAutoConfiguration

将主配置类所在包及其子包下的所有组件都扫描到spring容器
@EnableAutoConfiguration注解源码

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {

此注解作用为开启自动配置功能,以前需要配置的东西,springboot会帮我们配置好,@EnableAutoConfiguration告诉springboot开启自动配置功能,这样配置才会生效
这里面有@AutoConfigurationPackage注解,此注解作用为自动配置包
2.1@AutoConfigurationPackage源码

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {

}

这个自动配置包的功能主要由@Import(AutoConfigurationPackages.Registrar.class)注解来完成的
@Import属于spring底层的注解,此注解的功能可以为容器中导入组件,要怎么导入组件呢?
演示@Configuration和@Import注解的使用方法
下面有我自己用@Configuration注解写的一个连接mysql数据库的一个配置类,里面用到@import注解来向@Configuration注解下的类添加组件
主配置类

/**
 * 该类是一个配置类,作用和bean.xml作用一样
 * spring中的新注解
 * @Configuration 指定当前类是一个配置类
 * @ComponentScan 指定要扫描的包
 *          属性:basePackages和value一样
 *          作用等同于
 * @Bean 用于把当前方法的返回值当做bean对象传入Spring的ioc容器中
 *          属性:name 用于指定bean的id,如果不写则默认是当前方法的名称
 *          当我们使用注解配置方法时,如果方法有参数,spring框架会去容器中查找有没有可用的bean对象
 *          查找方式可Autowired方式是一样的,自动按照类型匹配,先匹配容器中有没有唯一配置的类型
 */
@Configuration
@ComponentScan(basePackages = {"com.haohan"})
@PropertySource(value = "classpath:jdbcConfig.properties")
@Import(value = SpringJdbcConfig.class)
public class SpringConfiguration {
}

由@Import调用的组件配置类

public class SpringJdbcConfig {
    @Value("${jdbc.driver}")
    private String driver;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;

    @Bean(name = "runner")
    @Scope(scopeName = "prototype")
    public QueryRunner createQueryRunner(@Qualifier("da1") DataSource dataSource){
        return new QueryRunner(dataSource);
    }
    @Bean(name = "da1")
    public ComboPooledDataSource createDataSource(){
        ComboPooledDataSource comboPooledDataSource = null;
        try {
            comboPooledDataSource = new ComboPooledDataSource();
            comboPooledDataSource.setDriverClass(driver);
            comboPooledDataSource.setJdbcUrl(url);
            comboPooledDataSource.setUser(username);
            comboPooledDataSource.setPassword(password);
        } catch (PropertyVetoException e) {
            e.printStackTrace();
        }
        return comboPooledDataSource;
    }
}

由@import注解导入了一个AutoConfigurationPackages.Registrar.class的类
** 2.1.1AutoConfigurationPackages.Registrar.class源码**

@Order(Ordered.HIGHEST_PRECEDENCE)
	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.<Object>singleton(new PackageImport(metadata));
		}

	}

此类为一个静态内部类,其中的registerBeanDefinitions方法的参数AnnotationMetadata metadata为注解源信息标的就是@SpringBootApplication,也就是springboot入口的注解,接下来看里面调用的register方法,的第二个参数,new PackageImports(metadata).getPackageNames().toArray(new String[0]))这里
getPackageNames()获取主配置类的包名
在@AutoConfigurationPackage的下方还有个@Import(AutoConfigurationImportSelector.class),导入哪些组件的选择器
2.2 AutoConfigurationImportSelector.class 源码

@Override
	public String[] selectImports(AnnotationMetadata annotationMetadata) {
		if (!isEnabled(annotationMetadata)) {
			return NO_IMPORTS;
		}
		try {
			AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
					.loadMetadata(this.beanClassLoader);
			AnnotationAttributes attributes = getAttributes(annotationMetadata);
			List<String> configurations = getCandidateConfigurations(annotationMetadata,
					attributes);
			configurations = removeDuplicates(configurations);
			configurations = sort(configurations, autoConfigurationMetadata);
			Set<String> exclusions = getExclusions(annotationMetadata, attributes);
			checkExcludedClasses(configurations, exclusions);
			configurations.removeAll(exclusions);
			configurations = filter(configurations, autoConfigurationMetadata);
			fireAutoConfigurationImportEvents(configurations, exclusions);
			return configurations.toArray(new String[configurations.size()]);
		}
		catch (IOException ex) {
			throw new IllegalStateException(ex);
		}
	}

在AutoConfigurationImportSelector有个 selectImports方法,这个方法的作用就是为spring容器导入哪些组件
里面的getCandidateConfigurations方法返回一个configurations的list集合.这个集合里面就是springboot需要导入的组件(自动配置类),比如我们要aop功能,就会导入aop的组件,如果是批处理的功能,就会导入批处理的组件,有了这些自动配置类,就免去了我们手动配置,编写注入功能组件等工作
在spring-boot-autoconfigure包下的/META-INF/spring.factories下获取EnableAutoConfiguration指定的值,将这些值作为自动配置类导入到spring容器中,帮我们进行配置工作

你可能感兴趣的:(springboot)