no9-springboot项目配置详解-条件注解-内嵌容器
分类: 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转换
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)展开评论