• Java 创建通用单例工具类(泛型)


    1.情景展示

      我们在接触单例设计模式的时候,只能创建简单的单例,也就是哪个Java类需要控制成单例,就写一个对应的工具类。例如:

      如上图所示,就是单例的表现形式之一:饿汉式(也就是不管你需不需,我先创建一个对象再说,你要我就给,不要我也已经创建好了);

      创建单例,我们需要将构造方法私有化,这样就可以保证调用该类时无法通过new来创建对象;

      另外,创建getInstance()方法,并需要被synchronized关键字修饰,以确保该对象同一时间只能被一个线程调用。

      那么,当我们有创建大量单例的需求时,总不能需要几个就写对应的类吧,这样不仅降低代码的可维护性,还会影响开发效率。

    2.原因分析

      通过泛型来实现 

    3.解决方案

    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * 单例模式+泛型
     * @description 所有的类都可以调用该类生成唯一的Java实例化对象
     * 调用者需要继承该类,调用方法如下:
     * MySingleton s = (MySingleton) Singleton.getInstance(MySingleton.class);
     * @author: Marydon
     * @date: 2020年07月13日 0013 19:35
     */
    public class SingletonUtils {
        //类初始化时,不初始化这个对象(延时加载,真正用的时候再创建)
        private static Map<Class<? extends SingletonUtils>, SingletonUtils> INSTANCES_MAP = new HashMap<>();
    
        /*
         * 无参构造方法
         * @attention: 这里不能再用private修饰了,因为该类是父类
         * @date: 2020年09月18日 0018 10:20
         */
        protected SingletonUtils() {
        }
    
        /*
         * 单例(懒汉式)
         * @date: 2020年07月13日 0013 19:50
         * @param: instanceClass
         * @return: com.xyh.bill.service.tools.Singleton
         */
        public synchronized static <E extends SingletonUtils> SingletonUtils getInstance(Class<E> instanceClass) throws Exception {
            if (INSTANCES_MAP.containsKey(instanceClass)) {
                return (E) INSTANCES_MAP.get(instanceClass);
            } else {
                E instance = instanceClass.newInstance();
                INSTANCES_MAP.put(instanceClass, instance);
                return instance;
            }
        }
    
    }
    

      构造方法需要使用protect修饰,否则

    4.调用

      确保要单例的Java对象,继承上面的Java类; 

    5.优化 

      这是一个接口请求的总入口,我们会发现通过泛型控制的单例模式,代码还是冗余,因为我使用的是spring,由于IOC的特性,spring托管的bean对象都是唯一的,所以,我们完全可以通过注解来简化代码。

      首先,给需要单例的类添加注解(因为这里是服务层所以用的是@Service)

      在Controller层调用,需要注入该对象 

      这样,我们就可以直接使用该对象啦

      这里需要注意的有两点:   

      要想让spring来管理java对象,需要在该类上添加@Component/@Service等注解;

      要想使用spring管理的bean对象,则调用该对象的类必须也是一个由spring来管理的对象,后者带有Controller注解的控制器,否则,一个普通的类是无法获取到spring管理的对象的,即使你加上@Autowired注解也没用

      所以,能通过spring来管理的对象,尽量使用spring来完成。

    写在最后

      哪位大佬如若发现文章存在纰漏之处或需要补充更多内容,欢迎留言!!!

     相关推荐:

  • 相关阅读:
    jsp大文件(视频)上传问题
    python多版本的pip共存问题解决办法
    buntu系统安装rpm包的方法
    如何查看linux是32位还是64位
    python的if else
    python获取列表唯一值
    python列表转数组
    python文件操作write与writelines的区别
    python中字符串str的strip()方法
    ubuntu16.04安装cloudcompare及打开方法
  • 原文地址:https://www.cnblogs.com/Marydon20170307/p/13690009.html
Copyright © 2020-2023  润新知