springboot @value取不到值_SpringBoot : 给初学者的实用配置指引

推荐阅读:

  • 面试败给微服务?别怕,我带你一起手撕Dubbo,SpringBoot与Cloud
  • 一个SpringBoot问题就干趴下了?我却凭着这份PDF文档吊打面试官.
  • Spring全家桶笔记:Spring+Spring Boot+Spring Cloud+Spring MVC

一 基本使用

367f403dcc30803afba120961bec54c7.png

1 pom.xml

SpringBoot可以通过parent或dependencyManagement两种方式引入。

1.1 parent方式

 org.springframework.boot spring-boot-starter-parent 2.1.10.RELEASE

因为很多时候我们需要引入自己项目的parent,所以这种引入方式不推荐。

1.2 dependencyManagement方式

 org.springframework.boot spring-boot-dependencies 2.1.10.RELEASEpomimport

dependencyManagement方式不干扰自己的项目结构,推荐这种方式引入。

2 代码

//@EnableAutoConfiguration // 启动自动配置//@ComponentScan //扫描目录//@Configuration // 配置bean@SpringBootApplicationpublic class SampleApp { public static void main(String[] args){ SpringApplication app = new SpringApplication(SampleApp.class); app.setBannerMode(Banner.Mode.OFF); // 关闭banner app.run(args); }}

或直接运行SpringApplication.run(SampleApp.class,args);也可以启动。

启动标注说明:

  • @EnableAutoConfiguration : 启用自动配置,可以指定exclude或excludeName进行指定或排除。 自动配置的模块可以参考:docs.spring.io/spring-boot…
  • @ComponentScan : 指定扫描目录,如果不指定basePackages,则从当前类所在的包开始扫描
  • @Configuration : 配置bean的类,标注了@Configuration的类中,可以用@Bean声明bean。
  • @SpringBootApplication = @EnableAutoConfiguration + @ComponentScan + @Configuration

二 声明Bean

声明bean有三种方式:

1 @Configuration & @Bean

在ComponentScan的basePackages目录(默认为当前类所在的包)中, 在类上标注@Configuration,使用@Bean标注方法来声明bean。

@Bean中不指定name时,方法名会被作为bean的id

@Configurationpublic class Services { @Bean public UserService userService(){ // Bean的id是userService return new UserService(); } @Bean(name = "userService2") // Bean的id是userService2 public UserService getUserService(){ return new UserService(); }}

对于不在ComponentScan包中的,可以使用 @Import 引入

@SpringBootApplication@Import({AnotherBeanConfiguration1.class, AnotherBeanConfiguration2.class})public class SampleApp{ }

2 @Service标注

在ComponentScan的包中,使用@Service标注类,bean的id默认是首字母小写的类名。可以通过@Service的value指定。

@Service //bean的id是userServicepublic class UserService {}

3 xml方式

用@ImportResource引入xml文件

@SpringBootApplication@ImportResource(locations = {"classpath:/spring/*.xml"})public class SampleApp{ }

三 属性文件

所有的系统属性可参考:docs.spring.io/spring-boot…

1 属性文件加载目录

如果不调用SpringApplication.setDefaultProperties,SpringBoot会从下面目录加载application.properties:

  • 1 当前目录下的/config
  • 2 当前目录
  • 3 classpath下的/config
  • 4 classpath根目录

引入额外的属性文件: 启动类上添加标注:@PropertySource(value = {"classpath:/config/jdbc.properties"})。

2 属性文件读取

2.1 使用 @Value

多用于取单个属性值,按照下面步骤可以将属性文件中的值读取到Bean的属性中:

