SpringBoot学习笔记
SpringBoot学习笔记
春节期间,对SpringBoot做了一些学习,记录点心得。
SpringBoot是Spring发展史的一个新的起点,有非常多新的特性。其中最重要的特性是自动化,原先我们在Spring中很多的Config类及Bean的定义都不需要了,是个非常大的优点。
初始配置
让我们从Maven配置开始,已经最大程度简化了。从下面的配置中,我们可以看到依赖中不包含版本信息,因为SpringBoot非常好的做了测试,对应版本都是可用的。如果需要使用更高的版本,需要进行下测试。
需要注意的是,SpringBoot默认不包含MyBatis,需要单独添加。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
入口注解
SpringBoot应用都是从SpringBootApplication这个注解开始,其代码如下,我们分析下其内部特性。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class))
public @interface SpringBootApplication {
Class<?>[] exclude() default {};
String[] excludeName() default {};
@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
String[] scanBasePackages() default {};
@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
Class<?>[] scanBasePackageClasses() default {};
}
@SpringBootConfiguraion就是标准的配置,里面直接可以定义Bean,但需要知道的是一个SpringBoot只能出现一次这个注解。
@ComponetScan默认扫描相同包下的Bean,如果是其他的就需要配置。可以加一些简单的过滤去,选择或者排除掉一些特定的Bean。
@EnableAutoConfiguration最为关键,下面会详述。
自动配置
@EnableAutoConfiguration,这个是SpringBoot的核心:自动配置。
简单来说,如果我们的程序包里包含了某个class,把某一个jar包放进来,Spring会猜测我们希望用到里面的某些Bean。这个时候,SpringBoot就会定义一个Config的配置,把jar包里的Bean定义好,然后可以自动的纳进来。就是说我们不用定义Bean了,也不用写Config文件。SpringBoot就自动加载进来,好处是已经做了好多的现成模块可以用。
其机制是通过定义一个Configuration的class,里面可以通过配置,将其他的Configuration引入进来。在jar包下META-INF/spring.factories文件里面会定义的是接口类和接口实现类。已经实现的引入都存放在spring-boot-autoconfigure下面,默认引入非常多有100多个,基本开发中的常见模块都包括了,这个配置是提前做好的,是标准化和最优化的,可以参考来学习。下面是部分片段的示例。
Initializers
org.springframework.context.ApplicationContextInitializer=
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,
org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer
Application Listeners
org.springframework.context.ApplicationListener=
org.springframework.boot.autoconfigure.BackgroundPreinitializer
Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
自动配置示例
下面看一下Spring Web的配置示例,是比较复杂的,但同时将本地环境和生产环境的情况都考虑了进去。可以称之为一种最佳实践。
@ConditionalOnWebApplication表示只有在web服务器才会加载。
并且没有定义Tomcat工厂类,且存在Tomcat.class和Servlet.class,就自动创建。
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@Configuration
@ConditionalOnWebApplication
@Import(BeanPostProcessorsRegistrar.class)
public class EmbeddedServletContainerAutoConfiguration {
/**
* Nested configuration if Tomcat is being used.
*/
@Configuration
@ConditionalOnClass({ Servlet.class, Tomcat.class })
@ConditionalOnMissingBean(value = EmbeddedServletContainerFactory.class, search = SearchStrategy.CURRENT)
public static class EmbeddedTomcat {
@Bean
public TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() {
return new TomcatEmbeddedServletContainerFactory();
}
}
}
小结
SpringBoot的核心思想简单来说就是不重复造轮子,主要针对原先在工程中比较繁琐的依赖和配置管理的工作,无侵入式的实现也非常符合Spring的传统哲学。
整个框架既不智能,也没有真正的自动化,但通过最佳实践的积累和框架的包装,提供了一种拿来即用的工作方式。易用性是框架生命力的重要来源,尤其对于初学者来说,会产生非常大的帮助。