开发日记——第一个单例模式

xml文件

<root>
	<lable>
		<name>中心业务概览</name>
		<url>
			http://202.189.3.29:8642/MicroStrategy/servlet/mstrWeb?Server=WIN-OQRGOM8UCK1&amp;Project=FXQ2&amp;Port=0&amp;evt=2048001&amp;src=mstrWeb.2048001&amp;documentID=38DFE98F4E39C8DF598EFEB85ED8C064&amp;currentViewMedia=1&amp;visMode=0&amp;hiddensections=header,path,dockTop,dockLeft,footer
		</url>
		<depts>
			<dept>FXQ013</dept>
			<dept>FXQ003</dept>
		</depts>
		<menus>
			<menu>lhfx</menu>
			<menu>sbxsk</menu>
		</menus>
	</lable>

	<lable>
		<name>大额交易报告接收总量与趋势</name>
		<url>
			http://202.189.3.29:8642/MicroStrategy/servlet/mstrWeb?Server=WIN-OQRGOM8UCK1&amp;Project=FXQ2&amp;Port=0&amp;evt=2048001&amp;src=mstrWeb.2048001&amp;documentID=B86F3F8246690F03B7EBF4B8FE90A249&amp;currentViewMedia=1&amp;visMode=0&amp;hiddensections=header,path,dockTop,dockLeft,footer
		</url>
		<depts>
			<dept>FXQ013</dept>
			<dept>FXQ003</dept>
		</depts>
		<menus>
			<menu>lhfx</menu>
			<menu>sbxsk</menu>
		</menus>
	</lable>

	
</root>

第一版

静态块加载解析xml

/**
 * 东华软件
 */
package com.dh.monitor.util.microstrategy;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.informix.util.stringUtil;

/**
 * @author lidehu
 * @date 2018年11月21日
 * @description 
 */
@Component
public class MicrostrategyUtils {
	
	private static final Map<String, List<Map<String, String>>> map = new HashMap<>();

	static {
		parseXml();
	}
	
	/**
	 * 根据菜单和部门编码获取访问mstr对应的链接
	 */
	public static List<Map<String, String>> loadLable(String menu, String deptCode) {
		return map.get(getKey(menu, deptCode));
	}
	
	/**
	 * 通过xml路径名解析xml文件并存在内存中
	 */
	private static void parseXml() {
		SAXReader reader = new SAXReader();
		try {
			//解析xml文件
//			String file = new MicrostrategyUtils().getClass().getClassLoader().getResource("config/microstrategy.xml").getFile();
			String file = System.getProperty("user.dir")+File.separator+"config"+File.separator+ "config"+File.separator+"microstrategy.xml";
            Document document = reader.read(new File(file));
            Element root = document.getRootElement();
            List<Element> elements = root.elements();
            for(Element lable : elements) {
            	String name = lable.element("name").getStringValue().trim();
            	String url = lable.element("url").getStringValue().trim();
            	List<String> depts =  new ArrayList<>();
            	List<String> menus =  new ArrayList<>();
            	for(Element dept : lable.element("depts").elements())
            		depts.add(dept.getStringValue().trim());
            	for(Element menu : lable.element("menus").elements())
            		menus.add(menu.getStringValue().trim());

            	//分组并存入内存中
            	Map<String, String> loaclMap = new HashMap<>();
        		loaclMap.put("name", name);
        		loaclMap.put("url", url);
        		for(String dept : depts) {
        			for(String menu : menus) {
        				String key = getKey(menu, dept);
        				if(map.containsKey(key)) {
        					List<Map<String, String>> list = map.get(key);
        					list.add(loaclMap);
        					map.put(key, list);
        				} else {
        					List<Map<String, String>> list = new ArrayList<>();
        					list.add(loaclMap);
        					map.put(key, list);
        				}
        			}
        		}
        		
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        }
	}
	
	private static String getKey(String menu, String dept) {
		return menu+"/"+dept;
	}
	
}

项目启动时执行parseXml方法,不能实现延迟加载。并且不能注入静态属性。因为静态块加载时间先于spring容器扫描bean。现在考虑用静态内部类单例模式实现延迟加载和属性注入。

第二版

/**
 * 东华软件
 */
package com.dh.monitor.util.microstrategy;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.informix.util.stringUtil;

import net.bytebuddy.agent.builder.AgentBuilder.InitializationStrategy.SelfInjection.Lazy;

/**
 * @author lidehu
 * @date 2018年11月21日
 * @description 
 */
public class MicrostrategyUtils {
	
