@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()去得到
感觉这里有点麻烦,请高手解答。