  • application.properties设置:app.name=test.app
  • @Value("${app.name}") private String appName;

即可实现appName = "test.app"。

属性文件, YAML文件, 环境变量, 命令行参数中配置的值,都可通过@Value获取。

2.2 使用 @ConfigurationProperties

例如,在application.properties中设置:

test.compnayinfo.id=123 test.compnayinfo.name=testname

那么在代码中可以这样读取属性:

@Component@ConfigurationProperties(prefix = "test.compnayinfo") public class CompanyInfo{ private Integer id;  private String name;  // setters / getters }

通过指定ConfigurationProperties的prefix,CompanyInfo这个Bean的属性值,已被属性文件里的值初始化。

3 外部配置

docs.spring.io/spring-boot…

优先级如下:

  • 1.Command line arguments. 如 --server.port=9000
  • 2.Java System properties (System.getProperties()).
  • 3.OS environment variables.
  • 4.jar包外的 (application-{profile}.properties and YAML variants).
  • 5.jar包内的 (application-{profile}.properties and YAML variants).
  • 6.jar包外的 (application.properties and YAML variants).
  • 7.jar包内的 (application.properties and YAML variants).
  • 8.@PropertySource annotations on your @Configuration classes.
  • 9.Default properties (默认是application.properties,可以通过调用SpringApplication.setDefaultProperties指定).

4 其它

命令行指定属性文件目录: java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties

Profile-specific properties:

  • 1 application-{profile}.properties : 会覆盖application.properties的属性。
  • 2 application.properties中指定:spring.profiles.active=profileName,或 在代码中指定 SpringApplication.setAdditionalProfiles(...)

Placeholders: app.name=MyApp app.description=${app.name} xxxxxx

四 Servlet Filters

声明一个FilterRegistrationBean即可:

@Configurationpublic class Filters { @Bean public FilterRegistrationBean filterRegistrationBean1(){ FilterRegistrationBean bean = new FilterRegistrationBean(new Filter() { public void init(FilterConfig filterConfig) throws ServletException { System.out.println("init filterRegistrationBean1"); } public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { logger.info("doFilter filterRegistrationBean1"); filterChain.doFilter(servletRequest, servletResponse); } public void destroy() { } }); bean.setName("filterRegistrationBean1"); bean.setUrlPatterns(Collections.singletonList("/*")); bean.setOrder(2); return bean; }}

五 Spring拦截器

继承WebMvcConfigurerAdapter,并在覆盖的addInterceptors方法中,添加HandlerInterceptorAdapter对象即可。

@Configurationpublic class Interceptors extends WebMvcConfigurerAdapter { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new HandlerInterceptorAdapter() { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("first interceptor"); return super.preHandle(request, response, handler); } }); }}

六 https:

一般我们都是在nginx中启用https,不需要在java应用中启动。但如果需要,可以按照以下方式处理:

生成keystore:keytool -genkey -alias testkeystore -keystore keystore.jks -keyalg RSA

1 仅使用https(不使用http方式)

在属性文件中配置:

server.port=8443server.ssl.key-store=classpath:keystore.jksserver.ssl.key-store-password=secretserver.ssl.key-password=another-secret

2 新增https支持

需要新增一个支持https的connector, 参考: docs.spring.io/spring-boot…

@Configurationpublic class SampleTomcatTwoConnectorsService { @Bean public EmbeddedServletContainerFactory servletContainer() { TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory(); tomcat.addAdditionalTomcatConnectors(createSslConnector()); return tomcat; } private Connector createSslConnector() { Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol"); Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler(); try { File keystore = new ClassPathResource("test.keystore").getFile(); connector.setScheme("https"); connector.setSecure(true); connector.setPort(8443); protocol.setSSLEnabled(true); protocol.setKeystoreFile(keystore.getAbsolutePath()); protocol.setKeystorePass("111111"); protocol.setKeyAlias("testkeystore"); } catch (IOException ex) { ex.printStackTrace(); } return connector; }}

七 静态文件及freemarker

1 静态文件

如果目录为 resources/static: 则application.properties中配置: spring.mvc.static-path-pattern=/static/**

2 freemarker配置

默认的freemarker目录:resources/freemarker,ftl文件放到该目录下即可。

application.properties中 spring.freemarker.*的配置:

spring.freemarker.cache=truespring.freemarker.check-template-location=truespring.freemarker.content-type=text/htmlspring.freemarker.enabled=truespring.freemarker.settings.template_update_delay=0spring.freemarker.settings.default_encoding=UTF-8

八 几个有用的tips

1 PostConstruct

java.annotation.PostConstruct标注,Bean属性设置完之后调用,效果同InitializingBean.afterPropertiesSet。

2 PreDestroy:

java.annotation.PreDestroy标注,Bean销毁前调用,一般用于释放资源 。效果同DisposableBean.destroy。

3 Runtime.addShutdownHook

以下几种场景被调用:

1)程序正常结束退出

2)System.exit()

3)Ctrl+C

4)系统关闭

5)kill pid (kill -9 pid 不会调用hook)


作者:BoomShell
原文链接:https://juejin.im/post/5dc57668e51d452c227db6d8

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值