您的位置:首页 > 编程语言 > Java开发

Spring的Dao Service采用单例模式+ThreadLoca模式实现线程安全

2016-08-05 10:42 405 查看
 在使用Spring时,很多人可能对Spring中为什么DAO和Service对象采用单实例方式很迷惑,这些读者是这么认为的:

    DAO对象必须包含一个数据库的连接Connection,而这个Connection不是线程安全的,所以每个DAO都要包含一个不同的Connection对象实例,这样一来DAO对象就不能是单实例的了。

    上述观点对了一半。对的是“每个DAO都要包含一个不同的Connection对象实例”这句话,错的是“DAO对象就不能是单实例”。

    其实Spring在实现Service和DAO对象时,使用了ThreadLocal这个类,这个是一切的核心! 如果你不知道什么事ThreadLocal

Spring使用ThreadLocal解决线程安全问题:

    Spring中DAO和Service都是以单实例的bean形式存在,Spring通过ThreadLocal类将有状态的变量(例如数据库连接Connection)本地线程化,从而做到多线程状况下的安全。在一次请求响应的处理线程中, 该线程贯通展示、服务、数据持久化三层,通过ThreadLocal使得所有关联的对象引用到的都是同一个变量。 
    参考下面代码,这个是《Spring3.x企业应用开发实战中的例子》

[java] view
plain copy

 print?

public class SqlConnection {    

    //①使用ThreadLocal保存Connection变量    

    privatestatic ThreadLocal <Connection>connThreadLocal = newThreadLocal<Connection>();    

    publicstatic Connection getConnection() {    

       // ②如果connThreadLocal没有本线程对应的Connection创建一个新的Connection,    

       // 并将其保存到线程本地变量中。    

       if (connThreadLocal.get() == null) {    

           Connection conn = getConnection();    

           connThreadLocal.set(conn);    

           return conn;    

       } else {    

           return connThreadLocal.get();    

           // ③直接返回线程本地变量    

       }    

    }    

    public voidaddTopic() {    

       // ④从ThreadLocal中获取线程对应的Connection    

       try {    

           Statement stat = getConnection().createStatement();    

       } catch (SQLException e) {    

           e.printStackTrace();    

       }    

    }    

}  

这个是例子展示了不同线程使用TopicDao时如何使得每个线程都获得不同的Connection实例副本,同时保持TopicDao本身是单实例。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: