no9-springboot项目配置详解-条件注解-内嵌容器

飞一样的编程
飞一样的编程
擅长邻域:Java,MySQL,Linux,nginx,springboot,mongodb,微信小程序,vue

分类: Java springboot 专栏: springboot学习 标签: 配置详解 条件注解 内嵌容器

2023-03-26 00:01:47 560浏览

配置详解,条件注解,内嵌容器

配置详解

application.properties存放位置优先级

application.properties配置文件一 共可以出现在如下4个位置

1项目根目录下的config文件夹中(注意是工程的根目录下,不是模块的根目录下)

2.项目根目录下(注意是工程的根目录下,不是模块的根目录下)

3.classpath下的config文件夹中

4.classpath下

如果4个地方都存在配置文件,会取四个文件的并集,

如果配置出现冲突(出现相同的key),则优先级高的会覆盖优先级低的。

加载的优先级从1到4依次降低

配置文件分类

  • properties和yml的优先级(properties的优先级高)
  • bootstrap.properties

这个优先级更高,但在单纯的springboot项目里是不起效果的,后面讲到sprngcloud分布式项目的时候这个有用。

SpringBoot项目中bootstrap.properties为什么不生效,解决方案:

从配置文件中获取值

@ConfigurationProperties

  • 1.可以批量的将配置文件中的内容注入到对象中,支持松散绑定。
@Component
@Data
@ConfigurationProperties(prefix = "book")
public class Book {

    private String name;
    private String author;
}
book.name=三国演义
book.author=罗贯中
@SpringBootTest
public class BookTest {
    @Autowired
    Book book;

    @Test
    void testBook(){
        System.out.println(book);
    }
}
  • 2.使用@ConfigurationProperties和@Bean注解在配置类的Bean定义方法上
jfit.spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
jfit.spring.datasource.jdbcUrl=jdbc:mysql:///assay?serverTimezone=Asia/Shanghai
jfit.spring.datasource.username=root
jfit.spring.datasource.password=123456
@Configuration
public class DataSourceConfig {

    @Bean
    @ConfigurationProperties(prefix = "jfit.spring.datasource")
    DataSource dataSource(){
        return DataSourceBuilder.create().build();
    }

}

这里便是将前缀为“jfit.spring.datasource"的属性,赋值给DataSource对应的属性值。

@Configuration注解的配置类中通过@Bean注解在某个方法上将方法返回的对象定义为一个Bean,并使用配置文件中相应的属性初始化该Bean的属性。

  • 3.使用@ConfigurationProperties注解到普通类,然后再通过@EnableConfigurationProperties定义为Bean。
@Data
@ConfigurationProperties(prefix = "book")
public class Book {

    private String name;
    private String author;
}
@SpringBootApplication
@EnableConfigurationProperties(Book.class)
public class Ch501Application {

    public static void main(String[] args) {
        SpringApplication.run(Ch501Application.class, args);
    }

}
//用的时候直接依赖注入即可
@Autowired
Book book;

@Value

不支持松散绑定,支持spel表达式

@Component
@Data
public class Book {

    @Value("${book.name}")
    private String name;
    @Value("${book.author}")
    private String author;
}
@Component
@Data
public class TestEntity {
    @Value("#{systemProperties['os.name'] }")
    private String osString;//注入操作系统属性
    @Value("#{ T(java.lang.Math).random() * 100.0 }")
    private Double randomNumber;

    //注入其他bean的属性
    @Value("#{book.name}")
    private String bookname;
    //注入url资源  org.springframework.core.io.Resource
    @Value("https://www.baidu.com")
    private Resource testUrl;
}

简单类型、对象类型、对象集合、数组类型、map等分别用yml和properties两种写

@Data
@Component
@ConfigurationProperties("jf3q")
public class TestYml {
    private Book book;
    private List<Book> books;
    private String[] strs;
    private Map<String,Object> maps;
}
jf3q:
  book:
    name: 水浒传
    author: 施耐庵
  books:
    - name: 西游记
      author: xxx
    - name: 红楼梦
      author: yyyy
#  strs: ['aaa','bbb']
  strs:
    - 'aaa'
    - 'bbb'
#  maps: {'account': z3, 'realname': 张三}
  maps:
    'account': ls
    'realname': 李四

单引号问题

在yml配置文件中单引号会转义,双引号不会转义,在properties里没区别

yml和properties转换

https://toyaml.com/index.html

SpringBoot 配置切换

spring.profiles.active

@Conditional条件注解

用于条件启用或者禁用@Configuration类或者@Bean方法,例如:把默认数据源HikariDataSource换成Druid,那么默认的数据源HikariDataSource对应的bean就不能再配置,否则会出现两个数据源,因而某些bean是否需要注册到spring容器是有 条件的。

需求:根据当前操作系统返回列举文件夹的命令

Windows:dir

linux:ls

需要把什么条件下注册哪个listService表达给spring。

