• 设计模式课程 设计模式精讲 8-11 单例模式源码解析(jdk+spring+mybaties)


    1    源码解析

    1.1  单例解析1

    1.2  单例解析2(容器单例)

    1.3  单例解析3

    1.4  单例解析4

    1    源码解析
    1.1  单例解析1

    java.lang.Runtime

    /**
     *    饿汉式加载,初始化的时候,就已经new出了对象
     */ 
    private static Runtime currentRuntime = new Runtime();
    
        /**
         * Returns the runtime object associated with the current Java application.
         * Most of the methods of class <code>Runtime</code> are instance
         * methods and must be invoked with respect to the current runtime object.
         *
         * @return  the <code>Runtime</code> object associated with the current
         *          Java application.
         */
        public static Runtime getRuntime() {
            return currentRuntime;
        }
    1.2  单例解析2(容器单例)

    java.awt.Desktop(cs)

     /**
         * Returns the <code>Desktop</code> instance of the current
         * browser context.  On some platforms the Desktop API may not be
         * supported; use the {@link #isDesktopSupported} method to
         * determine if the current desktop is supported.
         * @return the Desktop instance of the current browser context
         * @throws HeadlessException if {@link
         * GraphicsEnvironment#isHeadless()} returns {@code true}
         * @throws UnsupportedOperationException if this class is not
         * supported on the current platform
         * @see #isDesktopSupported()
         * @see java.awt.GraphicsEnvironment#isHeadless
         */
    
        /*
         *    同步锁,context取对象,如果该对象为为null,new出新的对象,然后放入context
         */
        public static synchronized Desktop getDesktop(){
            if (GraphicsEnvironment.isHeadless()) throw new HeadlessException();
            if (!Desktop.isDesktopSupported()) {
                throw new UnsupportedOperationException("Desktop API is not " +
                                                        "supported on the current platform");
            }
    
            sun.awt.AppContext context = sun.awt.AppContext.getAppContext();
            Desktop desktop = (Desktop)context.get(Desktop.class);
    
            if (desktop == null) {
                desktop = new Desktop();
                context.put(Desktop.class, desktop);
            }
    
    
        /**
         *  context put的时候加上同步锁,可以避免多线程put异常
         */
        public Object put(Object var1, Object var2) {
            HashMap var3 = this.table;
            synchronized(this.table) {
                MostRecentKeyValue var4 = this.mostRecentKeyValue;
                if (var4 != null && var4.key == var1) {
                    var4.value = var2;
                }
    
                return this.table.put(var1, var2);
            }
        }
    1.3  单例解析3(Spring框架获取单例对象)

    spring中的单例是bean作用域中的一个,作用域在每个应用程序的上下文中只创建一个我们设置属性的实例,

    和我们的单例的区别是:spring将实例的数量限制的作用域在整个应用程序的上下文,而java应用程序中,是将类加载器的数量限制在给定的类加载器的整个空间里。

    所以说,在spring中启动多个容器的时候,每个容器即使是单例的,都可以拿到这个对象。

      public final T getObject() throws Exception {
            if (this.isSingleton()) {
                return this.initialized ? this.singletonInstance : this.getEarlySingletonInstance();
            } else {
                return this.createInstance();
            }
        }
    
    /*
     *    如果被初始化,获取早期的单例对象
     * 
     */
    //通过代理去拿新对象
        private T getEarlySingletonInstance() throws Exception {
            Class<?>[] ifcs = this.getEarlySingletonInterfaces();
            if (ifcs == null) {
                throw new FactoryBeanNotInitializedException(this.getClass().getName() + " does not support circular references");
            } else {
                if (this.earlySingletonInstance == null) {
                    this.earlySingletonInstance = Proxy.newProxyInstance(this.beanClassLoader, ifcs, new AbstractFactoryBean.EarlySingletonInvocationHandler());
                }
    
                return this.earlySingletonInstance;
            }
        }
    1.4  单例解析4(基于threadLocal的线程案例)(mybaties获取单例对象)

    mybaties上下文保证了每个线程各自的数据,每个线程自己的上下文,自己保存好

      private static final ThreadLocal<ErrorContext> LOCAL = new ThreadLocal<ErrorContext>();
      
     private ErrorContext() {
      }
    
      public static ErrorContext instance() {
        ErrorContext context = LOCAL.get();
    if (context == null) {
          context = new ErrorContext();
          LOCAL.set(context);
        }
        return context;
      }
  • 相关阅读:
    iOS截取长图,自定义截取size
    工作
    UITableView适配iOS11
    利用脚本实现build号自动加一
    iOS原生与JS互调
    CSS高级技巧
    伪元素选择器
    CSS设置过渡
    CSS文本属性 二
    css设置圆角矩形
  • 原文地址:https://www.cnblogs.com/1446358788-qq/p/11450813.html
Copyright © 2020-2023  润新知