通过spring配置文件详解可以达到@EnableScheduling这种效果

干货:Spring Boot的自动配置干货:Spring Boot的自动配置婷婷汽车百家号随着Ruby、Groovy等动态语言的流行,相比较之下Java的开发显得格外笨重。繁多的配置、低下的开发效率、复杂的部署流程以及第三方技术集成难度大等问题一直被人们所诟病。随着Spring家族中的新星Spring Boot的诞生,这些问题都在逐渐被解决。个人觉得Spring Boot中最重要的两个优势就是可以使用starter简化依赖配置和Spring的自动配置。使用starter简化依赖配置Spring提供了一系列starter来简化Maven配置。其核心原理也就是Maven和Gradle的依赖传递方案。当我们在我们的pom文件中增加对某个starter的依赖时,该starter的依赖也会自动的传递性被依赖进来。而且,很多starter也依赖了其他的starter。例如webstarter就依赖了tomcat starter,并且大多数starter基本都依赖了spring-boot-starter。Spring自动配置Spring Boot会根据类路径中的jar包、类,为jar包里的类自动配置,这样可以极大的减少配置的数量。简单点说就是它会根据定义在classpath下的类,自动的给你生成一些Bean,并加载到Spring的Context中。自动配置充分的利用了spring 4.0的条件化配置特性,能够自动配置特定的Spring bean,用来启动某项特性。条件化配置假设你希望一个或多个bean只有在某种特殊的情况下才需要被创建,比如,一个应用同时服务于中美用户,要在中美部署,有的服务在美国集群中需要提供,在中国集群中就不需要提供。在Spring 4之前,要实现这种级别的条件化配置是比较复杂的,但是,Spring 4引入了一个新的@Conditional注解可以有效的解决这类问题。@Bean @Conditional(ChinaEnvironmentCondition.class) publicServiceBeanserviceBean{ returnnewServiceB }当@Conditional(ChinaEnvironmentCondition.class)条件的值为true的时候,该ServiceBean才会被创建,否则该bean就会被忽略。@Conditional指定了一个条件。他的条件的实现是一个Java类——ChinaEnvironmentCondition,要实现以上功能就要定义ChinaEnvironmentCondition类,并继承Condition接口并重写其中的matches方法。class ChinaEnvironmentCondition implements Condition{ public final boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { Environment env = context.getE return env.containProperty(&ENV_CN&); } }在上面的代码中,matches方法的内容比较简单,他通过给定的ConditionContext对象进而获取Environment对象,然后使用该对象检查环境中是否存在ENV_CN属性。如果存在该方法则直接返回true,反之返回false。当该方法返回true的时候,就符合了@Conditional指定的条件,那么ServiceBean就会被创建。反之,如果环境中没有这个属性,那么这个ServiceBean就不会被创建。除了可以自定义一些条件之外,Spring 4本身提供了很多已有的条件供直接使用,如:@ConditionalOnBean @ConditionalOnClass @ConditionalOnExpression @ConditionalOnMissingBean@ConditionalOnMissingClass @ConditionalOnNotWebApplicationSpring Boot应用的启动入口自动配置充分的利用了spring 4.0的条件化配置特性,那么,Spring Boot是如何实现自动配置的?Spring 4中的条件化配置又是怎么运用到Spring Boot中的呢?这要从Spring Boot的启动类说起。Spring Boot应用通常有一个名为*Application的入口类,入口类中有一个main方法,这个方法其实就是一个标准的Java应用的入口方法。一般在main方法中使用SpringApplication.run来启动整个应用。值得注意的是,这个入口类要使用@SpringBootApplication注解声明。@SpringBootApplication是Spring Boot的核心注解,他是一个组合注解。@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 @interfaceSpringBootApplication { //略 }@SpringBootApplication是一个组合注解,它主要包含@SpringBootConfiguration、@EnableAutoConfiguration等几个注解。也就是说可以直接在启动类中使用这些注解来代替@ SpringBootApplication注解。关于Spring Boot中的Spring自动化配置主要是@EnableAutoConfiguration的功劳。该注解可以让Spring Boot根据类路径中的jar包依赖为当前项目进行自动配置。至此,我们知道,Spring Boot的自动化配置主要是通过@EnableAutoConfiguration来实现的,因为我们在程序的启动入口使用了@SpringBootApplication注解,而该注解中组合了@EnableAutoConfiguration注解。所以,在启动类上使用@EnableAutoConfiguration注解,就会开启自动配置。那么,本着刨根问底的原则,当然要知道@EnableAutoConfiguration又是如何实现自动化配置的,因为目前为止,我们还没有发现Spring 4中条件化配置的影子。EnableAutoConfiguration其实Spring框架本身也提供了几个名字为@Enable开头的Annotation定义。比如@EnableScheduling、@EnableCaching、@EnableMBeanExport等,@EnableAutoConfiguration的理念和这些注解其实是一脉相承的。@EnableScheduling是通过@Import将Spring调度框架相关的bean定义都加载到IoC容器。@EnableMBeanExport是通过@Import将JMX相关的bean定义加载到IoC容器。@EnableAutoConfiguration也是借助@Import的帮助,将所有符合自动配置条件的bean定义加载到IoC容器。下面是EnableAutoConfiguration注解的源码:@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented@Inherited@AutoConfigurationPackage @Import({EnableAutoConfigurationImportSelector.class}) public @interfaceEnableAutoConfiguration { //略 }观察@EnableAutoConfiguration可以发现,这里Import了@EnableAutoConfigurationImportSelector,这就是Spring Boot自动化配置的“始作俑者”。至此,我们知道,至此,我们知道,由于我们在Spring Boot的启动类上使用了@SpringBootApplication注解,而该注解组合了@EnableAutoConfiguration注解,@EnableAutoConfiguration是自动化配置的“始作俑者”,而@EnableAutoConfiguration中Import了@EnableAutoConfigurationImportSelector注解,该注解的内部实现已经很接近我们要找的“真相”了。EnableAutoConfigurationImportSelectorEnableAutoConfigurationImportSelector的源码在这里就不贴了,感兴趣的可以直接去看一下,其实实现也比较简单,主要就是使用Spring 4提供的的SpringFactoriesLoader工具类。通过SpringFactoriesLoader.loadFactoryNames读取了ClassPath下面的META-INF/spring.factories文件。这里要简单提一下spring.factories文件,它是一个典型的java properties文件,配置的格式为Key = Value形式。EnableAutoConfigurationImportSelector通过读取spring.factories中的key为org.springframework.boot.autoconfigure.EnableAutoConfiguration的值。如spring-boot-autoconfigure-1.5.1.RELEASE.jar中的spring.factories文件包含以下内容:# Auto Configure org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\ org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\ org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\ org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\ org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\ org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\ org.springframework.boot.autoconfigure.cloud.CloudAutoConfiguration,\ ...... org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration上面的EnableAutoConfiguration配置了多个类,这些都是Spring Boot中的自动配置相关类;在启动过程中会解析对应类配置信息。每个Configuation都定义了相关bean的实例化配置。都说明了哪些bean可以被自动配置,什么条件下可以自动配置,并把这些bean实例化出来。如果我们新定义了一个starter的话,也要在该starter的jar包中提供spring.factories文件,并且为其配置org.springframework.boot.autoconfigure.EnableAutoConfiguration对应的配置类。Configuation我们从spring-boot-autoconfigure-1.5.1.RELEASE.jar中的spring.factories文件随便找一个Configuration,看看他是如何自动加载bean的。@Configuration @AutoConfigureAfter({JmxAutoConfiguration.class}) @ConditionalOnProperty( prefix = &spring.application.admin&, value = {&enabled&}, havingValue = &true&, matchIfMissing = false ) public class SpringApplicationAdminJmxAutoConfiguration { @Bean @ConditionalOnMissingBean public SpringApplicationAdminMXBeanRegistrar springApplicationAdminRegistrar throws MalformedObjectNameException { String jmxName = this.environment.getProperty(&spring.application.admin.jmx-name&, &org.springframework.boot:type=Admin,name=SpringApplication&); if(this.mbeanExporter != null) { this.mbeanExporter.addExcludedBean(jmxName); } returnnewSpringApplicationAdminMXBeanRegistrar(jmxName); } }看到上面的代码,终于找到了我们要找的东西——Spring 4的条件化配置。上面SpringApplicationAdminJmxAutoConfiguration在决定对哪些bean进行自动化配置的时候,使用了两个条件注解:ConditionalOnProperty和ConditionalOnMissingBean。只有满足这种条件的时候,对应的bean才会被创建。这样做的好处是什么?这样可以保证某些bean在没满足特定条件的情况下就可以不必初始化,避免在bean初始化过程中由于条件不足,导致应用启动失败。总结至此,我们可以总结一下Spring Boot的自动化配置的实现:通过Spring 4的条件配置决定哪些bean可以被配置,将这些条件定义成具体的Configuation,然后将这些Configuation配置到spring.factories文件中,作为key:org.springframework.boot.autoconfigure.EnableAutoConfiguration的值,这时候,容器在启动的时候,由于使用了EnableAutoConfiguration注解,该注解Import的EnableAutoConfigurationImportSelector会去扫描classpath下的所有spring.factories文件,然后进行bean的自动化配置。我特意整理了一下,里面的技术不是靠几句话就能讲清楚,所以干脆找朋友录制了一些视频,很多问题其实答案很简单,但是背后的思考和逻辑不简单,要做到知其然还要知其所以然。如果想学习Java工程化、高性能及分布式、深入浅出。性能调优、Spring,MyBatis,Netty源码分析的朋友可以加我新建的Java群:,群里有阿里大牛直播讲解技术,以及Java大型互联网技术的视频免费分享给大家。所以,如果我们想要自定义一个starter的话,可以通过以上方式将自定义的starter中的bean自动化配置到Spring的上下文中,从而避免大量的配置。注:喜欢的朋友可以点赞关注,一起学习进步本文仅代表作者观点,不代表百度立场。系作者授权百家号发表,未经许可不得转载。婷婷汽车百家号最近更新:简介:致力打造汽车知识大讲堂,专注汽车领域精神作者最新文章相关文章@EnableAutoCongiguration详解
从Spring 3.0开始,为了替代繁琐的XML配置,引入了@Enable...注解对@Configuration类进行修饰以达到和XML配置相同的效果。想必不少开发者已经使用过类似注解:@EnableTransactionManagement开启Spring事务管理,相当于XMl中的&tx:*&@EnableWebMvc使用Spring MVC框架的一些默认配置@EnableScheduling会初始化一个Scheduler用于执行定时任务和异步任务Spring Boot提供的@EnableAutoCongiguration似乎功能更加强大,一旦加上,上述所有的配置似乎都被包含进来而无需开发者显式声明。它究竟是如何做到的呢,先看看它的定义:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({ EnableAutoConfigurationImportSelector.class,
AutoConfigurationPackages.Registrar.class })
public @interface EnableAutoConfiguration {
* Exclude specific auto-configuration classes such that they will never be applied.
Class&?&[] exclude() default {};
EnableAutoConfigurationImportSelector使用的是spring-core模块中的SpringFactoriesLoader#loadFactoryNames()方法,它的作用是在类路径上扫描META-INF/spring.factories文件中定义的类:# Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.data.JpaRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.MongoRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.redis.RedisAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JmsTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,\
org.springframework.boot.autoconfigure.mobile.DeviceResolverAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.autoconfigure.reactor.ReactorAutoConfiguration,\
org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.FallbackWebSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\
org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration,\
org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.web.MultipartAutoConfiguration,\
org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration,\
org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.WebSocketAutoConfiguration实际上这就是Spring Boot会自动配置的一些对象,例如前面提到的Web框架由EmbeddedServletContainerAutoConfiguration, DispatcherServletAutoConfiguration, ServerPropertiesAutoConfiguration等配置完成,而DataSource的自动配置则是由DataSourceAutoConfiguration完成。现在我们以Mongo的配置MongoAutoConfiguration为例,来探索Spring
Boot是如何完成这些配置的:@Configuration
@ConditionalOnClass(Mongo.class)
@EnableConfigurationProperties(MongoProperties.class)
public class MongoAutoConfiguration {
@Autowired
private MongoP
@PreDestroy
public void close() throws UnknownHostException {
if (this.mongo != null) {
this.mongo.close();
@ConditionalOnMissingBean
public Mongo mongo() throws UnknownHostException {
this.mongo = this.properties.createMongoClient();
return this.
首先这是一个Spring的配置@Configuration,它定义了我们访问Mongo需要的@Bean,如果这个@Configuration被Spring Context扫描到,那么Context中自然也就有两个一个Mongo对象能够直接为开发者所用。
但是注意到其它几个Spring注解:@ConditionOnClass表明该@Configuration仅仅在一定条件下才会被加载,这里的条件是Mongo.class位于类路径上@EnableConfigurationProperties将Spring Boot的配置文件(application.properties)中的spring.data.mongodb.*属性映射为MongoProperties并注入到MongoAutoConfiguration中。@ConditionalOnMissingBean说明Spring Boot仅仅在当前上下文中不存在Mongo对象时,才会实例化一个Bean。这个逻辑也体现了Spring Boot的另外一个特性——自定义的Bean优先于框架的默认配置,我们如果显式的在业务代码中定义了一个Mongo对象,那么Spring Boot就不再创建。
接下来看一看MongoProperties:
@ConfigurationProperties(prefix = "spring.data.mongodb")
public class MongoProperties {
private int port = DBPort.PORT;
private String uri = "mongodb://localhost/test";
// ... getters/ setters omitted
显然,它就是以spring.data.mongodb作为前缀的属性,然后通过名字直接映射为对象的属性,同时还包含了一些默认值。如果不配置,那么mongo.uri就是mongodb://localhost/test。
没有更多推荐了,
不良信息举报
举报内容:
@EnableAutoCongiguration详解
举报原因:
原文地址:
原因补充:
最多只允许输入30个字
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!你似乎来到了没有知识存在的荒原...
来源链接是否正确?用户、话题或问题是否存在?基于Spring
Boot 实现定时任务-springboot,java,spring 相关文章-天码营
基于Spring
Boot 实现定时任务
很多时候,我们有这么一个需求,需要在每天的某个固定时间或者每隔一段时间让应用去执行某一个任务。为了实现这个需求,通常我们会通过多线程来实现这个功能,但是这样我们需要自己做一些比较麻烦的工作。接下来,让我们看看如何使用Spring scheduling task简化定时任务功能的实现。添加maven依赖为了方便展示,我们使用Spring Boot来简化我们的Spring配置。因为我们使用的是Spring自带的Scheduling,因此我们只需要引入最进本的spring-boot-starter即可。&parent&
&groupId&org.springframework.boot&/groupId&
&artifactId&spring-boot-starter-parent&/artifactId&
&version&1.2.5.RELEASE&/version&
&properties&
&java.version&1.8&/java.version&
&/properties&
&dependencies&
&dependency&
&groupId&org.springframework.boot&/groupId&
&artifactId&spring-boot-starter&/artifactId&
&/dependency&
&/dependencies&
注意,Spring boot需要JDK8的编译环境。创建Scheduled Task让我们创建一个ScheduleTask来实现我们的需求:@Component
public class ScheduledTask {
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private Integer count0 = 1;
private Integer count1 = 1;
private Integer count2 = 1;
@Scheduled(fixedRate = 5000)
public void reportCurrentTime() throws InterruptedException {
System.out.println(String.format("---第%s次执行,当前时间为:%s", count0++, dateFormat.format(new Date())));
@Scheduled(fixedDelay = 5000)
public void reportCurrentTimeAfterSleep() throws InterruptedException {
System.out.println(String.format("===第%s次执行,当前时间为:%s", count1++, dateFormat.format(new Date())));
@Scheduled(cron = "0 0 1 * * *")
public void reportCurrentTimeCron() throws InterruptedException {
System.out.println(String.format("+++第%s次执行,当前时间为:%s", count2++, dateFormat.format(new Date())));
可以看到,我们在我们真正需要执行的方法上添加了@Scheduled标注,表示这个方法是需要定时执行的。在@Scheduled标注中,我们使用了三种方式来实现了同一个功能:每隔5秒钟记录一次当前的时间:fixedRate = 5000表示每隔5000ms,Spring scheduling会调用一次该方法,不论该方法的执行时间是多少fixedDelay = 5000表示当方法执行完毕5000ms后,Spring scheduling会再次调用该方法cron = "*/5 * * * * * *"提供了一种通用的定时任务表达式,这里表示每隔5秒执行一次,更加详细的信息可以参考。配置Scheduling接下来我们通过Spring boot来配置一个最简单的Spring web应用,我们只需要一个带有main方法的类即可:@SpringBootApplication
@EnableScheduling
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
我们先来看看class上的标注:@SpringBootApplication 实际上是了以下三个标注的集合:@Configuration 告诉Spring这是一个配置类,里面的所有标注了@Bean的方法的返回值将被注册为一个Bean@EnableAutoConfiguration 告诉Spring基于class path的设置、其他bean以及其他设置来为应用添加各种Bean@ComponentScan 告诉Spring扫描Class path下所有类来生成相应的Bean@EnableScheduling 告诉Spring创建一个task executor,如果我们没有这个标注,所有@Scheduled标注都不会执行通过以上标注,我们完成了schedule的基本配置。最后,我们添加main方法来启动一个Spring boot应用即可。测试在根目录下执行命令:mvn spring-boot:run,我们可以看到:
本文由创作,转载需署名作者且注明文章出处
要获取本文的参考代码,请访问:
cron = "*/5 * * * * * *"& &多了个*大兄弟
Spring MVC实战入门训练,以一个博客系统为例,将Spring MVC的核心知识融入到实战当中...
练习基于MyBatis和Spring MVC搭建问答网站,学习Spring/Spring MVC/S...
本课程中将介绍目前深度学习领域中最流行的诸多模型和算法。通过对这些算法的学习,你将能够对深度学习领域...

我要回帖

更多关于 配置文件 的文章

 

随机推荐