SpringBoot一览

spring-boot入门

了解SpringBoot

为什么学习SpringBoot

java一直被人诟病的一点就是臃肿、麻烦。当我们还在辛苦的搭建项目时,可能Python程序员已经把功能写好了,究其原因注意是两点:

  • 复杂的配置,
    项目各种配置其实是开发时的损耗, 因为在思考 Spring 特性配置和解决业务问题之间需要进行思维切换,所以写配置挤占了写应用程序逻辑的时间。
  • 一个是混乱的依赖管理。
    项目的依赖管理也是件吃力不讨好的事情。决定项目里要用哪些库就已经够让人头痛的了,你还要知道这些库的哪个版本和其他库不会有冲突,这难题实在太棘手。并且,依赖管理也是一种损耗,添加依赖不是写应用程序代码。一旦选错了依赖的版本,随之而来的不兼容问题毫无疑问会是生产力杀手。

SpringBoot的特点

Spring Boot 主要目标是:

  • 为所有 Spring 的开发者提供一个非常快速的、广泛接受的入门体验
  • 开箱即用(启动器starter-其实就是SpringBoot提供的一个jar包),但通过自己设置参数(.properties),即可快速摆脱这种方式。
  • 提供了一些大型项目中常见的非功能性特性,如内嵌服务器、安全、指标,健康检测、外部化配置等
  • 绝对没有代码生成,也无需 XML 配置。

快速入门

建立Maven工程

添加依赖

SpringBoot提供了一个名为spring-boot-starter-parent的工程,里面已经对各种常用依赖(并非全部)的版本进行了管理,
我们的项目需要以这个项目为父工程,这样我们就不用操心依赖的版本问题了,需要什么依赖,直接引入坐标即可!

添加父工程坐标

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.0.RELEASE</version>
</parent>

添加Web启动器

为了让SpringBoot帮我们完成各种自动配置,
我们必须引入SpringBoot提供的自动配置依赖,我们称为启动器。因为我们是web项目,这里我们引入web启动器

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

管理JDK版本

默认情况下,maven工程的jdk版本是1.5,而我们开发使用的是1.8,因此这里我们需要修改jdk版本,只需要简单的添加以下属性即可

<properties>
    <java.version>1.8</java.version>
</properties>

启动类

@SpringBootApplication
public class org.ranger.Application {
    public static void main(String[] args) {
        SpringApplication.run(org.ranger.Application.class, args);
    }
}

添加Controller

@Controller
public class IndexController {
    @ResponseBody
    @RequestMapping("/hello")
    public Object hello(){
        return "hello,spring boot~!";
    }

    @ResponseBody
    @RequestMapping("/index")
    public String index(){
        return "index";
    }
}

Java配置

回顾历史

在以前我们配置一个bean该怎么做呢?

在xml配置文件中添加标签,例如配置数据库连接池

<!-- 配置连接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
      init-method="init" destroy-method="close">
    <property name="url" value="${jdbc.url}" />
    <property name="username" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />
</bean>

使用Java配置

Java配置主要是使用Java注解和类

  • @Configuration:声明一个类作为配置类,代替xml文件
  • @Bean:声明在方法上,根据方法的返回值加入Bean容器,代替<bean/>标签
  • @Value:属性注入
  • PropertySource:指定外部属性文件

我们使用Java配置来配置数据库连接池,首先引入连接池依赖

 <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.9</version>
        </dependency>

创建配置文件类

@PropertySource("jdbc.properties")
@Configuration
public class JDBCConfig {
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.driverClassName}")
    private String driverClassName;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;
    private String url1;

    @Bean
    public DataSource dataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(url1);
        dataSource.setDriverClassName(driverClassName);
        dataSource.setUsername(username);
        dataSource.setPassword(password);

        return dataSource;
    }
}

SpringBoot的属性注入

上面我们使用了@Value注解来注入属性,这种方式可行但不能注入复杂的类型

SpringBoot中提供了另外一种属性注入的方式,这种方式既可以注入基本数据类型也可注入复杂数据类型

使用@ConfigurationProperties(prefix="jdbc")

application.yml中配置相应的属性值:

jdbc:
  url: jdbc:mysql://127.0.0.1:3306/leyou
  driverClassName: com.mysql.jdbc.Driver
  username: cyp
  password: cyp
@ConfigurationProperties(prefix = "jdbc")
public class JDBCProperties {
    private String url;
    private String driverClassName;
    private String username;
    private String password;

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getDriverClassName() {
        return driverClassName;
    }