	private static final Map<String, List<Map<String, String>>> map = new HashMap<>();
	
	private static int cntInstance = 0;
	
	private MicrostrategyUtils() {
		synchronized(this) {
			if(++cntInstance > 1) {
				throw new RuntimeException("非法反射调用");
			}
		}
		parseXml();
	}
	
	/*
	 * 静态内部类单例模式
	 * @author lidehu
	 * @date 2018年11月22日
	 */
	private static class LazyParseXml {
		private static MicrostrategyUtils instance = new MicrostrategyUtils();
	}
	
	private static MicrostrategyUtils getInstacne() {
		return LazyParseXml.instance;
	}
	
	// 通过xml路径名解析xml文件并存在内存中
	private void parseXml() {
		SAXReader reader = new SAXReader();
		try {
			//解析xml文件
			String file = getClass().getClassLoader().getResource("config/microstrategy.xml").getFile();
//			String file = System.getProperty("user.dir")+File.separator+ "config"+File.separator+"microstrategy.xml";
            Document document = reader.read(new File(file));
            Element root = document.getRootElement();
            List<Element> elements = root.elements();
            for(Element lable : elements) {
            	String name = lable.element("name").getStringValue().trim();
            	String url = lable.element("url").getStringValue().trim();
            	List<String> depts =  new ArrayList<>();
            	List<String> menus =  new ArrayList<>();
            	for(Element dept : lable.element("depts").elements())
            		depts.add(dept.getStringValue().trim());
            	for(Element menu : lable.element("menus").elements())
            		menus.add(menu.getStringValue().trim());

            	//分组并存入内存中
            	Map<String, String> loaclMap = new HashMap<>();
        		loaclMap.put("name", name);
        		loaclMap.put("url", url);
        		for(String dept : depts) {
        			for(String menu : menus) {
        				String key = getKey(menu, dept);
        				if(map.containsKey(key)) {
        					List<Map<String, String>> list = map.get(key);
        					list.add(loaclMap);
        					map.put(key, list);
        				} else {
        					List<Map<String, String>> list = new ArrayList<>();
        					list.add(loaclMap);
        					map.put(key, list);
        				}
        			}
        		}
        		
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        }
	}
	
	private static String getKey(String menu, String dept) {
		return menu+"/"+dept;
	}
	
	
	/**
	 * 根据菜单和部门编码获取访问mstr对应的链接
	 */
	public static List<Map<String, String>> loadLable(String menu, String deptCode) {
		if(LazyParseXml.instance == null) {
			getInstacne();
		}
		return map.get(getKey(menu, deptCode));
	}
	
}

第二版实现了延迟加载,并考虑到非法反射调用私有构造器,和多线程非法反射调用。

运行时,因为一个大意class上的@Component没有去掉,结果进入我自定义的异常。发现spring在加载时竟然会反射调用私有构造器。然后测试了一下,果然是的。

 去掉注解没有了。

但是项目通过jenkins构建后又踩一个坑,运行时程序出错,我的静态内部类找不到。

最后因为jenkins构建出错的原因,只能退回第一版,其实这里用延迟加载没有必要,因为加载后不用回收。

by the way:单例模式destory方法需要用到GC。

静态内部类保证线程安全请见:https://blog.csdn.net/mnb65482/article/details/80458571

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值