关于ControllerFactory

image.png

在gitee上看到最新的ControllerFactory代码中加入了依赖注入,Controller是每次请求都new一个实例的,每次new完实例还要进行service注入,可想而知性能会随着Controller中依赖数的增加而慢慢越差。

代码如下:

public Controller getController(Class<? extends Controller> controllerClass) throws ReflectiveOperationException {
		Controller ret = controllerClass.newInstance();
		if (injectDependency) {
			com.jfinal.aop.Aop.inject(ret);
		}
		return ret;
	}

@JFinal 帮忙解惑上面问题



另外我想做一个单列的Controller(假设系统中的所有Controller都是无状态的),代码大致如下:

public class SingletonControllerFactory extends ControllerFactory{
	private final static Map<Class<? extends Controller>, Controller> singletonCache = new ConcurrentHashMap<>();
	
	public Controller getController(Class<? extends Controller> controllerClass) throws ReflectiveOperationException {
		Controller ret = singletonCache.get(controllerClass);
		if (ret == null) {
			ret = controllerClass.newInstance();
			/**
			if (injectDependency) {
				com.jfinal.aop.Aop.inject(ret);
			}*/
			singletonCache.put(controllerClass, ret);
		}
		return ret;
	}
}

然后在配置文件中加入:

constants.setControllerFactory(new SingletonControllerFactory());

官方有个FastControllerFactory了,该有个SingletonControllerFactory吧?

@JFinal 



评论区

杜福忠

2020-06-19 09:53

你这个有线程安全问题(request,response啥的),直接用FastControllerFactory吧,别折腾了

JFinal

2020-06-20 18:00

正如 @杜福忠 同学所说,想要让 controller 成为单例,无法解决 controller 同部一些属性的多线程问题

虽然你自己放入 controller 的业务层等等实例是无状态的,但 controller 内部持有的一些属性却是有状态的

官方提供的 FastControllerFactory 虽然不是让 controller 成为单例,但是可以让 controller 对象可以被复用,从而可以不必每次都创建 controller 对象

此外,jfinal 的 inject 是极快的,绝大部分情况下无需考虑这方面的性能。jfinal 只是为了追求极致才提供了 FastControllerFactory

jfinal 未将 FastControllerFactory 配置为默认值,是因为担心使用者在 controller 中自己再使用了 "有状态" 的属性,从而引发线程安全问题。这个问题需要覆盖 controller 中的 _clear_() 方法来解决。 在源码中有详细说明

性能一定是排在安全性之后的,况且 jfinal 性能早已过剩

热门反馈

扫码入社