    public void setDriverClassName(String driverClassName) {
        this.driverClassName = driverClassName;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

使用:通过@EnableConfigurationProperties(JdbcProperties.class)来声明要使用JdbcProperties这个类的对象

可以使用以下方式注入JDBCProperties对象

  • @Autowired注入

    @Autowired
    private JdbcProperties prop;
  • 构造函数注入

    private JdbcProperties prop;
    public JdbcConfig(Jdbcproperties prop){
        this.prop = prop;
    }
  • 声明有@Bean的方法参数注入

    @Bean
    public Datasource dataSource(JdbcProperties prop){
       // TODO
    }

    本例中,我们采用第三种方式。

@Configuration
@EnableConfigurationProperties(JDBCProperties.class)
public class JDBCConfig {
    @Bean
    public DataSource dataSource(JDBCProperties jdbc){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(jdbc.getUrl());
        System.out.println(jdbc.getUrl());
        dataSource.setDriverClassName(jdbc.getDriverClassName());
        dataSource.setUsername(jdbc.getUsername());
        dataSource.setPassword(jdbc.getPassword());

        return dataSource;
    }
}

自动配置原理

使用了 SpringBoot之后,以前很多繁琐的配置文件都不需要我们自己写了,这是怎么做到的呢,这一切都依赖于SpringBoot的自动配置

SpringBoot应用是从main方法开始的,main方法所在的类有一个@SpringBootApplication注解。

@SpringBootApplication

查看该注解的源码

@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个:

  • @SpringBootConfiguration
  • @EnableAutoConfiguration
  • ComponentScan

@SpringBootConfiguration

查看这个注解的源码

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {

}

通过这段我们可以看出,在这个注解上面,又有一个@Configuration注解。通过上面的注释阅读我们知道:
这个注解的作用就是声明当前类是一个配置类,然后Spring会自动扫描到添加了@Configuration的类,并且读取其中的配置信息。
而@SpringBootConfiguration是来声明当前类是SpringBoot应用的配置类,项目中只能有一个。所以一般我们无需自己添加。

@EnableAutoConfiguration

SpringBoot内部对大量的第三方库或Spring内部库进行了默认配置,这些配置是否生效,取决于我们是否引入了对应库所需的依赖,如果有那么默认配置就会生效。

@ComponentScan

/**
 * Configures component scanning directives for use with @{@link Configuration} classes.
 * Provides support parallel with Spring XML's {@code <context:component-scan>} element.
 *
 * <p>Either {@link #basePackageClasses} or {@link #basePackages} (or its alias
 * {@link #value}) may be specified to define specific packages to scan. If specific
 * packages are not defined, scanning will occur from the package of the
 * class that declares this annotation.
 *
 * <p>Note that the {@code <context:component-scan>} element has an
 * {@code annotation-config} attribute; however, this annotation does not. This is because
 * in almost all cases when using {@code @ComponentScan}, default annotation config
 * processing (e.g. processing {@code @Autowired} and friends) is assumed. Furthermore,
 * when using {@link AnnotationConfigApplicationContext}, annotation config processors are
 * always registered, meaning that any attempt to disable them at the
 * {@code @ComponentScan} level would be ignored.
 *
 * <p>See {@link Configuration @Configuration}'s Javadoc for usage examples.
 *
 * @author Chris Beams
 * @author Juergen Hoeller
 * @author Sam Brannen
 * @since 3.1
 * @see Configuration
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {

大概的意思:

配置组件扫描的指令。提供了类似与 标签的作用
通过basePackageClasses或者basePackages属性来指定要扫描的包。如果没有指定这些属性,那么将从声明这个注解的类所在的包开始,扫描包及子包

而我们的@SpringBootApplication注解声明的类就是main函数所在的启动类,因此扫描的包是该类所在包及其子包。因此,一般启动类会放在一个比较前的包目录中。

默认配置原理

通过刚才的学习,我们知道@EnableAutoConfiguration会开启SpringBoot的自动配置,并且根据你引入的依赖来生效对应的默认配置。那么问题来了:

  • 这些默认配置是在哪里定义的呢?
  • 为何依赖引入就会触发配置呢?

其实在我们的项目中,已经引入了一个依赖:spring-boot-autoconfigure,其中定义了大量自动配置类

这里面几乎涵盖了所有的主流框架

SpringBoot为我们提供了默认配置,而默认配置生效的条件一般有两个:

  • 你引入了相关依赖
  • 你自己没有配置

1)启动器

所以,我们如果不想配置,只需要引入依赖即可,而依赖版本我们也不用操心,因为只要引入了SpringBoot提供的stater(启动器),就会自动管理依赖及版本了。

2)全局配置

另外,SpringBoot的默认配置,都会读取默认属性,而这些属性可以通过自定义application.properties文件来进行覆盖。这样虽然使用的还是默认配置,但是配置中的值改成了我们自定义的。

实践:加密数据库密码

引入依赖

<dependency>
    <groupId>com.github.ulisesbocchio</groupId>
    <artifactId>jasypt-spring-boot-starter</artifactId>
    <version>1.16</version>
</dependency>

配置加密密钥
jasypt.encryptor.password=ranger

获取加密后的数据

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = Application.class)
public class EncryptTest {
    @Autowired
    StringEncryptor encryptor;

    @Test
    public void encry(){
        //加密username
        String username = encryptor.encrypt("cyp");
        System.out.println(username);
        //加密password
        String password = encryptor.encrypt("cyp");
        System.out.println(password);


    }
}

配置文件中配置

猜你喜欢

转载自www.cnblogs.com/watertreestar/p/11780267.html