解决方法:

Windows下的条件类实现Condition接口:如果是在Windows下就返回true,否则返回false

public class WindowsConditional implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {

        //把条件表达写在这

        return  context.getEnvironment().getProperty("os.name").toLowerCase().contains("windows");
    }
}

同理Linux的条件类

public class LinuxConditional implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {

        //把条件表达写在这

        return  context.getEnvironment().getProperty("os.name").toLowerCase().contains("linux");
    }
}

修改配置类(采用配置类的方式注入bean,把之前的@service去掉)

@Configuration
public class AppConfig {

    @Bean
    @Conditional(WindowsConditional.class)
    public ListService windowsListService(){
        return  new WindowsListServiceImpl();
    }
    @Bean
    @Conditional(LinuxConditional.class)
    public ListService linuxListService(){
        return  new LinuxListServiceImpl();
    }
}

使用@Conditional注解常用注解

@ConditionalOnBean: 系统的ioc容器里如果存在某个bean的情况下才会实例化这个bean

@ConditionalOnClass: 系统中如果存在某个类的情况下,才会实例化一个Bean.

@ConditionalOnExpression: 当表达式为true的时候, 才会实例化一个Bean.

@ConditionalOnMissingBean: 系统的ioc容器里如果不存在某个bean的情况下才会实例化这个bean

@ConditionalOnMissingClass: 系统中如果不存在某个类的情况下,才会实例化一个Bean.

@ConditionalOnNotWebApplication: 不是web应用,才会实例化一个Bean。

@ConditionalOnBean: 当容器中有指定Bean的条件下进行实例化。

@ConditionalohMissingBean: 当容器里没有指定Bean的条件下进行实例化。

@ConditionalOnClass: 当classpath类路径下有指定类的条件下进行实例化。

@ConditionalOnMissingClass: 当类路径下没有指定类的条件下进行实例化。

@ConditionalOnWebApplication: 当项目是一个Web项目时进行实例化。

@ConditionalOnNotWebApplication: 当项目不是一个Web项目时进行实例化。

@ConditionalOnProperty:当指定的属性有指定的值时进行实例化。

@ConditionalOnExpression:基于SpEL表达式的条件判断。

@Condit ionalOnJava:当JVM版本为指定的版本范围时触发实例化。

@ConditionalOnResource:当类路径下有指定的资源时触发实例化。

@ConditionalOnJndi:在JNDI存在的条件下触发实例化。

自定义错误页

  • 静态错误页:

  • 动态错误页

全局异常啥的后面做项目的时候讲

boot项目里导入xml配置文件

beans.xml

  <bean class="com.bdqn.ch501.entity.UserInfo">
        <property name="username" value="xiaojie"/>
        <property name="realname" value="张三"/>

    </bean>
@Configuration
@ImportResource("classpath:beans.xml")
public class Beans {
}
 @Resource
    UserInfo userInfo;
    @Test
    void testUser(){
        System.out.println(userInfo);
    }

内置web容器原理

假设之前的ssm项目也采用内嵌的tomcat怎么玩

  • 1.先添加依赖
        <!--提供tomcat核心功能-->
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-core</artifactId>
            <version>8.5.87</version>
        </dependency>
        <!--提供jsp翻译编译等功能-->
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
            <version>8.5.87</version>
        </dependency>
  • 2.写启动类
package com.jf3q.controller;

import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.startup.Tomcat;
import org.springframework.web.servlet.DispatcherServlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class App {
    public static void main(String[] args) {
        Tomcat tomcat= new Tomcat();
        //修改默认端口
        tomcat.setPort(9999);
        //设置应用的根目录
        tomcat.getHost().setAppBase(System.getProperty("user.dir")+"/.");
        /**
         * 添加一个webapp应用到服务器
         * contextPath:用于上下文映射
         * docBase:上下文的根目录
         */
        Context context = tomcat.addWebapp("/","F:\\工作\\springboot_study\\ch5-2\\src\\main\\webapp");
        //编程方式添加一个Servlet
        Tomcat.addServlet(context, "helloWord", new HttpServlet() {
            @Override
            protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                resp.getWriter().println("hello word");
            }
        });

        context.addServletMappingDecoded("/hello", "helloWord");
        try {
            tomcat.start();
            tomcat.getServer().await();//防止程序立即结束
        } catch (LifecycleException e) {
            e.printStackTrace();
        }

    }
}

注意:springmvc配置文件和web.xml该怎么写还是怎么写。

好博客就要一起分享哦!分享海报

此处可发布评论

评论(3展开评论

维也纳达芬奇 能力:10

2023-03-30 10:11:51

6
就一傻蛋 能力:10

2023-03-30 09:41:58

6666
蓝色妖姬 能力:10

2023-03-28 11:38:14

蓝色妖姬你不爱,非要在渣男身上找存在
点击查看更多评论

展开评论

您可能感兴趣的博客

客服QQ 1913284695