Google Code Prettify

2017年7月27日 星期四

變更 property 檔裡的設定值

Java 的程式設定習慣放在 property 檔,這些檔會放置在 classpath 的某處,大部份時候程式都只需要讀取檔案裡的資料,要變更資料是人工變更,但是,萬一程式想變更怎麼辦? 底下式可以辦到 …

紅色部份比較常見,就是讀入 application.properties 裡的資料到 prop 裡,綠色部份是變更想變更的值後在存回去。
Properties prop = new Properties();

URL url = this.getClass().getClassLoader().getResource("application.properties");
URI uri = url.toURI();
File file = new File(uri);
   
InputStream is = new FileInputStream(file);
prop.load(is);
is.close();
   
FileOutputStream os = new FileOutputStream(file);
prop.setProperty("myKey", myValue);
prop.store(os, null);
os.close();
上面這樣就搞定了嗎? 通常應該沒有這麼好過 … Orz...
因為程式中如果有用到這個 property 檔的相關變數應該也要被更新,在 spring framework 中,載入 property 檔,是在 @Configuration 所在的類別再增加如下註釋。
@PropertySource("classpath:application.properties")
在需要使用裡面的設定的類別裡如下載入。
@Value("${myKey}")
private String myValue;
因為我們已經將 property 檔委由 spring framework 管理,要重新載入,就要從 spring 的環境著手。
@Inject
private StandardEnvironment environment;
...
MutablePropertySources propertySources = environment.getPropertySources();
PropertySource resourcePropertySource = propertySources.get("class path resource [application.properties]");
        
URL url = this.getClass().getClassLoader().getResource("application.properties");
URI uri = url.toURI();
File file = new File(uri);
  
InputStream is = new FileInputStream(file);
Properties prop = new Properties();
prop.load(is);
is.close();
        
propertySources.replace("class path resource [application.properties]", new PropertiesPropertySource("class path resource [application.properties]", prop));




2017年7月23日 星期日

Spring Application Event

spring framework 的 bean 一般熟知的就是 IoC 的依賴注入 (dependency injection),這裡介紹一個較少用到的功能,bean 與 bean 之前傳遞事件! 既然是談到事件,最好就先了解一下 Observer Pattern,spring framework 實作了這個 pattern,讓程式中有兩個 bean,當 bean A 狀態有變化時,可以通知 bean B,說明如下:
  • Event
 1 @Data
 2 public class MyBeanEvent extends ApplicationEvent {
 3     private String msg;
 4 
 5     public MyBeanEvent(Object source) {
 6         super(source);
 7         
 8         this.msg = (String) source;
 9     }
10 }
首先定義一個事件類別,這個類別需繼承 ApplicationEvent 類別,我們自己定義的事件類別需有建構子 (constructor),即程式中 5 ~ 9 行,我們將傳遞過來的物件存入變數 msg 裡。
  • Publisher
1 @Component
2 public class MyPublisher {
3     @Inject
4     private ApplicationContext context;
5     
6     public void publish(String msg) {
7         context.publishEvent(new MyBeanEvent(msg));
8     }
9 }
發佈訊息的類別如上,使用 spring 的 ApplicationContext 的 publishEvent method 即可發佈出訊息物件,所有的傾聽者 bean 就會收到訊息物件。
  • Listener
1 @Component
2 public class MyListener implements ApplicationListener<MyBeanEvent> {
3 
4     @Override
5     public void onApplicationEvent(MyBeanEvent event) {
6         System.out.println("listen: " + event.getMsg());
7     }
8 }
傾聽類別要實作 ApplicationListener 介面,並指出要傾聽的事件類別,如上面的第 2 行,這個介面會要求傾聽類別實作一個 onApplicationEvent method,當 publisher 發出事件時,這個 method 即會收到該事件,這裡很簡單的將收到的事件內容印出來 (line 6)。
  • Config
1 @Configuration
2 @ComponentScan("idv.steven.info.tse")
3 public class MyEventConfig {
4 
5 }
要測試 publisher 送出的訊息是否會被 listener 收到,當然要先讓 spring 將它們載入,因為 publisher 和 listener 兩個 bean 是被在 idv.steven.info.tse package 下,所以第 2 行就去掃描該 package。
  • Main
1 public class MyTestMain {
2 
3     public static void main(String[] args) {
4         AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyEventConfig.class);
5         MyPublisher publisher = context.getBean(MyPublisher.class);
6         publisher.publish("Hello World");
7         context.close();
8     }
9 }
主程式很簡單,使用 spring 的 AnnotatioinConfigApplicationContext 載入 MyEventConfig,MyEventConfig 會去掃描指定的 package 將標有 @Component 相關的 bean 載入,載入後就如第 5 行,主程式取得 publisher 物件,然後在第 6 行發佈出 "Hello World" 的訊息,執行的結果就可以看到 console 印出如下訊息:
listen: Hello World



2017年7月6日 星期四

Updating Angular CLI

Angular 還在快速發展中,目前版本更新的很快,有個要特別注意的是,如果要更新 Angular CLI,一定要依下列的步驟: Updating Angular CLI

Updating Angular CLI

If you're using Angular CLI 1.0.0-beta.28 or less, you need to uninstall angular-cli package. It should be done due to changing of package's name and scope from angular-cli to @angular/cli:
npm uninstall -g angular-cli
npm uninstall --save-dev angular-cli
To update Angular CLI to a new version, you must update both the global package and your project's local package.
Global package:
npm uninstall -g @angular/cli
npm cache verify
npm install -g @angular/cli@latest
如果是 Angular 2.x ~ 4.x 版,第二行要寫 npm cache clean
Local project package:
rm -rf node_modules dist # use rmdir /S/Q node_modules dist in Windows Command Prompt; use rm -r -fo node_modules,dist in Windows PowerShell
npm install --save-dev @angular/cli@latest
npm install
如果不這麼做呢? 可能就會有一些版本的衝突,發生類似下面的錯誤訊息 ...
Module build failed: TypeError: Cannot read property 'newLine' of undefined




【日劇 - I Love You Just a Little Bit】
這是劇中的男主角,藝名「鈴木伸之」,第一次看他演戲,一直到10集都看完了,還以為他是「福士蒼汰」… 下圖是福士蒼汰 …
是不是長得很像?!
這是女主角的老公,看似溫柔實則變態,跟這種人相處,會有一種不知道什麼時候他會抓狂而被他傷害的恐懼,最後女主角 (波(王留)) 確實也沒有跟他在一起,這樣比較正常,應該說正常人都不會跟他在一起的吧?!
至於女主角波(王留),她在劇中的造型算是不太好看,她在別的戲裡的造型應該都比這個好看許多! 劇中她是外遇的人妻,這算負面的角色嗎? 好像也不盡然,終究感情這種事不該是用婚姻來約束,當然更不應該像台灣,竟然到了21世紀了,還用刑法來約束人的感情,在東亞國家中,台灣是唯一承認同性婚姻的國家,也是唯一用刑法懲罰外遇男女的國家! 總覺得婚姻這件事,要成立時當然要雙方都同意,但是要結束時,應該一方同意即可結束,只是離婚時"理虧"的一方要在財產及小孩的撫養權上付出代價,這樣不會比較合理嗎? 用刑法讓兩個彼此討厭的人在一起一輩子真的非常荒謬!! 而且這難道不是更嚴厲的懲罰?!