Jfinal集成Guice完成ioc
Jfinal集成Guice完成ioc
山东小木 发表于4年前
Jfinal集成Guice完成ioc
  • 发表于 4年前
  • 阅读 3112
  • 收藏 17
  • 点赞 1
  • 评论 32

【腾讯云】如何购买服务器最划算?>>>   

@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()去得到

感觉这里有点麻烦,请高手解答。


共有 人打赏支持
粉丝 191
博文 39
码字总数 23803
评论 (32)
JFinal
谢谢分享,顶一个
山东小木

引用来自“JFinal”的评论

谢谢分享,顶一个

有没有更好的方式啊 guice虽然比spring轻量 但是需要调用guice的bind函数太费劲了 service多了的话 需要写很多啊
JFinal

引用来自“xwalker”的评论

引用来自“JFinal”的评论

谢谢分享,顶一个

有没有更好的方式啊 guice虽然比spring轻量 但是需要调用guice的bind函数太费劲了 service多了的话 需要写很多啊

如果Service是无状态的,我会直接在Controller 中这样: private XxxService xxxService = new XxxService(),世间本无事,很多人都忘了new 是怎么用的了
山东小木

引用来自“JFinal”的评论

引用来自“xwalker”的评论

引用来自“JFinal”的评论

谢谢分享,顶一个

有没有更好的方式啊 guice虽然比spring轻量 但是需要调用guice的bind函数太费劲了 service多了的话 需要写很多啊

如果Service是无状态的,我会直接在Controller 中这样: private XxxService xxxService = new XxxService(),世间本无事,很多人都忘了new 是怎么用的了

Controller中使用的service 使用的时候加载一次 单例 使用new的话 每次都创建新的啊
JFinal

引用来自“xwalker”的评论

引用来自“JFinal”的评论

引用来自“xwalker”的评论

引用来自“JFinal”的评论

谢谢分享,顶一个

有没有更好的方式啊 guice虽然比spring轻量 但是需要调用guice的bind函数太费劲了 service多了的话 需要写很多啊

如果Service是无状态的,我会直接在Controller 中这样: private XxxService xxxService = new XxxService(),世间本无事,很多人都忘了new 是怎么用的了

Controller中使用的service 使用的时候加载一次 单例 使用new的话 每次都创建新的啊

忘写了一个static,应该是这样的private static final XxxService xxxService = new XxxService()
JFinal
以上写法,你用习惯以后会发现少很多事
山东小木

引用来自“JFinal”的评论

以上写法,你用习惯以后会发现少很多事

多谢指导
JFinal

引用来自“xwalker”的评论

引用来自“JFinal”的评论

以上写法,你用习惯以后会发现少很多事

多谢指导

感谢支持。一般来说 IOC 是为了在注入实现类时引入代理,从而实现 AOP,AOP可以用来实现声明式事务,权限管理等等的切面功能,但对于JFinal来说,AOP已用拦截器天然进行了支持,所以就没有多少必要再自己整一套IOC了
山东小木

引用来自“JFinal”的评论

引用来自“xwalker”的评论

引用来自“JFinal”的评论

以上写法,你用习惯以后会发现少很多事

多谢指导

感谢支持。一般来说 IOC 是为了在注入实现类时引入代理,从而实现 AOP,AOP可以用来实现声明式事务,权限管理等等的切面功能,但对于JFinal来说,AOP已用拦截器天然进行了支持,所以就没有多少必要再自己整一套IOC了

哦 照此说来 这里集成guice没什么必要了 直接按照Jfinal中Model的dao定义方式,在service中
public static Service service=new service();controller中需要使用的话直接 Service.service.getList(); 还是在controller中定义静态的service?
绝望的八皮
哈,好久以前自己弄过,当时记得怎么弄来着是可以不用bind的。。后来那个版本不在了,然后又再也想不起来怎么搞,文档看了好多。。后来已经放弃ioc了就没研究了。。楼主看好你哦
山东小木

引用来自“绝望的八皮”的评论

哈,好久以前自己弄过,当时记得怎么弄来着是可以不用bind的。。后来那个版本不在了,然后又再也想不起来怎么搞,文档看了好多。。后来已经放弃ioc了就没研究了。。楼主看好你哦

请教 看看9楼的问题 使用ioc好还是直接static new出来
绝望的八皮
ioc是个骗局哈哈,现在一般不这么玩了。其实业务本生就应该无状态,无状态那么用static也没啥其实。。专心不受打扰的去做实际的业务才是真,其他的能少则少吧。当然我不否认在java里面有些地方也可能需要ioc能更好一点
hengheng8848

引用来自“xwalker”的评论

引用来自“JFinal”的评论

谢谢分享,顶一个

有没有更好的方式啊 guice虽然比spring轻量 但是需要调用guice的bind函数太费劲了 service多了的话 需要写很多啊

可以用guice自己的注解邦定@ImplementBy
萧萧恋
我是觉得 没有必要抽出来一个 service层 Controller + Model 多好!
山东小木

