Could not initialize class com.sendinfo.usr.util.SysCacheUtil 问题解决

  1. 描述现象,启动报错
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mqServiceFactory' defined in class path resource [applicationContext.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.sendinfo.mq.service.impl.MqServiceFactory]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: Could not initialize class com.sendinfo.usr.util.SysCacheUtil
		at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:288)
		at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1035)
		at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:939)
		at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485)
		at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
		at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
		at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
		at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
		at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
		at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:322)
		... 77 more
	Caused by: java.lang.NoClassDefFoundError: Could not initialize class com.sendinfo.usr.util.SysCacheUtil

看上去很奇怪,SysCacheUtil 类明明是存在的怎么会NoClassDefFoundError,不过后半句Could not initialize class com.sendinfo.usr.util.SysCacheUtil 也给出了说明,是因为类没有初始化成功所以才NoClassDefFoundError

  1. 看 SysCacheUtil 类
public class SysCacheUtil {

   private static final MemcachedClient MEMCACHED_CLIENT;

// 问题出在这里,UserConfig.SYSCACHECLIENT的值返回为null,静态块就会null指针异常,由于static块在类加载的时候就执行,执行失败类加载也就失败
   static {
      String client =UserConfig.SYSCACHECLIENT;
      String str[] =client.split(":");
      if(str.length>1){
         Integer port=11211;
         try {
            port=Integer.valueOf(str[1].trim());
         } catch (Exception e) {
            System.out.println("端口默认为:12222");
            e.printStackTrace();
         }
         MEMCACHED_CLIENT= new MemcachedClient(str[0], port);
      }else if(str.length>0){
         MEMCACHED_CLIENT= new MemcachedClient(str[0], 12222);
      }else{
         MEMCACHED_CLIENT= new MemcachedClient("cache.memcached.server.2", 12222);
   }}
   
   /**
    * 设置数据到MemCached中,如果已经存在则覆盖
    * @param key 键
    * @param value 值
    * @return
    */
   public static void addSysOption(String key, Object value, int expire) throws Exception {
      MEMCACHED_CLIENT.set(key, value,expire);
   }
   
   /**
    * 获取memcached
    * @return
    */
   public static String getSysOption(String key) throws Exception{
         String value = MEMCACHED_CLIENT.get(key);
         if (StringUtil.isNotTrimBlank(value)) {
            return value;
         }
         return null;
   }

   /**
    * 删除memecache值
    * @param key
    */
   public static void delSysOption(String key) throws Exception{
      MEMCACHED_CLIENT.delete(key);
   }
}
  1. UserConfig 的SYSCACHECLIENT 是怎么赋值的? 其实是通过set注入的
<!-- 工作台配置等 -->
	<bean id="userConfig" class="com.sendinfo.usr.util.UserConfig" lazy-init="false">
		<property name="sysCacheClient" value="${SysCache.client}" />
		<property name="weixinDev" value="${weixin.Dev}" />
		<property name="platformAppCode" value="${platform.appCode}" />
		<property name="platformAppKey" value="${platform.appKey}" />
		<property name="platformDomain" value="${platform.domain}" />
		<property name="sysPictureUrl" value="${sys.Picture.Url}" />
	</bean>

但是userConfig初始化的顺序迟于MqServiceFactory ,所以UserConfig.SYSCACHECLIENT静态变量的值还是空的
4. 解决方法,将SysCacheUtil 的初始化静态块逻辑,放到一个方法里,并

private static MemcachedClient getMemcaheClient() {
		if(MEMCACHED_CLIENT != null){
			return MEMCACHED_CLIENT;
		}

		if(MEMCACHED_CLIENT == null){
			synchronized (SysCacheUtil.class){
				if(MEMCACHED_CLIENT == null){
				    // 去掉对UserConfig的依赖,直接获取系统属性
					// String client = UserConfig.SYSCACHECLIENT;
					String client = System.getProperty("SysCache.client")
					String str[] = client.split(":");
					if (str.length > 1) {
						Integer port = 11211;
						try {
							port = Integer.valueOf(str[1].trim());
						} catch (Exception e) {
							System.out.println("端口默认为:12222");
							e.printStackTrace();
						}
						MEMCACHED_CLIENT = new MemcachedClient(str[0], port);
					} else if (str.length > 0) {
						MEMCACHED_CLIENT = new MemcachedClient(str[0], 12222);
					} else {
						MEMCACHED_CLIENT = new MemcachedClient("cache.memcached.server.2", 12222);
					}
				}
			}
		}
		return MEMCACHED_CLIENT;
	}

本问题涉及到spring bean初始化顺序, java 类加载相关知识点, 基本是绕过了这两个点解决了本问题

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值