@jfinal 由于目前Jfinal中缺少IOC的实现 项目中使用了Jfinal用来控制转发 orm等 为了让开发人员尽量少于sql语句打交道 我又分离出了service层,需要在Controller
@jfinal
由于目前Jfinal中缺少IOC的实现 项目中使用了Jfinal用来控制转发 orm等 为了让开发人员尽量少于sql语句打交道
我又分离出了service层,需要在Controller中调用service提供的服务操作数据库,需要使用到依赖注入ioc
不想使用spring,于是换做google的Guice
下面来看具体插件代码:
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来记录绑定依赖注入
start的时候会调用Guice进行bind
GuiceInterceptor.java
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中配置插件
/** * 配置神奇的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()去得到
感觉这里有点麻烦,请高手解答。