• SpringBoot 自动化配置,以quartz为例


    总结来说:

    SpringBoot的自动化配置是这样实现的,启动时会去加载jar包(一般是spring-boot-autoconfigure-2.1.1.RELEASE.jar)中如下路径的“META-INF/spring.factories”内容,如下:

    org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration,\
    org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\
    org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
    org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration,\
    org.springframework.boot.autoconfigure.reactor.core.ReactorCoreAutoConfiguration,\
    org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,

    然后以上述的全类名加载相关的bean,比如QuartzAutoConfiguration进行自动化配置,如下:

    package org.springframework.boot.autoconfigure.quartz;
    
    import java.util.Map;
    import java.util.Properties;
    
    import javax.sql.DataSource;
    
    import org.quartz.Calendar;
    import org.quartz.JobDetail;
    import org.quartz.Scheduler;
    import org.quartz.Trigger;
    
    import org.springframework.beans.factory.ObjectProvider;
    import org.springframework.boot.autoconfigure.AbstractDependsOnBeanFactoryPostProcessor;
    import org.springframework.boot.autoconfigure.AutoConfigureAfter;
    import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
    import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
    import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
    import org.springframework.boot.context.properties.EnableConfigurationProperties;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.annotation.Order;
    import org.springframework.core.io.ResourceLoader;
    import org.springframework.scheduling.quartz.SchedulerFactoryBean;
    import org.springframework.scheduling.quartz.SpringBeanJobFactory;
    import org.springframework.transaction.PlatformTransactionManager;
    
    /**
     * {@link EnableAutoConfiguration Auto-configuration} for Quartz Scheduler.
     *
     * @author Vedran Pavic
     * @author Stephane Nicoll
     * @since 2.0.0
     */
    @Configuration
    @ConditionalOnClass({ Scheduler.class, SchedulerFactoryBean.class,
            PlatformTransactionManager.class })
    @EnableConfigurationProperties(QuartzProperties.class)
    @AutoConfigureAfter({ DataSourceAutoConfiguration.class,
            HibernateJpaAutoConfiguration.class })
    public class QuartzAutoConfiguration {
    
        private final QuartzProperties properties;
    
        private final ObjectProvider<SchedulerFactoryBeanCustomizer> customizers;
    
        private final JobDetail[] jobDetails;
    
        private final Map<String, Calendar> calendars;
    
        private final Trigger[] triggers;
    
        private final ApplicationContext applicationContext;
    
        public QuartzAutoConfiguration(QuartzProperties properties,
                ObjectProvider<SchedulerFactoryBeanCustomizer> customizers,
                ObjectProvider<JobDetail[]> jobDetails,
                ObjectProvider<Map<String, Calendar>> calendars,
                ObjectProvider<Trigger[]> triggers, ApplicationContext applicationContext) {
            this.properties = properties;
            this.customizers = customizers;
            this.jobDetails = jobDetails.getIfAvailable();
            this.calendars = calendars.getIfAvailable();
            this.triggers = triggers.getIfAvailable();
            this.applicationContext = applicationContext;
        }
        //最重要的一步是生成SchedulerFactoryBean,通过这个FactoryBean就可以生成Scheduler对象,达到自动化配置的效果
        @Bean
        @ConditionalOnMissingBean
        public SchedulerFactoryBean quartzScheduler() {
            SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
            SpringBeanJobFactory jobFactory = new SpringBeanJobFactory();
            jobFactory.setApplicationContext(this.applicationContext);
            schedulerFactoryBean.setJobFactory(jobFactory);
            if (this.properties.getSchedulerName() != null) {
                schedulerFactoryBean.setSchedulerName(this.properties.getSchedulerName());
            }
            schedulerFactoryBean.setAutoStartup(this.properties.isAutoStartup());
            schedulerFactoryBean
                    .setStartupDelay((int) this.properties.getStartupDelay().getSeconds());
            schedulerFactoryBean.setWaitForJobsToCompleteOnShutdown(
                    this.properties.isWaitForJobsToCompleteOnShutdown());
            schedulerFactoryBean
                    .setOverwriteExistingJobs(this.properties.isOverwriteExistingJobs());
            if (!this.properties.getProperties().isEmpty()) {
                schedulerFactoryBean
                        .setQuartzProperties(asProperties(this.properties.getProperties()));
            }
            if (this.jobDetails != null && this.jobDetails.length > 0) {
                schedulerFactoryBean.setJobDetails(this.jobDetails);
            }
            if (this.calendars != null && !this.calendars.isEmpty()) {
                schedulerFactoryBean.setCalendars(this.calendars);
            }
            if (this.triggers != null && this.triggers.length > 0) {
                schedulerFactoryBean.setTriggers(this.triggers);
            }
            customize(schedulerFactoryBean);
            return schedulerFactoryBean;
        }
    ......
    }

    那启动时是如何加载spring.factories文件中的类并生成对象的呢

    这块每个版本的SpringBoot项目实现是不一样的,此处以2.1.1版本为例说明:

    1、启动类的:

    @SpringBootApplication

    2、SpringootApplication的@EnableAutoConfiguration注解:

    @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 {

    3、@EnableAutoConfiguration中的@Import(AutoConfigurationImportSelector.class)注解:

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

    4、@Import注解的作用就是生成bean,而生成哪些bean就是根据他的参数AutoConfigurationImportSelector.class来决定。

    5、AutoConfigurationImportSelector中定义了需要生成的bean的列表。

  • 相关阅读:
    Linux系统中pssh系列工具的使用
    Linux软件包管理和磁盘管理实践
    Linux系统自动化安装之pxe实现
    Linux系统SSH服务基于key认证实践
    Linux系统文本处理之awk数组实践
    Linux访问控制列表
    Linux系统中SSH端口转发
    (转)python的range()函数用法
    Python 学习之list和Tuple类型
    List<String> 和 ArrayList<String>的区别
  • 原文地址:https://www.cnblogs.com/silenceshining/p/16037014.html
Copyright © 2020-2023  润新知