SpringBoot 的学习整理

  1. 关于 @SpringBootApplication 的主程序入口
    Springboot 的程序入口类,即main方法执行的类是有一些需要注意的地方的,它的路径应当在
    所有代码的根目录下。springboot 启动时是从 入口main方法所在类的目录为根目录向上扫描的。
    如果main方法不在根目录则这个目录外的bean 不会被spring管理注入

2. 数据源配置

```
    @Order(Ordered.HIGHEST_PRECEDENCE) ①
    @Configuration ②
    @EnableTransactionManagement(proxyTargetClass = true) ③
    @EnableJpaRepositories(basePackages = "com.**.repository") ④
    @EntityScan(basePackages = "com.**.entity") ⑤
    public class JpaConfiguration {
        @Bean
        PersistenceAnnotationBeanPostProcessor persistenceAnnotationBeanPostProcessor() {
            return new PersistenceAnnotationBeanPostProcessor();
        }
    }
```
① 如果有多个数据源的时候这个标记就会起作用,数据源配置的优先级
② 标明这个类是一个configuration 类,在启动时会自动读取这里的配置
③ 开启事务管理
④ 配置 repository 的路径,如果不配置的话默认应该是根目录下的repository,对于分模块的情况最好进行配置 `"com.**.repository"` 这个配置会读取所有以com开头 repository 结尾的文件。
⑤ 配置entity 的路径

多数据源的配置:

```
    @Configuration
    public class DataSourceConfig {

        @Bean(name = "primaryDataSource") ①
        @Qualifier("primaryDataSource")
        @ConfigurationProperties(prefix="spring.datasource.primary") ②
        public DataSource primaryDataSource() {
            return DataSourceBuilder.create().build();
        }

        @Bean(name = "secondaryDataSource")
        @Qualifier("secondaryDataSource")
        @Primary  ③
        @ConfigurationProperties(prefix="spring.datasource.secondary")
        public DataSource secondaryDataSource() {
            return DataSourceBuilder.create().build();
        }

        @Bean(name = "primaryJdbcTemplate")
        public JdbcTemplate primaryJdbcTemplate(
                @Qualifier("primaryDataSource") DataSource dataSource) {
            return new JdbcTemplate(dataSource);
        }

        @Bean(name = "secondaryJdbcTemplate")
        public JdbcTemplate secondaryJdbcTemplate(
                @Qualifier("secondaryDataSource") DataSource dataSource) {
            return new JdbcTemplate(dataSource);
        }

    }
    //application.properties
    spring.datasource.primary.url=jdbc:mysql://localhost:3306/adp?characterEncoding\=UTF-8
    spring.datasource.primary.username=root
    spring.datasource.primary.password=root
    spring.datasource.primary.driverClassName=com.mysql.jdbc.Driver

    spring.datasource.secondary.url=jdbc:mysql://localhost:3306/adp1?characterEncoding\=UTF-8
    spring.datasource.secondary.username=root
    spring.datasource.secondary.password=root
    spring.datasource.secondary.driverClassName=com.mysql.jdbc.Driver
```

    ① 定义一个主数据源
    ② 读取我们在 application.yml(properties)中的配置数据源地址信息
    ③ 因为我们对一个DataSourceBuiler 创造了2个实现所以 需要用@primary 

    多数据源同样可以配置 repository 的包路径,可以给第一个数据源配置主数据源的repository地址和 entity
    同样也可以专门为第二个数据源配置专门的 repository和entity

    列举一个 主数据库配置
