springboot基础
springboot解决两个问题
配置和依赖,按照习惯实现自动配置,因此也被成为脚手架,效率很快;
- 解决复杂的xml配置文件,无须XML配置了,使用JAVA配置类和注解实现所有配置;而且实现自动配置(项目启动时,就扫描自动配置的清单)
- 解决混乱的依赖 (版本问题冲突之类的),starter
spring的发展历程
1全xml,spring核心思想,控制反转和依赖注入
2 Xml和注解相结合, 之前已经把自己写的类都用注解了(@Component),但第三方的类不能注解,仍必须写在xml文件里。 一般而言,业务bean使用注解,基础配置使用xml
3 全用注解, 第三方的类通过配置类解决了,@Configuration, 而且把web.xml文件以及各种配置都通过配置类来进行了,
4 发挥到极致的就是springboot,会帮我们实现一个自动配置,按照习惯
springboot父工程
SpringBoot提供了一个名为spring-boot-starter-parent的工程,里面已经对各种常用依赖(并非全部)的版本进行了管理,我们的项目需要以这个项目为父工程;
这个父工程标志着现在是一个springboot工程了
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.2.RELEASE</version> </parent>
springboot启动器
配置启动器,即”自动配置”依赖(管理依赖的依赖) web项目所以引入的是web启动器 (springMVC相关依赖和配置类),玩springboot一定要有启动器,这是实现自动配置的基础。
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> //这个启动器依赖的版本不用写了, 因为父工程的存在 </dependency> </dependencies>
全局引导类
@RestController
@EnableAutoConfiguration 开启自动配置 开启自动配置的注解,springBoot根据依赖和这个bean自动完成了web及SpringMVC的默认配置了! 例如视图解析器,处理器映射器,处理器适配器等,原因:引入了相关依赖(启动器),默认配置就生效 public class HelloController { @GetMapping("show") public String test(){ return "hello Spring Boot! 你好世界";
}
public static void main(String[] args) { SpringApplication.run(HelloController.class, args); } }
问题:
当有多个controller时,每个controller中都配置自动配置的注解或者main方法,不行
一个springboot工程只有一个springboot的main方法, 监听8080端口(内置tomcat默认是8080,端口可以手动再配置)
写一个全局main,引导类,单独写一个 全局引导类 写在基包下,得在src目录下 TestApplication.class 放在比较浅的包目录中 //基包
@EnableAutoConfiguration 开启自动配置 @ComponentScan 以注解的方式开启扫描注解,扫描基包(这个类所在的包)下所有Controller, 必须要有,这是注解形式 <context:component-scan /> xml形式 可以加扫描范围 , 例(“com.panda.service”) public class TestApplication { public static void main(String[] args) { SpringApplication.run(TestApplication.class, args); //args可省略 } }
用@SpringbootApplication代替上面两个注解,@springbootApplication是一个组合注解,其实等价于下面三个注解
@SpringBootConfiguration : 声明当前类是SpringBoot应用的配置类, 之所以在上面没有添加,是因为项目中只有这一个作为应用的配置类
@EnableAutoConfiguration:开启自动配置
@ComponentScan:开启注解扫描,这个注解是扫描其他bean加载到spring,这个注解本身也是要在有@Configuration注解的配置类上使用
配置类
配置类,javaConfig是继xml配置方式和注解配置方式之后的再一次升级。将第三方类使用配置类方式进行配置,由此可以实现全配置,完全不再使用xml配置。
配置类使用的几个注解:
@Configuration 声明当前是一个配置类,代替xml文件的作用 SpringBootConfiguration声明的是全局配置,启动类/引导类,只有一个
@Bean 写在方法上,将方法的返回值放入bean容器(交给Spring IOC管理) 往往new一个对象(第三方类或者自己写的功能类,已经写好的)
@Value 属性注入;可以直接注入属性文件的值
@PropertySource 指定外部属性文件 // 配置类读取外部属性文件的属性信息,如果属性文件名字是application,可以省略
手动写一个配置类JdbcConfiguration,配置 JDBC数据源信息。
1、引入依赖,第三方类库 德鲁伊启动器
<dependency> <groupId>com.github.drtrang</groupId> <artifactId>druid-spring-boot2-starter</artifactId> <version>1.1.10</version> </dependency>
2、属性文件,jdbc.properies
jdbc.driverClassName=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://127.0.0.1:3306/datebase jdbc.username=root jdbc.password=123
3、创建配置类
@Configuration //声明是一个配置类 @PropertySource("classpath:jdbc.properties") //指定属性文件,只有指定了,下面的@value才能进行注入;如果application.properties,则不用PropertySource也可以注入 public class JdbcConfiguration { @Value("${jdbc.url}") String url; @Value("${jdbc.driverClassName}") String driverClassName; @Value("${jdbc.username}") String username; @Value("${jdbc.password}") String password; @Bean // 声明当前方法是一个注册bean的方法,将方法的返回值加入Spring容器,等价于bean标签的作用 public DataSource dataSource() { DruidDataSource dataSource = new DruidDataSource(); //引入相关依赖了 dataSource.setUrl(url); dataSource.setDriverClassName(driverClassName); dataSource.setUsername(username); dataSource.setPassword(password); return dataSource; } }
问题:
上面属性的注入是通过Vaule注解,不够强大,只能注入基本类型值,【可以使用字符串,el表达式】,可以通过 属性读取类 来进行属性注入 ,使用更安全和便于管理。
@ConfigurationProperties(prefix = "jdbc") 此处要求配置文件必须是application.properties,如果不是还得@PropertySource public class JdbcProperties { private String url; private String driverClassName; private String username; private String password; // ... 略 // getters 和 setters }
注意:属性资源配置文件要改名application,成默认 application.properties / application.yml
然后在配置类中使用这个属性类来给属性进行注入,直接装配这个属性配置类
@Configuration @EnableConfigurationProperties(JdbcProperties.class) //对使用 属性读取类 的声明 这个类可以写在启动类?这里就不用写了??? 因为JdbcProperties没有注册到bean,声明就是这个作用 public class JdbcConfiguration { @Autowired //将属性读取类对象注入 private JdbcProperties jdbcProperties; @Bean public DataSource dataSource() { DruidDataSource dataSource = new DruidDataSource(); dataSource.setUrl(jdbcProperties.getUrl()); dataSource.setDriverClassName(jdbcProperties.getDriverClassName()); dataSource.setUsername(jdbcProperties.getUsername()); dataSource.setPassword(jdbcProperties.getPassword()); return dataSource; } }
注意:
1)@EnableConfigurationProperties(JdbcProperties.class) ,因为JdbcProperties这个属性配置类本身没注册到spring,所以在此需要进行声明才能实现注入;如果JdbcProperties已经注册到spring,将不需要这个注解;
2)因为JdbcProperties注册到spring,在bean配置方法中,可以直接作为方法参数注入,如下:
@Bean public DataSource dataSource(JdbcProperties jdbcProperties) { //一般这种写法,是类型参数,已经是一个bean,因此可以作为bean的方法参数使用 // ... }
自动配置/默认配置
默认配置 也是通过上面java配置类【就是原始的xml配置文件】的形式进行了默认的配置,自动实现类的注册,不用自己写配置类,都写好了,而且是按照常用习惯,在引入的依赖中,已经引入了一个依赖:spring-boot-autoconfigure,其中有大量的自动配置类,涵盖了主流框架
定义了许多自动配置类, 当开启@EnableAutoConfiguration就会自动配置这些配置类(中的类/对象) 交给Spring容器 //EnableAutoConfiguration 是springboot自动配置的核心
这些配置类上除了有声明当前是一个配置类的注解外,还有一些什么时候使用这些配置类的条件注解,因此做到了有效配置(何种情况下进行自动配置,是否引入了相关依赖,是否进行了属性项的配置);自动配置类,可看做条件注解+配置类注解
当不想使用默认配置,而当去自定义配置类,默认配置类就会失效
自动配置实现的默认配置,通过配置类和属性配置类实现,【类里面有相关的需要被配置到Spring的Bean类/对象 (通过@Bean方法下的返回值对象) 】
默认配置的属性 也是来自属性类 @configurationProperties(prefix=””),属性类定义了默认的属性(如果不想使用这些默认属性值,可以在application.properties中进行修改和覆盖)
@SpringBootApplication public class BootApplication { public static void main(String[] args) { SpringApplication.run(BootApplication.class, args); } }
@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
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import({AutoConfigurationImportSelector.class}) //会去扫描spring.factories清单,里面是所有可以自动配置的清单,可以自定义starter,加进去
public @interface EnableAutoConfiguration {