@ConditionalOnProperty實作按需注入bean
短信工具類 SmsUtil
zhenghe-common是一個基礎包,
SmsUtil坐落在zhenghe-common里,先看看Smsutil的面目,
package com.emax.zhenghe.common.util; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; @Slf4j @Configuration public class SmsUtil { @Value("${smtp.config.username}") private String userName; @Value("${smtp.config.requestAddress}") private String requestAddress; @Value("${smtp.config.password}") private String passWord; @Value("${smtp.config.oem.username:oem}") private String oemUserName; @Value("${smtp.config.oem.password:oemsdfaaskdlkfk15673%!@4}") private String oemPassWord; /** * 發送短信 * @param phone 手機號 * @param msg 短信內容 * @return */ public String sendSMS(String phone, String msg) { StringBuilder sbParam = new StringBuilder(); StringBuilder url = new StringBuilder(); try { sbParam.append("?account=").append(userName); sbParam.append("&pwd=").append(URLEncoder.encode(passWord, "UTF-8")).append("&mphone=").append(phone).append("&content=") .append(URLEncoder.encode(msg, "UTF-8")); url.append(requestAddress) .append(sbParam.toString()); Integer result = HttpClientUtils.requestByGetMethod(url.toString()); return result.toString(); } catch (Exception e) { e.printStackTrace(); log.error("發送短信例外", e); } return "資訊發送成功!"; } /** * 發送短信 */ public String sendSMS(String phone, String msg,String userName,String passWord) { ... } /** * 發送短信 */ public String sendOemSMS(String phone, String msg, String smsSign) { StringBuilder smsSignBuilder = new StringBuilder(); smsSignBuilder.append("【") .append(smsSign) .append("】") .append(msg); return sendSMS(phone, smsSignBuilder.toString(), oemUserName, oemPassWord); } }
這里要說的是上面通過@Value注入的field,
存在的問題是:這要求所有依賴了zhenghe-common并掃描com.emax.zhenghe.common.util包的應用,都必須定義那些短信相關的properties配置,
需要改進的是:這些properties都以smtp.config開頭,所以使用spring-beans的@Value顯得啰嗦,不如使用spring-boot的@ConfigurationProperties,
先看問題-有的應用不涉及到收發短信,可以不用配置短信相關的這些properties,
解決辦法就是spring-boot-autoconfigure的@ConditionalOnProperty注解,
@ConditionalOnProperty注解是spring-boot-autoconfigure下“條件注入”的重要成員,根據配置引數,來決定是否需要創建bean,它主要是通過自身的兩個屬性來控制自動配置是否生效,這兩個屬性分別是name、havingValue,只有當組態檔(application.properties或者bootstrap.yml)中和name相同的屬性的值和注解上havingValue的值相同時,該組態檔才會生效,
敲黑板,@ConditionalOnProperty并不繼承@Configuration,它只是控制bean是否生效的,所以@Configuration注解還是需要加在SmsUtil頭上的,
如下是@ConditionalOnProperty的javadoc

仔細看javadoc,就能找到答案,這里,我們的改造方案是
@ConditionalOnProperty(prefix = "smtp.config",name = "requestAddress") |
下面方式也行,但是不如上面的易讀,
@ConditionalOnProperty( name = "smtp.config.requestAddress") |
@Configuration是spring-context-**.jar的成員,繼承@Component,

spring-context包里下面的這些注解,你一定知道,
+- context
| +- annotation
| | +- Bean
| | +- ComponentScan
| | +- Configuration
| | +- Import
| | +- Lazy
| | +- Primary
| | +- Profile
| | +- Scope
+- stereotype
| +- Service
| +- Component
| +- Controller
| +- Repository
而 @Value @Autowired 在 spring-beans-**.jar包里(package:org.springframework.beans.factory.annotation); @Mapping @PutMapping @ResponseBody @RestController etc., 在spring-web-**.jar包里(package:org.springframework.web.bind.annotation),
BTW,@Service 與 @Component 的區別
再說改進項:@ConfigurationProperties取代@Value
org.springframework.boot.context.properties.ConfigurationProperties在spring-boot-**.jar里,用法很easy,指定prefix即可,
需要指明的是,setter方法還是要有的,這里使用lombok的@Setter注解,
其中,oemUserName與property配置項的名稱不一致,需要單獨用@Value指定,并且value必須用全名 : @Value("${smtp.config.oemName:null}"),
改造后的SmsUtil
package com.emax.zhenghe.common.util; import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; @Slf4j //↓↓ 宣告bean @Configuration(value = "https://www.cnblogs.com/buguge/archive/2022/10/15/smsUtil") @ConditionalOnProperty(prefix = "smtp.config", name = "requestAddress") //↓↓ properties配置 @ConfigurationProperties(prefix = "smtp.config") @Setter//必須有setter才能為field賦上值 public class SmsUtil { private String userName; private String requestAddress; private String password; @Value("${smtp.config.oemName:null}") private String oemUserName; private String oemPassWord; /** * 發送短信 */ public String sendSMS(String phone, String msg) { ... } /** * 發送短信 */ public String sendSMS(String phone, String msg,String userName,String passWord) { ... } /** * 發送短信 */ public String sendOemSMS(String phone, String msg, String smsSign) { ... } }
當看到一些不好的代碼時,會發現我還算優秀;當看到優秀的代碼時,也才意識到持續學習的重要!--buguge
本文來自博客園,轉載請注明原文鏈接:https://www.cnblogs.com/buguge/p/16795409.html
<style>hr.signhr{width:80%;margin:0 auto;border: 0;height: 4px;background-image: linear-gradient(to right, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.75), rgba(0, 0, 0, 0))}</style>
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/514289.html
標籤:其他
上一篇:Hadoop安裝
