no9-springboot项目配置详解-条件注解-内嵌容器
分类: Java springboot 专栏: springboot学习 标签: 配置详解 条件注解 内嵌容器
2023-03-26 00:01:47 1152浏览
配置详解
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转换
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)展开评论

新业务
springboot学习
ssm框架课
vue学习
【带小白】java基础速成