引用来自“萧萧恋”的评论

我是觉得 没有必要抽出来一个 service层 Controller + Model 多好!

这个在于个人习惯 封装service层是为了将controller规范化 业务逻辑都写在service中 对开发人员屏蔽掉sql语句
萧萧恋

引用来自“xwalker”的评论

引用来自“萧萧恋”的评论

我是觉得 没有必要抽出来一个 service层 Controller + Model 多好!

这个在于个人习惯 封装service层是为了将controller规范化 业务逻辑都写在service中 对开发人员屏蔽掉sql语句

那SQL语句也不是写在Controller里啊,是写到Model 里面的,Controller 来调用Model 这样本身就是最面向对象的!
山东小木

引用来自“萧萧恋”的评论

引用来自“xwalker”的评论

引用来自“萧萧恋”的评论

我是觉得 没有必要抽出来一个 service层 Controller + Model 多好!

这个在于个人习惯 封装service层是为了将controller规范化 业务逻辑都写在service中 对开发人员屏蔽掉sql语句

那SQL语句也不是写在Controller里啊,是写到Model 里面的,Controller 来调用Model 这样本身就是最面向对象的!

我做的系统较大 分库分表 不适合用model 使用的是db+record 自己写语句
山东小木

引用来自“萧萧恋”的评论

引用来自“xwalker”的评论

引用来自“萧萧恋”的评论

我是觉得 没有必要抽出来一个 service层 Controller + Model 多好!

这个在于个人习惯 封装service层是为了将controller规范化 业务逻辑都写在service中 对开发人员屏蔽掉sql语句

那SQL语句也不是写在Controller里啊,是写到Model 里面的,Controller 来调用Model 这样本身就是最面向对象的!

SysCompany.dao.findFirst("select id,name,db_name,com_account from sys_company where com_account=?",com_account);
你在controller中使用model搜索不也是写sql语句吗?封装层其实就是屏蔽一下 减少代码量
萧萧恋

引用来自“xwalker”的评论

引用来自“萧萧恋”的评论

引用来自“xwalker”的评论

引用来自“萧萧恋”的评论

我是觉得 没有必要抽出来一个 service层 Controller + Model 多好!

这个在于个人习惯 封装service层是为了将controller规范化 业务逻辑都写在service中 对开发人员屏蔽掉sql语句

那SQL语句也不是写在Controller里啊,是写到Model 里面的,Controller 来调用Model 这样本身就是最面向对象的!

SysCompany.dao.findFirst("select id,name,db_name,com_account from sys_company where com_account=?",com_account);
你在controller中使用model搜索不也是写sql语句吗?封装层其实就是屏蔽一下 减少代码量

我倒觉得 这里的封装不是减少代码量 反之应该是增加代码量,jfinal的模式很明显半充血模型,就是让你把业务写到Model里面去的,因为他没有属性,所以这里的Model其实就是业务Bean,而且在这层业务Bean上面还可以使用事物,这样已经够了,对于常见的三层架构来说,其实是没办法的,由于hibernate的关系,实体类必须是简单的POJO,也就是里面包含属性和get and set方法,这样你的实体类确定了以后,就没有业务层了,你就必须抽象出一个业务层来做事物处理,所以才产生了3层的分层,反过来看jfinal这里他没有hibernate那种orm映射,所以是业务是可以全部写到Model层的,这样模块化更明显!
山东小木

引用来自“萧萧恋”的评论

引用来自“xwalker”的评论

引用来自“萧萧恋”的评论

引用来自“xwalker”的评论

引用来自“萧萧恋”的评论

我是觉得 没有必要抽出来一个 service层 Controller + Model 多好!

这个在于个人习惯 封装service层是为了将controller规范化 业务逻辑都写在service中 对开发人员屏蔽掉sql语句

那SQL语句也不是写在Controller里啊,是写到Model 里面的,Controller 来调用Model 这样本身就是最面向对象的!

SysCompany.dao.findFirst("select id,name,db_name,com_account from sys_company where com_account=?",com_account);
你在controller中使用model搜索不也是写sql语句吗?封装层其实就是屏蔽一下 减少代码量

我倒觉得 这里的封装不是减少代码量 反之应该是增加代码量,jfinal的模式很明显半充血模型,就是让你把业务写到Model里面去的,因为他没有属性,所以这里的Model其实就是业务Bean,而且在这层业务Bean上面还可以使用事物,这样已经够了,对于常见的三层架构来说,其实是没办法的,由于hibernate的关系,实体类必须是简单的POJO,也就是里面包含属性和get and set方法,这样你的实体类确定了以后,就没有业务层了,你就必须抽象出一个业务层来做事物处理,所以才产生了3层的分层,反过来看jfinal这里他没有hibernate那种orm映射,所以是业务是可以全部写到Model层的,这样模块化更明显!

同意 但是分库分表的情况下是没有model的 使用record 系统复杂 分布式 需要切分表 没法使用一个model去映射表
×
山东小木
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: