@jfinal java
因爲目前Jfinal中缺乏IOC的實現 項目中使用了Jfinal用來控制轉發 orm等 爲了讓開發人員儘可能少於sql語句打交道spring
我又分離出了service層,須要在Controller中調用service提供的服務操做數據庫,須要使用到依賴注入iocsql
不想使用spring,因而換作google的Guice數據庫
下面來看具體插件代碼:ide
GuicePlugin.java函數
package guice; import java.util.HashMap; import java.util.Map.Entry; import com.google.inject.Binder; import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.Module; import com.jfinal.plugin.IPlugin; /** * Guice IOC plugin * @author xwalker <br/> http://my.oschina.net/imhoodoo */ public class GuicePlugin implements IPlugin { private static Injector guice; //綁定注入的map @SuppressWarnings("rawtypes") private HashMap<Class, Class> bindMap; /** * 默認構造函數 初始化綁定注入map */ @SuppressWarnings("rawtypes") public GuicePlugin() { bindMap = new HashMap<Class, Class>(); } /** * 綁定依賴 * @param bindSrc * @param bindTo */ public void bind(Class<?> bindSrc, Class<?> bindTo) { bindMap.put(bindSrc, bindTo); } /** * 封裝guice中的getInstance * @param clazz * @return */ public static <T> T getInstance(Class<T> clazz){ return guice.getInstance(clazz); } @Override public boolean start() { guice = Guice.createInjector(new Module() { @SuppressWarnings("unchecked") @Override public void configure(Binder binder) { for (@SuppressWarnings("rawtypes") Entry<Class, Class> entry : bindMap.entrySet()) { binder.bind(entry.getKey()).to(entry.getValue()); } } }); return true; } @Override public boolean stop() { return true; } }
這裏用一個bindMap來記錄綁定依賴注入ui
start的時候會調用Guice進行bindgoogle
GuiceInterceptor.javaspa
package guice; import java.lang.reflect.Field; import com.google.inject.Inject; import com.jfinal.aop.Interceptor; import com.jfinal.core.ActionInvocation; import com.jfinal.core.Controller; /** * Guice ioc interceptor * @author xwalker <br/> http://my.oschina.net/imhoodoo * */ public class GuiceInterceptor implements Interceptor { @Override public void intercept(ActionInvocation ai) { /* * 獲得攔截的controller 判斷是否有依賴注入的屬性 */ Controller controller = ai.getController(); Field[] fields = controller.getClass().getDeclaredFields(); for (Field field : fields) { Object bean = null; if (field.isAnnotationPresent(Inject.class)) bean = GuicePlugin.getInstance(field.getType()); else continue; try { if (bean != null) { field.setAccessible(true); field.set(controller, bean); } } catch (Exception e) { throw new RuntimeException(e); } } ai.invoke(); } }
在Jfinalconfig中配置插件.net
/** * 配置神奇的GUICE IOC組件 * @param me */ private void configIoc(Plugins me) { GuicePlugin guicePlugin=new GuicePlugin(); guicePlugin.bind(BaseService.class, DbService.class); me.add(guicePlugin); }
這樣在controller中就能夠使用DbService依賴注入了 使用註解@Inject
public class DBController extends Controller { @Inject private DbService dbService; }
有一個比較麻煩的地方就是須要依賴注入的service 都須要在配置中添加bind
binder.bind(entry.getKey()).to(entry.getValue())
guicePlugin.bind(BaseService.class, DbService.class);
Guice中不知道還有沒有其餘方式配置 只須要註解 不須要其餘像bind的方式
還有就是注入的service在使用的時候須要使用guice.getInstance()去獲得
感受這裏有點麻煩,請高手解答。