```

    @Configuration
    @EnableTransactionManagement
    @EnableJpaRepositories(
            entityManagerFactoryRef = "entityManagerFactoryPrimary",
            transactionManagerRef = "transactionManagerPrimary",
            basePackages = {"com"}) //设置Repository所在位置
    public class PrimaryConfig {

        @Autowired
        @Qualifier("primaryDataSource")
        private DataSource primaryDataSource;

        @Primary
        @Bean(name = "entityManagerPrimary")
        public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
            return entityManagerFactoryPrimary(builder).getObject().createEntityManager();
        }

        @Primary
        @Bean(name = "entityManagerFactoryPrimary")
        public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary(EntityManagerFactoryBuilder builder) {
            return builder
                    .dataSource(primaryDataSource)
                    .properties(getVendorProperties(primaryDataSource))
                    .packages("com") //设置实体类所在位置
                    .persistenceUnit("primaryPersistenceUnit")
                    .build();
        }

        @Autowired
        private JpaProperties jpaProperties;

        private Map<String, String> getVendorProperties(DataSource dataSource) {
            return jpaProperties.getHibernateProperties(dataSource);
        }

        @Primary
        @Bean(name = "transactionManagerPrimary")
        public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
            return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
        }

    }
```
  1. @ComponentScan注解。这个注解的作用类似于我们在spring的xml配置文件中的base-package的作用。
    在Applcation.上添加这个注解后,会自动所有子包,寻找含有@Repository、@Service、@Controller、
    @Component、@RestController、@Configuration注解的类,实现实例化和依赖注入等功能。
    对于一些依赖的第三方jar,由于这些类上并没有添加以上的这些注解,因此通过@ComponentScan无法直接获取其实例。
    例如我们再进行Mybatis与Spring整合的使用,使用到SqlSessionFactory,通过@ComponentScan无法获取其实例。
    对于这种情况, SpringBoot官方倾向于在一个添加@Configuration注解的类上,来获取需要依赖注入的Bean。
    不过结合目前的Spring使用情况来说,大部分公司都是XML+注解联合使用的。
    因此Spring也提供了另外一个注解@ImportResource,来导入xml格式的配置文件。

    所以入口类上最好加上这个注解

  2. 消失的web.xml 怎么办
    通常情况下很多 filter listener 之类的都是在web.xml 中配置的,springboot 把web.xml给省掉了。
    那我们想要手动加一些这样的东西该怎么办? springboot中提供了更简单的办法。

public class DemoFilter implements Filter{

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("==>DemoFilter启动");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        System.out.println("==>DemoFilter拦截请求");
        chain.doFilter(request, response);

    }

    @Override
    public void destroy() {

    }
}
过滤器只需要继承 Filter 即可
import x.servlet.ServletContextEvent;
import x.servlet.ServletContextListener;

public class DemoListener implements ServletContextListener{

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("==>DemoListener启动");

    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {

    }

}
监听器也是同样的

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter{
    @Bean
    public FilterRegistrationBean getDemoFilter(){
        DemoFilter demoFilter=new DemoFilter();
        FilterRegistrationBean registrationBean=new FilterRegistrationBean();
        registrationBean.setFilter(demoFilter);
        List<String> urlPatterns=new ArrayList<String>();
        urlPatterns.add("/*");//拦截路径,可以添加多个
        registrationBean.setUrlPatterns(urlPatterns);
        registrationBean.setOrder(1);
        return registrationBean;
    }

    @Bean
    public ServletListenerRegistrationBean<EventListener> getDemoListener(){
        ServletListenerRegistrationBean<EventListener> registrationBean
                                   =new ServletListenerRegistrationBean<>();
        registrationBean.setListener(new DemoListener());
//      registrationBean.setOrder(1);
        return registrationBean;
    }
}
最后再继承 WebMvcConfigurerAdapter 然后把这些东西加上
  1. 单元测试
    建议编写一个 base类

    @RunWith(SpringRunner.class) ①
    @SpringBootTest ②
    @Transactional ③
    class base //...

    ① 运行环境类
    ② SpringBootTest
    ③ 开启单元测试事务回滚
    
  2. 自带的定时任务

@Configuration@EnableScheduling // 启用定时任务 ②
public class CustomerStatusScheduling {
    private final SignRecordRepository signRecordRepository;

    private final SignRecordHistoryRepository signRecordHistoryRepository;

    @Autowiredpublic CustomerStatusScheduling(SignRecordRepository signRecordRepository, SignRecordHistoryRepository signRecordHistoryRepository) {
        this.signRecordRepository = signRecordRepository;
        this.signRecordHistoryRepository = signRecordHistoryRepository;
    }

