可以理解为spring-boot是为了快速构建spring项目的一种框架。比如普通的开发spring-mvc项目,正常的话需要在web.xml配置dispach-servlet,需要在我们的xml文件中配置视图解析器、配置handlermapping和handleradapter解析器、定义扫描包目录、配置事务管理器等。另外还需要配置tomcat服务器,通过maven或者手动将war包打包至tomcat服务器。而spring-boot根据约定大于配置原则,只需要简单的几步,就可以完成一个简单的spring-mvc项目的配置与实现。(很多无需特别关注的配置都使用默认实现,spring-boot都给我们配置好了)。
一个正常的spring-boot启动项目,其入口程序如下:
@RestController
@SpringBootApplication
@MapperScan("com.example.mybatis2.dao")
public class Mybatis2Application {
public static void main(String[] args)
{
SpringApplication.run(Mybatis2Application.class, args);
}
}
其中要关注的就是@springbootapplication这个注解,通过这个注解完成。
这个注解其实是@ComponentScan,@SpringBootConfiguration,@EnableAutoConfiguration三个注解的集合。其中,@ComponentScan是扫描指定的包,将包内的bean注入到ioc容器中。
而@SpringBootConfiguration的真正实现是@Configuration
在spring中,既可以通过xml将定义bean,并注入ioc容器中,也可以通过java代码实现bean注入。在下面代码中
@SpringBootApplication
@MapperScan("com.example.mybatis2.dao")
public class Mybatis2Application {
public static void main(String[] args)
{
SpringApplication.run(Mybatis2Application.class, args);
}
@RequestMapping("/")
public String index(){
return "Hello Spring Boot2222";
}
@RequestMapping("/test")
public String test(){
return "Hello Spring test";
}
@Autowired
private Environment env;
//destroy-method="close"的作用是当数据库连接不使用的时候,就把该连接重新放到数据池中,方便下次使用调用.
@Bean(destroyMethod = "close")
public DataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl(env.getProperty("spring.datasource.url"));
dataSource.setUsername(env.getProperty("spring.datasource.username"));//用户名
dataSource.setPassword(env.getProperty("spring.datasource.password"));//密码
dataSource.setDriverClassName(env.getProperty("spring.datasource.driver-class-name"));
dataSource.setInitialSize(2);//初始化时建立物理连接的个数
dataSource.setMaxActive(20);//最大连接池数量
dataSource.setMinIdle(0);//最小连接池数量
dataSource.setMaxWait(60000);//获取连接时最大等待时间,单位毫秒。
dataSource.setValidationQuery("SELECT 1");//用来检测连接是否有效的sql
dataSource.setTestOnBorrow(false);//申请连接时执行validationQuery检测连接是否有效
dataSource.setTestWhileIdle(true);//建议配置为true,不影响性能,并且保证安全性。
dataSource.setPoolPreparedStatements(false);//是否缓存preparedStatement,也就是PSCache
return dataSource;
}
@Bean
@ConfigurationProperties(prefix = "com.example.demo")
public People people() {
return new People();
}
}
可以把上述的被@SpringBootApplication注解的类(当然也就是被@Configuration注解),表明这个类是一个javaconfig配置类,其可以替代xml文件。在类里通过@Bean注解,可以将bean注入ioc容器。比如上面的people实例。
最重要的@EnableAutoConfiguration是实现spring-boot的关键。其思想类似于java的spi。通过规定的位置找到spring.factories文件,找到其对应的org.springframework.boot.autoconfigure.EnableAutoConfiguration键所对应的值(是各种自动配置类的数组组合)
# 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.CloudServiceConnectorsAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,\
org.springframework.boot.autoconfigure.elasticsearch.jest.JestAutoConfiguration,\
org.springframework.boot.autoconfigure.elasticsearch.rest.RestClientAutoConfiguration,\
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\
org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\
org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,\
org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration,\
org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration,\
org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration,\
org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration,\
org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration,\
org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,\
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,\
...
根据这个类的文件路径,找到对象的类,通过反射进行实例化,从而将自动配置的对象注入到spring容器。
参考https://www.jianshu.com/p/464d04c36fb1
spring-boot-devtools为应用提供一些开发时特性,包括默认值设置,自动重启,在dependency中添加:
org.springframework.boot
spring-boot-devtools
true
其中,重点关注一下optional这个标签。在dependency中,optional标签标示
当project-A 依赖project-B, project-B 依赖project-D时,官方文档解释:
What if we dont want project D and its dependencies to be added to Project A’s classpath because we know some of Project-D’s dependencies (maybe Project-E for example) was missing from the repository, and you don’t need/want the functionality in Project-B that depends on Project-D anyway. In this case, Project-B’s developers could provide a dependency on Project-D that is true, like this:
sample.ProjectD
ProjectD
1.0-SNAPSHOT
true
在ide中修改完后,通过ctrl+f9进行build后,可自动完成热部署。
自动重启的原理在于spring boot使用两个classloader:不改变的类(如第三方jar)由base类加载器加载,正在开发的类由restart类加载器加载。应用重启时,restart类加载器被扔掉重建,而base类加载器不变,这种方法意味着应用程序重新启动通常比“冷启动”快得多,因为base类加载器已经可用并已填充。
所以,当我们开启devtools后,classpath中的文件变化会导致应用自动重启。