当前位置:首页 > 开发 > 开源软件 > 正文

Nutz--->>反复新建ioc容器的后果

发表于: 2014-12-18   作者:xiaoxiao1992428   来源:转载   浏览:
摘要: 问题: public class DaoZ {     public static Dao dao() { // 每当需要使用dao的时候就取一次     Ioc ioc = new NutIoc(new JsonLoader("dao.js"));     return ioc.get(
问题:
public class DaoZ {
 
  public static Dao dao() { // 每当需要使用dao的时候就取一次
    Ioc ioc = new NutIoc(new JsonLoader("dao.js"));
    return ioc.get(Dao.class);
  }
 
}

----------------------------------------------------------------------------
Wedal解析:
注意, java.sql.DataSource只是个接口.但下面讨论的DataSource均指代数据库连接池实现.

根本原因在于: Nutz的Ioc容器不是全局的,一旦没有被引用,就随时被GC.

    题目中的NutIoc实例,在方法返回之后,处于无引用的状态, 即满足了GC的条件,随时会被GC.

    题目中默认为2个基本ioc对象, DataSource和Dao, 其中Dao默认指代NutDao

    NutIoc被gc时,会触发depose事件, 从而调用各ioc对象的depose/close方法

    一般来说DataSource都会配置成depose事件触发close方法,即关闭连接池. 这样就导致DataSource对象处于关闭状态, 而NutDao的数据库连接均由DataSource提供, 直接导致NutDao实例在操作任意数据库方法时报错.

    注意, GC的时机是几乎不可控,不可预测的, 这就意味着上述的ioc容器被gc, depose方法被调用,DataSource被关闭的时机也是不可控及不可预测的. 这会导致程序有时候是好的(GC在Dao方法执行完成之后),有时候会挂的(GC在Dao执行完成之前)



错误的解决思路:
   1. 去掉depose事件. 首先是连接池都有初始大小和最小活跃数,这意味着DataSource被gc前总持有那么几个数据库连接. 并发上去了,gc来不及, 很快就数据库连接耗尽.

2. 那,去掉depose事件,连接池初始化大小和最小活跃数都设置为0呢. 初始化大小为0, 但你总会使用一次NutDao的方法吧, 那么就建立了一个连接, 然后最小活跃数是0, 将连接数从1降为0那么, 总有那么一个时间差,然后, 呵呵, 一个坑就摆在那了, 哪天碰巧没能快速关闭,也没被gc, 爆数据库连接数

3. 好吧,那我不用连接池,可以了吧? 可以,性能掉渣

解决方法:

   1 在Mvc中, 你几乎100%会用到@IocBy, 也就是NutMvc来持有ioc, 那么你就不别自行new NutIoc了. 在Setup接口中,你可以通过config.getIoc()来获取Ioc容器(常见于启动时的初始化,加载全局变量,计划任务什么的), 在任何不可能直接得到Ioc容器的地方, 通过 Mvcs.ctx().getDefaultIoc() 获取 .注意, Mvcs.ctx()总是非常规方法.

   2 非Mvc环境, 应使用一个工具类管理, 而且必须持有Ioc容器

   3
    public class DaoZ { // 供参考
    private static Ioc ioc; // 静态属性,确保了Ioc容器不会被gc
    
    public static synchronized Ioc ioc() { // 同步,用你喜欢的方法就好啦
        if (ioc == null) {
            try {
                ioc = new NutIoc(new ComboIocLoader("*js","ioc/", "*annotation", "net.wendal.iot"));
            }
            catch (ClassNotFoundException e) {
                throw Lang.warp(e);
            }
        }
        return ioc;
    }
    
    public static Dao dao() {
        return ioc.get(Dao.class);
    }
}

Nutz--->>反复新建ioc容器的后果

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
跟开涛学Spring 传统应用程序示意图 当有了IoC/DI的容器后,在客户端类中不再主动去创建这些对象了
跟开涛学Spring 传统应用程序示意图 当有了IoC/DI的容器后,在客户端类中不再主动去创建这些对象了
1. IoC容器 负责Bean的实例化、注入、生命周期方法管理,包括以下类型接口,前者更强大更常用 Appli
<context-param> <param-name>contextConfigLocation</param-name> <param-va
学习spring,找到一篇,http://www.blogjava.net/killme2008/archive/2007/04/20/112160.html,共享
IOC是inversion of control缩写,中文翻译为控制反转。没有引入IOC的时候,业务层都是在需要的时候主
Autofac是轻量级的开源Ioc容器,在这里可以下载http://code.google.com/p/autofac/。如果你用过其他
和Jbpm3一样,Jbpm4实现了自己的IOC容器。以现在的眼光看来,应用程序里一个IOC容器几乎是居家必备
比Spring简单的IoC容器   Spring 虽然比起EJB轻量了许多,但是因为它需要兼容许多不同的类库,导
Autofac是轻量级的开源Ioc容器,在这里可以下载http://code.google.com/p/autofac/。如果你用过其他
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号