    @Scheduled(cron ="0 0 0 1/1 * ?")  ④
    public void reSetCustomerStatus(){
        signRecordRepository.reSetCustomerStatus();
    }

}
① 这个标签就不用说了...
② 启动定时任务
③ 注入需要的bean (spring 高版本推荐使用这种构造器的方式来注入bean)
④ 定时任务类 在cron 写上 cron表达式即可开启定时任务
  1. 项目启动时自动执行方法

入口方法 实现 CommandLineRunner 接口
然后实现 它的 run 方法

public interface CommandLineRunner {
    void run(String... args) throws Exception;

}

接口源码 参数是 可变长数组String 参数

  1. 关于 spring data jpa 的一些东西

    基础的 findByXXXAndXXX 的规则就不说了

    1. 分页
      Pageable pageable = new PageRequest(page, num);
      创建一个 Page 对象

      repository 接口中定义如下方法
      Page findAll(Pageable pageable);
      返回的Page

      Page源码

         public interface Page<T> extends Slice<T> {
          int getTotalPages();
      
          long getTotalElements();
      
          <S> Page<S> map(Converter<? super T, ? extends S> converter);
         }
      
          public interface Slice<T> extends Iterable<T> {
              int getNumber();
              int getSize();
              int getNumberOfElements();
              List<T> getContent();
              boolean hasContent();
              Sort getSort();
              boolean isFirst();
              boolean isLast();
              boolean hasNext();
              boolean hasPrevious();
              Pageable nextPageable();
              Pageable previousPageable();
              <S> Slice<S> map(Converter<? super T, ? extends S> converter);
          }

      page 和 slice 接口里的方法足够我们大多数分页的应用场景

      获取本次分页查询数据结果 需要调用 getContent 方法 返回的是一个list的数据集

      map方法是提供数据转换的方法
      Spring jpa 提供了很多Coverter接口的实现

    2. findBy 关联对象
      在hibernate 中经常会有 一对多 多对一的映射关系(我们系统中没这么搞)

          public class SignRecordHistory {
              @Id
              @GeneratedValue
              private Long id;
              @ManyToOne(fetch = FetchType.EAGER)
              @JoinColumn(name = "customer")
              private Customer customer;
              @Column
              private Date signDate;
              @Column
              private String manager;

      比如 SignRecordHistory 中有多对一映射了 customer对象
      这时findBy 就需要用另一种格式来写

      List<SignRecordHistory> findBySignDateBetweenAndCustomer_delFlag
      (Date start, Date end, int delFlag);

      Customer_delFlag 就表示 查找 customer.delFlag
      多层结构就多个 ‘_’

  2. springboot 依赖管理

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    
    <properties>
        <kotlin.compiler.incremental>true</kotlin.compiler.incremental>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <kotlin.version>1.1.2</kotlin.version>
    </properties>
    

    spring boot 配置都在 parent里
    通过修改 properties 里的配置可以修改springboot 的依赖
    详见 spring-boot-starter-parent-xx.pom

    大多数第三方jar包都是由springboot来统一管理,这样的好处是避免了各类jar包的冲突
    这样做除了帮助对依赖有管理,其还有2个优点:

    如果之后想对依赖进行升级,只需修改spring-boot-starter-parent的版本即可,
    其管理的第三方依赖即可以完成自动化的一致性升级。
    帮助我们解决第三方框架由于版本不兼容而引发的冲突,稍微有点开发经验的朋友可能都有这样经历,
    常常因为项目中引入了框架的JAR包,但是由于它们互相之间版本不兼容而导致项目启动失败等问题,
    而现在这些版本之间管理都由Spring Boot来帮助我们完成,其互相之间出现冲突就基本上不复存在了。
    因此,Spring官方强烈建议用户在使用Spring Boot,不要再对已经定义好的Spring版本进行重写。

  3. @Autowired
    private Environment env;

    springboot在启动的时候会自动将 application.proeprties 装载到 Evnironment中
    获取 application.proeprties 中的配置项只需要
    env.getProperty(“jdbc.url”) 这样就可以

    或者使用 @Value 注解
    比如
    @Value(“${jdbc.driverClass}”)
    private String jdbcDriverClass;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
学习尚硅谷视频整理的文档 Spring Boot 1 1 Spring Boot入门 4 1.1 简介 4 1.2 微服务(martin fowler发表了一篇文章) 5 1.3 环境约束 7 1.4 第一个Spring Boot项目(jar):HelloWorld 8 1.5 入门案例详解 11 1.5.1 POM文件 11 1.5.2 主程序,主入口 12 1.6 使用Spring Initializer向导快速创建Spring Boot 16 2 Spring Boot配置 18 2.1 配置文件 18 2.2 YML语法 19 2.3 YML配置文件值获取 21 2.4 properties配置文件乱码问题 24 2.5 @ConfigurationProperties与@Value的区别 25 2.6 配置@PropertySource、@ImportResource、@Bean 27 2.7 配置文件占位符 30 2.8 Profile多环境支持 31 2.9 配置文件的加载位置 33 2.10 外部配置加载顺序 36 2.11 自动配置原理 37 2.12 @Conditional派生注解 41 3 Spring Boot与日志 42 3.1 日志框架分和选择 42 3.2 SLF4j使用 43 3.3 其他日志框架统一转换成slf4j+logback 44 3.4 Spring Boot日志使用 45 3.5 Spring Boot默认配置 47 3.6 指定日志文件和日志Profile功能 52 3.7 切换日志框架(不使用SLF4j+LogBack) 54 4 Spring Boot与Web开发 55 4.1 Web开发简介 55 4.2 静态资源映射规则 56 4.3 引入Thymeleaf 60 4.4 Thymeleaf语法 61 4.5 SpringMVC自动配置原理 67 4.6 SpringBoot扩展与全面接管 70 4.7 如何修改SpringBoot的默认配置 72 4.8 【实验】CRUD操作 73 4.8.1 默认访问首页 73 4.8.2 登录页面国际化 74 4.8.3 登录 80 4.8.4 拦截器进行登录检查 81 4.8.5 实验要求(没按要求做,不想改了!) 82 4.8.6 CRUD-员工列表 83 4.8.7 CRUD-员工修改 86 4.8.8 CRUD-员工添加 87 4.8.9 CRUD-员工删除 88 4.9 错误处理原理&错误页面定制 90 4.10 配置嵌入式Servlet容器(springboot 1.50版本) 97 4.10.1 如何定制和修改Servelt容器的相关配置 97 4.10.2 注册servlet三大组件【servlet,filter,listener】 98 4.10.3 替换为其他嵌入式容器 102 4.10.4 嵌入式servlet容器自动配置原理 103 4.10.5 嵌入式servlet容器启动原理 103 4.11 使用外置的Servlet容器 104 4.11.1 步骤 104 4.11.2 原理 107 5 Spring Boot与Docker(虚拟化容器技术) 110 5.1 简介 110 5.2 核心概念 111 5.3 安装Docker 112 5.4 Docker常用命令&操作 113 5.5 安装MySQL示例 114 6 Spring Boot与数据访问 115 6.1 JDBC 115 6.1.1 实现 115 6.1.2 自动配置原理 116 6.2 整合Durid数据源 117 6.3 整合Mybatis 122 6.3.1 注解版 123 6.3.2 配置文件版 124 6.4 整合SpringData JPA 125 6.4.1 SpringData简介 125 6.4.2 整合 126 7 Spring Boot启动配置原理 128 7.1 启动流程(Springboot 1.50版本) 128 7.1.1 创建SpringApplication对象 129 7.1.2 运行run方法 130 7.1.3 编写事件监听机制 132 8 Spring Boot自定义starters 136 8.1 概述 136 8.2 步骤 137 9 更多Springboot整合示例 144 10 Spring Boot与缓存 145 10.1 JSR107缓存规范 145 10.2 Spring的缓存抽象 146 10.2.1 基本概念 146 10.2.2 整合项目 146 10.2.3 CacheEnable注解 148 10.2.4 Cache注解 150 10.3 整合redis 154 10.3.1 在Docker上安装redis 154 10.3.2 Redis的Template 154 10.3.3 整合(百度) 155
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值