Guice真的無法享受企業級元件嗎
Guice真的無法享受企業級元件嗎,炮轟Guice的佔絕大多數。但如果Guice能整合Spring,那麼我們似乎可以做很多有意義的事了。那麼開始Spring整合之旅吧。不過crazybob在整合方面極不配合,就給了我們一個單元測試類,然後讓我們自力更生。好在Guice本身足夠簡單。
首先還是來一個最簡單無聊的HelloWorld整合吧。
HelloWorld.java
- package com.leo.domain;
- public class HelloWorld {
- public String sayHello(String str) {
- return str;
- }
- }
package com.leo.domain; public class HelloWorld { public String sayHello(String str) { return str; } }
夠簡單了吧。
現在開始編寫你的applicationContext.xml(如果不熟悉Spring的話,可能無法繼續往下看)。
為保持簡潔,去掉了那一段DTD。
- <beans>
- <bean id="helloWorld" class="com.leo.domain.HelloWorld" />
- beans>
好了,開始與Guice整合吧。
Guice的核心就是com.google.inject.Module,它類似於Spring的bean工廠。 HelloWorldMyModule.java
- package com.leo.module;
- import static com.google.inject.spring.SpringIntegration.fromSpring;
- import org.springframework.beans.factory.BeanFactory;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- import com.google.inject.Binder;
- import com.google.inject.Module;
- import com.leo.domain.HelloWorld;
- public class HelloWorldMyModule implements Module {
- public void configure(Binder binder) {
- final BeanFactory beanFactory = new ClassPathXmlApplicationContext(
- new String[] { "applicationContext.xml", "daoContext.xml" });
- binder.bind(BeanFactory.class).toInstance(beanFactory);
- binder.bind(HelloWorld.class).toProvider(
- fromSpring(HelloWorld.class, "helloWorld"));
- }
- }
package com.leo.module; import static com.google.inject.spring.SpringIntegration.fromSpring; import org.springframework.beans.factory.BeanFactory; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.google.inject.Binder; import com.google.inject.Module; import com.leo.domain.HelloWorld; public class HelloWorldMyModule implements Module { public void configure(Binder binder) { final BeanFactory beanFactory = new ClassPathXmlApplicationContext( new String[] { "applicationContext.xml", "daoContext.xml" }); binder.bind(BeanFactory.class).toInstance(beanFactory); binder.bind(HelloWorld.class).toProvider( fromSpring(HelloWorld.class, "helloWorld")); } }
其中:
- final BeanFactory beanFactory = new ClassPathXmlApplicationContext(
- new String[] { "applicationContext.xml", "daoContext.xml" });
- binder.bind(BeanFactory.class).toInstance(beanFactory);
final BeanFactory beanFactory = new ClassPathXmlApplicationContext( new String[] { "applicationContext.xml", "daoContext.xml" }); binder.bind(BeanFactory.class).toInstance(beanFactory);
定義了Guice與Spring整合後,將spring工廠也由Guice託管。我感覺crazybob在與Spring整合事件上非常低調,給了個嚇死人的單元測試,而且沒有任何文件,這個單元測試裡的bean都是臨時動態注入進去的,不知道是因為出自對Spring XML配置的不滿,還是根本沒想到用Guice的人會去整合Spring,我個人感覺他在這一點上非常吝嗇。 注意這一句:
- binder.bind(HelloWorld.class).toProvider(
- fromSpring(HelloWorld.class, "helloWorld"));
binder.bind(HelloWorld.class).toProvider( fromSpring(HelloWorld.class, "helloWorld"));
這與普通Guice本身託管的Bean注入不一樣,fromSpring很明顯說明這個bean來自於spring,而且與helloWorld與applicationContext.xml中定義的那個是一致的。
好了,我們開始來個單元測試
HelloWorldTest.java
- package com.leo.service;
- import junit.framework.TestCase;
- import com.google.inject.Guice;
- import com.google.inject.Inject;
- import com.google.inject.Injector;
- import com.leo.domain.HelloWorld;
- import com.leo.module.HelloWorldMyModule;
- /**
- * @author superleo
- */
- public class HelloWorldTest extends TestCase {
- @Inject
- private HelloWorld helloWorld;
- public void testHelloWorld() {
- HelloWorldMyModule module = new HelloWorldMyModule(); // 建HelloWorldModule,生成Guice的bean工廠
- HelloWorldTest test = new HelloWorldTest();
- Injector in = Guice.createInjector(module);
- in.injectMembers(test); // 將HelloWorldTest所依賴的helloWorld注入進去
- System.out.println(test.helloWorld.sayHello("hey, hello-world"));
- }
- }
package com.leo.service; import junit.framework.TestCase; import com.google.inject.Guice; import com.google.inject.Inject; import com.google.inject.Injector; import com.leo.domain.HelloWorld; import com.leo.module.HelloWorldMyModule; /** * @author superleo */ public class HelloWorldTest extends TestCase { @Inject private HelloWorld helloWorld; public void testHelloWorld() { HelloWorldMyModule module = new HelloWorldMyModule(); // 建HelloWorldModule,生成Guice的bean工廠 HelloWorldTest test = new HelloWorldTest(); Injector in = Guice.createInjector(module); in.injectMembers(test); // 將HelloWorldTest所依賴的helloWorld注入進去 System.out.println(test.helloWorld.sayHello("hey, hello-world")); } }
程式碼還是非常簡單。執行後,正常的結果會出來在控制檯上。但是這段程式碼能說明什麼,無非就是helloWorld不需要set,get方法,但還多加了一大堆什麼Injector, Module之類的。實際上在Guice與Struts2整合後,這些硬編碼是不會出現的,而且如果不是因為與Spring整合,連Module裡面配置HelloWorld都不要。但不是有人說Guice無法使用企業級元件嗎?就單純一個DI,根本就是玩具,但大家想想Guice能通過Spring來應用這些企業級元件的話,Guice還是有優勢的。因為它夠簡單,夠快,夠靈活,強型別,本身沒有XML(與其它框架整合,不能保證別的框架沒有),幾乎沒有學習曲線,文件就一個HTML。因此,我現在想給大家運用JavaMail,這個算企業級常用的元件了吧?
繼續編寫Spring的applicationContext.xml applicationContext.xml
- xml version="1.0" encoding="UTF-8"?>
- nbsp;beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
- <beans>
- <!-- Java Mail -->
- <bean id="mailSender"
- class="org.springframework.mail.javamail.JavaMailSenderImpl">
- <property name="host" value="smtp.163.com" />
- <!-- 有些郵件伺服器傳送郵件需要認證,所以必須提供帳號 -->
- <property name="username" value="kyo100900@163.com" />
- <property name="password" value="111111" />
- <property name="javaMailProperties">
- <props>
- <prop key="mail.smtp.auth">trueprop>
- props>
- property>
- bean>
- <!--一個郵件模板(測試時使用)-->
- <bean id="mailMessage"
- class="org.springframework.mail.SimpleMailMessage">
- <property name="to" value="superleo_cn@hotmail.com" />
- <property name="from" value="kyo100900@163.com" />
- <property name="subject" value="fdsfdsfsdfsd" />
- bean>
- beans>
<!-- Java Mail --> <!--一個郵件模板(測試時使用)--> <!-- 有些郵件伺服器傳送郵件需要認證,所以必須提供帳號 --> true
上面就是大家在Spring配置檔案裡寫爛了的程式碼,別的什麼整合程式碼同理,就不多說了。 這時候,我們寫一個JavaMailModule
JavaMailModule.java
- package com.leo.module;
- import static com.google.inject.spring.SpringIntegration.fromSpring;
- import org.springframework.beans.factory.BeanFactory;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- import org.springframework.mail.MailSender;
- import org.springframework.mail.SimpleMailMessage;
- import org.springframework.mail.javamail.JavaMailSenderImpl;
- import com.google.inject.Binder;
- import com.google.inject.Module;
- public class JavaMailModule implements Module {
- public void configure(Binder binder) {
- final BeanFactory beanFactory = new ClassPathXmlApplicationContext(
- new String[] { "applicationContext.xml"});
- binder.bind(BeanFactory.class).toInstance(beanFactory);
- binder.bind(SimpleMailMessage.class).toProvider(
- fromSpring(SimpleMailMessage.class, "mailMessage"));
- binder.bind(MailSender.class).toProvider(
- fromSpring(JavaMailSenderImpl.class, "mailSender"));
- }
- }
package com.leo.module; import static com.google.inject.spring.SpringIntegration.fromSpring; import org.springframework.beans.factory.BeanFactory; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.mail.MailSender; import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.JavaMailSenderImpl; import com.google.inject.Binder; import com.google.inject.Module; public class JavaMailModule implements Module { public void configure(Binder binder) { final BeanFactory beanFactory = new ClassPathXmlApplicationContext( new String[] { "applicationContext.xml"}); binder.bind(BeanFactory.class).toInstance(beanFactory); binder.bind(SimpleMailMessage.class).toProvider( fromSpring(SimpleMailMessage.class, "mailMessage")); binder.bind(MailSender.class).toProvider( fromSpring(JavaMailSenderImpl.class, "mailSender")); } }
和HelloWorld一樣,只是分別換成了mailMessage, mailSender。寫到這裡大家肯定明白了,Guice與Spring整合其實非常非常簡單。
寫個測試吧:
JavaMail.java
- package com.leo.util;
- import org.springframework.mail.MailSender;
- import org.springframework.mail.SimpleMailMessage;
- import com.google.inject.Guice;
- import com.google.inject.Inject;
- import com.google.inject.Injector;
- import com.leo.module.MyModuleSpring;
- public class JavaMail {
- @Inject
- private MailSender mailSender;
- @Inject
- private SimpleMailMessage mailMessage;// 郵件模板
- public void sendMail() {
- System.out.println("-----------傳送郵件!---------");
- mailMessage.setText("send maiiiiiiiiiiiiiiiil~~~~~~~~~~~~~~~~~~");
- try {
- System.out.println(mailSender.toString());
- mailSender.send(mailMessage);
- } catch (Exception e) {
- e.printStackTrace();
- }
- System.out.println("-----------傳送成功!---------");
- }
- public static void main(String... strings) {
- MyModuleSpring spring = new MyModuleSpring();
- JavaMail mail = new JavaMail();
- Injector in = Guice.createInjector(spring);
- in.injectMembers(mail);
- mail.sendMail();
- }
- }
package com.leo.util; import org.springframework.mail.MailSender; import org.springframework.mail.SimpleMailMessage; import com.google.inject.Guice; import com.google.inject.Inject; import com.google.inject.Injector; import com.leo.module.MyModuleSpring; public class JavaMail { @Inject private MailSender mailSender; @Inject private SimpleMailMessage mailMessage;// 郵件模板 public void sendMail() { System.out.println("-----------傳送郵件!---------"); mailMessage.setText("send maiiiiiiiiiiiiiiiil~~~~~~~~~~~~~~~~~~"); try { System.out.println(mailSender.toString()); mailSender.send(mailMessage); } catch (Exception e) { e.printStackTrace(); } System.out.println("-----------傳送成功!---------"); } public static void main(String... strings) { MyModuleSpring spring = new MyModuleSpring(); JavaMail mail = new JavaMail(); Injector in = Guice.createInjector(spring); in.injectMembers(mail); mail.sendMail(); } }
只要使用者名稱密碼正確,沒有設定什麼代理,防火牆之類的,就能正常的執行,但大家如果測試的時候,請把電子郵件改改。至於說與Hibernate,事務等整合,已經出了wrap框架了,有興趣可以看看robbin寫的《Warp framework - 一個相當有前途的Java框架》。 因此Guice不是完全不可能使用所謂的企業級元件的,直接使用Spring就可很容易做到。那麼在應用Guice的時候,我感覺可以單獨建立一個SpringModule,將Guice無法做到的事通過Spring工廠來幫你組裝,其它方面,比如說Struts2的Action或Service層之間的注入等,直接用@Inject就得了,不要那麼多set,get,(Struts2需要放入到值棧的屬性例外)我們專案大多數Action超過幾千行了,光set,get就幾百行。Spring配置檔案估計拼在一起也有幾千行,但所謂注入到的其它企業級元件還不到5個,剩下全是service,dao,action等等。就算Spring可以autowire,也不是解決問題的根本。
Guice當然也有缺點——太過於簡單。不少JavaEE開發人員感覺似乎沒有什麼實際價值,更像是一種玩具。但我看好Guice的思想——簡單而且型別安全。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/13270562/viewspace-217883/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 美國研發“無法破解”的晶片,真的無人能攻破嗎?晶片
- 蘋果企業簽名穩定性好,超級簽名就真的不會掉籤嗎?蘋果
- 你真的以為蘋果只是一家科技企業嗎?蘋果
- 「合成類遊戲」真的無法進入休閒遊戲頭部領域嗎?遊戲
- 智慧推薦,真的會讓我們陷入“資訊繭房”無法自拔嗎?
- 傳統企業玩網際網路你真的準備好了嗎?
- 使用web-component搭建企業級元件庫Web元件
- win10企業版無法更新怎麼辦_win10企業版無法更新的解決方法Win10
- 騰訊:谷歌無人駕駛汽車真的安全嗎?谷歌
- Lightning Web元件:超快的企業級Web元件基礎Web元件
- iview 元件無法使用View元件
- 通天塔之石——企業級前端元件庫方案前端元件
- 企業級無線滲透與無線資料淺析
- 企業版管理工具無法開啟
- 蘋果稱無法實現本季度營收目標(蘋果企業賬號可以租用嗎)蘋果營收
- 【等保小知識】企業可以定級嗎?可以自己確定等保等級嗎?
- TestFlight適用於哪些平臺,真的能打倒蘋果企業簽名嗎蘋果
- 關於PHP在企業級開發領域的訪談——企業級開發,PHP準備好了嗎?PHP
- 微軟發出提醒企業升級Win10 May 2019功能更新:無法再延遲升級微軟Win10
- 企業級JAVAJava
- 企業無法留住技術人才的10大原因
- 谷歌汽車肇事遭打臉 無人駕駛真的可靠嗎?谷歌
- 輕量級DI框架Guice使用詳解框架GUI
- 基於TDesign風格的Blazor企業級UI元件庫BlazorUI元件
- 使用於企業級的無線網測試軟體
- windows 安裝 企業QQ後,個人qq無法登入Windows
- 你真的會用mysql行級鎖嗎?mysql 行級鎖全解析MySql
- iPhoneXR手機玩遊戲效果極棒是真的嗎?(蘋果企業開發者賬號)iPhone遊戲蘋果
- 企業雲WiFi好嗎WiFi
- 解答:Java就業薪資真的很高嗎?Java就業
- 網路安全等級保護真的很重要嗎?
- Lansweeper:調查顯示超過一半的企業裝置無法升級到Windows 11Windows
- Vue3 企業級優雅實戰 - 元件庫框架 - 8 搭建元件庫 cliVue元件框架
- 15 分鐘實現企業級應用無損上下線
- 超六成受訪企業無法識別黑客入侵黑客
- 小程式選人控制元件 – 仿企業微信實現多選及多層級無規則巢狀控制元件巢狀
- 小程式選人控制元件 - 仿企業微信實現多選及多層級無規則巢狀控制元件巢狀
- 你真的理解this嗎