从log4j切换到logback后项目无法启动

1、背景

有个旧项目之前使用的是log4j2来打印日志的,因为某些原因,同事想换成logback。

换成logback改动也很简单,大致就一下2步:

  1. 删除log4j2.xml配置,新增logback.xml配置。剔除掉log4j相关的jar

  2. 引入slf4j (其实之前使用log4j2的时候就已经引入了,只是有些地方写法不规范),

    代码【import org.apache.log4j.Logger】改成【import org.slf4j.Logger】(以及其他类似修改)

2、现象

全部改了之后,按道理说,应该就可以正常打印了。

但是启动发现,日志报错:

ERROR {org.springframework.web.context.ContextLoader:356} - Context initialization failed
java.lang.NoClassDefFoundError: org/apache/log4j/Logger
    at java.lang.Class.getDeclaredMethods0(Native Method)
    at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
    at java.lang.Class.getDeclaredMethods(Class.java:1975)
    at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:612)
    at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:524)
    at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:510)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.determineCandidateConstructors(AutowiredAnnotationBeanPostProcessor.java:241)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineConstructorsFromBeanPostProcessors(AbstractAutowireCapableBeanFactory.java:1069)
 
 ★小技巧:
 报错的日志比较多,甚至有些报错看起来有点莫名其妙。
 不要慌,先找到最早的案发现场日志,或者搜一下关键字。
 因为我们改的是日志,所以可以在报错信息中搜一下log/log4j 等关键字

3、问题排查

看到这里第一反应应该是有代码没改全了。全局搜一下log4j关键字,果然发现还有一处:

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
    ...
    <property name="filters" value="config,stat,log4j,wall" />    <!-- 这里的log4j 需要改成 slf4j -->
    ...
</bean>

DruidDatasource中定义了com.alibaba.druid.filter.logging.LogFilter,他有3个子类,分别对应不同的日志打印实现方式

  • com.alibaba.druid.filter.logging.Slf4jLogFilter
  • com.alibaba.druid.filter.logging.Log4jFilter
  • com.alibaba.druid.filter.logging.CommonsLogFilter

那我们怎么知道是配置成slf4j、Slf4j、还是Slf4jLogger呢?可以看这里druid源码文件【META-INF/druid-filter.properties】

druid.filters.default=com.alibaba.druid.filter.stat.StatFilter
druid.filters.stat=com.alibaba.druid.filter.stat.StatFilter
druid.filters.mergeStat=com.alibaba.druid.filter.stat.MergeStatFilter
druid.filters.counter=com.alibaba.druid.filter.stat.StatFilter
druid.filters.encoding=com.alibaba.druid.filter.encoding.EncodingConvertFilter
druid.filters.log4j=com.alibaba.druid.filter.logging.Log4jFilter
druid.filters.slf4j=com.alibaba.druid.filter.logging.Slf4jLogFilter
druid.filters.commonlogging=com.alibaba.druid.filter.logging.CommonsLogFilter
druid.filters.commonLogging=com.alibaba.druid.filter.logging.CommonsLogFilter
druid.filters.wall=com.alibaba.druid.wall.WallFilter
druid.filters.config=com.alibaba.druid.filter.config.ConfigFilter

无意中发现commonlogging这一行写重复了,哈哈,这个不是我拷贝重的,源码druid-1.0.18就是搞重复了!

改完之后,再启动项目,发现问题依旧啊!

4、问题分析

估计还是有别的地方写明了需要使用log4j,为了验证猜想,我设置了NoClassDefFoundError异常断点,再次debug启动。

进入断点的时候,就发现还有个 HttpSessionManager 代码中写死了【import org.apache.log4j.Logger;】

这个是个第三方的jar,代码是改不了的。就只能另寻他法了。

其实像这种情况,代码写死了使用log4j,想统一成slf4j,slf4j已经提供了解决方法。那就是引入log4j-over-slf4j。

使用log4j-over-slf4j取代log4j,这样log4j接口输出的日志就会通过log4j-over-slf4j路由到SLF4J上,这样即使系统(包含使用的第三方jar库,比如dubbo)都可以将日志最终路由到SLF4J上,进而集中输出

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>log4j-over-slf4j</artifactId>
    <version>1.7.1</version>
</dependency>

引入log4j-over-slf4j之后,再启动,就ok了~

5、问题延伸

再回过头看一下,log4j-over-slf4j到底给我们做了什么?

  1. 定义了【org.apache.log4j.Logger】对象,确保使用了log4j的老项目代码不至于编译不通过
package org.apache.log4j;

import org.slf4j.Marker;

public class Logger extends Category {
    ...
}
  1. 将【org.apache.log4j.Logger】的打印动作偷偷转移到slf4j上。

Logger继承自Category,并且实现了info、warn、error等打印日志的方法

package org.apache.log4j;

import java.util.Enumeration;
import org.apache.log4j.helpers.NullEnumeration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.Marker;
import org.slf4j.MarkerFactory;
import org.slf4j.spi.LocationAwareLogger;

public class Category {
    private static final String CATEGORY_FQCN = Category.class.getName();
    private String name;
    protected Logger slf4jLogger;
    private LocationAwareLogger locationAwareLogger;
    private static Marker FATAL_MARKER = MarkerFactory.getMarker("FATAL");

    Category(String name) {
        this.name = name;
        this.slf4jLogger = LoggerFactory.getLogger(name);
        if (this.slf4jLogger instanceof LocationAwareLogger) {
            this.locationAwareLogger = (LocationAwareLogger)this.slf4jLogger;
        }
    }
    
    public Level getEffectiveLevel() {
        if (this.slf4jLogger.isTraceEnabled()) {
            return Level.TRACE;
        } else if (this.slf4jLogger.isDebugEnabled()) {
            return Level.DEBUG;
        } else if (this.slf4jLogger.isInfoEnabled()) {
            return Level.INFO;
        } else {
            return this.slf4jLogger.isWarnEnabled() ? Level.WARN : Level.ERROR;
        }
    }
    
    public void info(Object message) {
        this.differentiatedLog((Marker)null, CATEGORY_FQCN, 20, message, (Throwable)null);
    }
    
    void differentiatedLog(Marker marker, String fqcn, int level, Object message, Throwable t) {
        String m = this.convertToString(message);
        if (this.locationAwareLogger != null) {
            this.locationAwareLogger.log(marker, fqcn, level, m, (Object[])null, t);
        } else {
            switch(level) {
            case 0:
                this.slf4jLogger.trace(marker, m);
                break;
            case 10:
                this.slf4jLogger.debug(marker, m);
                break;
            case 20:
                this.slf4jLogger.info(marker, m);
                break;
            case 30:
                this.slf4jLogger.warn(marker, m);
                break;
            case 40:
                this.slf4jLogger.error(marker, m);
            }
        }
    }            
} 

其实,类似的还有【jcl-over-slf4j】也是起到相同的作用。

例如:把Commons logging,log4j和java.util.logging桥接到SLF4J,底层使用logback的case。其他示例

本文转载于网络 如有侵权请联系删除

相关文章

  • “C++继任者”火到GitHub趋势榜一,C++之父:规范不足,无法评价

    Alex发自凹非寺 量子位|公众号QbitAI今年的CPPNorthC++大会上,谷歌宣布了一门新的编程语言Carbon,并称其将是“C++的继任者”。谷歌将其在GitHub上开源。虽然这个语言目前还处于实验阶段,但还是很快吸了引众多程序员前来围观,还一度登上了GitHub趋势榜第一,现已收获标星21.3k。对于谷歌方开发者称Carbon是C++的继承者一事,有国外媒体询问了C++之父BjarneStroustrup的看法,老爷子表示:这些年总是有新的语言试图成为C++的继承者,我欢迎对编程语言和编程风格进行实验; 但Carbon太新且规范不足,我无法真正做出有意义的技术评论。而通常在不开发全新语言规则、库和管理方案的情况下,很难提供C++的替代方案。所以谷歌团队为什么非要搞一个C++“替代版”而不是继续完善现有的C++?毕竟他们自己内部都在广泛使用这个语言。为什么不去升级C++?对此,带领团队开发Carbon的谷歌工程师钱德勒·卡鲁斯(ChandlerCarruth)解释称,C++至今已有40岁了,其自身的很多问题困扰着现在的开发人员。数十年来,C++已积累了许多技术负债。其维护者优

  • FastAPI(六十六)实战开发《在线课程学习系统》接口开发--用户登陆接口开发

    前言我们上一次分享了实战FastAPI(六十五)实战开发《在线课程学习系统》接口开发--用户注册接口开发,这次我们分享实际开发--用户登陆接口开发。正文我们先来梳理下逻辑 1.查询用户是否存在 2.校验密码是否正确 3.密码校验失败记录失败次数 4.失败次数大于10次,当天不能登陆 5.密码校验通过产生对应的token返回复制接着我们去设计pydantic,用于校验用户登陆classUserLogin(UserBase): password:str复制这里我们继承的是之前的UserBase。 对应操作数据库的curd我们用之前注册的时候使用的get_user_username即可。我们把密码输入失败和token放在redis中,那么redis对应的配置。 config.py配置 redishost='127.0.0.1' redisport='6379' redisdb=0复制我们在main.py增加配置 fromfastapiimportFastAPI fromaioredisimportcreate_redis_pool,Redis from

  • netty案例,netty4.1中级拓展篇四《Netty传输文件、分片发送、断点续传》

    前言介绍1、在实际应用中我们经常使用到网盘服务,他们可以高效的上传下载较大文件。那么这些高性能文件传输服务,都需要实现的分片发送、断点续传功能。 2、在Java文件操作中有RandomAccessFile类,他可以支持文件的定位读取和写入,这样就满足了我们对文件分片的最基础需求。 3、Netty服务端启动后,可以向客户端发送文件传输指令;允许接收文件、控制读取位点、记录传输标记、文件接收完成。 4、为了保证传输性能我们采用protostuff二进制流进行传输。 5、读取文件的时候需要注意,我们设定byte[1024]为默认读取范围,但当读取到最后的时候可能不足1024个字节,就会出现空字节。这个时候需要去掉空字节,否则我们的文件写入会多额外信息,导致文件不能打开{zip、war、exe、jar等}。开发环境1、jdk1.8【jdk1.7以下只能部分支持netty】 2、Netty4.1.36.Final【netty3.x4.x5每次的变化较大,接口类名也随着变化】代码示例itstack-demo-netty-2-04 └──src ├──main │└──java │└──org.it

  • Linux Shell 基础

    接触过一些shell脚本,做服务端运维时也时常用到,是时候专门学习一下了。基础HereScript使用_EOF_将多行语句作为单句,避免转义字符的麻烦:#echosecho"<html>"echo"<head>"echo"</head>"echo"</html>" echo"<html><head></head></html>" cat<<_EOF_<html><head></head></html>_EOF_复制VariablesRules:Namesmuststartwithaletter.Anamemustnotcontainembeddedspaces.Useunderscoresinstead.Youcannotusepunctuationmarks.#!/bin/bashtitle="SystemInformat

  • 质量管理体系五大核心工具

    来源:http://www.51testing.com/质量管理概述  质量管理是指在质量方面指挥和控制组织的协调的活动。质量管理,通常包括制定质量方针和质量目标以及质量策划、质量控制、质量保证和质量改进。 质量管理五大工具,也称品管五大工具。包括:  1.统计过程控制(SPC,StatisticalProcessControl);  2.测量系统分析(MSA,MeasureSystemAnalyse);  3.失效模式和效果分析(FMEA,FailureMode&EffctAnalyse);  4.产品质量先期策划(APQP,AdvancedProductQualityPlanning);  5.生产件批准程序(PPAP,ProductionPartApprovalProcess)。1、统计过程控制(SPC)  SPC是一种制造控制方法,是将制造中的控制项目,依其特性所收集的数据,通过过程能力的分析与过程标准化,发掘过程中的异常,并立即采取改善措施,使过程恢复正常的方法。  实施SPC的目的:  对过程做出可靠的评估;  确定过程的统计控制界限,判断过程是否失控和过程是否有能

  • 【Kubernetes系列】第1篇 架构及组件介绍

    1. Kubernetes简介Kubernetes是谷歌开源的容器集群管理系统,是Google多年大规模容器管理技术Borg的开源版本,主要功能包括: 基于容器的应用部署、维护和滚动升级负载均衡和服务发现跨机器和跨地区的集群调度自动伸缩无状态服务和有状态服务 广泛的Volume支持 插件机制保证扩展性Kubernetes发展非常迅速,已经成为容器编排领域的领导者。2. Kubernetes架构及组件介绍2.1kubernetes架构Kubernetes架构如图所示:Kubernetes主要由以下几个核心组件构成:etcd保存整个集群的状态;apiserver提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制;controllermanager负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;scheduler负责资源的调度,按照预定的调度策略将实例(Pod)调度到相应的主机上;kubelet负责维护容器的生命周期,同时也负责存储卷和网络的管理;containerruntime负责镜像管理以及容器的真正执行,在我们系统中指的是Dockerkube-prox

  • 「体育大数据」分析解读NBA背后的大数据

    从古希腊、古罗马到日不落帝国,到当今的美利坚合众国,自古以来强盛的王朝似乎从来都是和发达的体育分不开的。但是身处科技、金融、军事、体育强国的美国现在似乎是把体育玩到了一个新的境界,那就是:“大数据驱动的体育”。NBA是美国各个职业体育中的佼佼者,虽然在总营业额上次与美式足球NFL和职业棒球MLB列第三位,但是由于所需要的球员数目远远少于前面二者,NBA球员的年平均工资(515万美金,2012年数据),中位工资(230万美金)都远远高于所有职业体育项目。NBA的成功商业运作背后有着非常成功的IT支持。经常看NBA比赛的朋友一定知道,NBA比赛是一场视+听的盛宴,“视”不用多说,高清分辨率,多镜头多视角,精彩镜头慢动作回放等等,依赖最专业的摄像设备。“听”的部分呢?除了解说员熟悉的声音魅力,本身的体育经验和素养之外,在NBA比赛的解说中充满了有趣的、智慧的有关球队、球员,球赛的知识,让大家有“如数家珍”的感觉,例如:在圣诞节的NBA比赛中,解说员会告诉我们从1947年开始NBA圣诞节特别节目开始,纽约尼克斯队48次出现在圣诞节比赛中,洛杉矶湖人队39次,波士顿凯尔特人队29次参与圣诞比赛。

  • Shiro中的授权问题

    在初识Shiro一文中,我们对Shiro的基本使用已经做了简单的介绍,不懂的小伙伴们可以先阅读上文,今天我们就来看看Shiro中的授权问题。 Shiro中的授权,大体上可以分为两大类,一类是隐式角色,还有一类是显式角色。我们来分别看下。隐式角色隐式角色是一种基于角色的访问权限控制,它在使用的过程中,我们直接判断相应的Subject是否是某一种角色,进而判断该Subject是否具备某种权限,比如下面一个例子:定义用户在ini文件中定义用户和对应的角色:[users] zhang=123,role1,role2 wang=123,role1复制两个用户,zhang用户具有role1、role2两种角色,wang用户具有role1一种角色。判断用户是否具备某种角色先来个方法用来执行登录操作,如下:privatevoidlogin(StringiniFile,Stringusername,Stringpassword){ Factory<SecurityManager>factory=newIniSecurityManagerFactory(iniFile); SecurityMa

  • 川普PK希拉里,谁演讲技术更好?这里有一个AI做的测试

    来源:foxnews.com作者:BrookeCrothers编译:刘小芹【新智元导读】最近Trint公司做了一个测试,用它的AI软件对特朗普、克林顿、奥巴马等14名有影响力的政界人物的演讲进行语音转文本测试,目的是看看谁的演讲是AI最容易理解的。结果表明,前国务卿希拉里·克林顿排名第二,特朗普以97.89%正确率排在倒数第四名。尽管人工智能和机器学习的技术已经存在了几十年,但直到过去几年,它才开始获得主流的认可。例如,iPhone自2011年起内置了智能助理Siri,用于理解语音。Android设备有GoogleAssistant和一个名为“语音输入”的语音转文本工具,可以与谷歌文档一起使用。Trint公司提供基于AI的软件,用于转录录制的音频,能够在几分钟内以低成本返回转录文本,正确率达到98%。但是,转录一个政治家的言论是另外一回事。“Trint不是一个听写软件,而是一种利用大量训练数据工作的语音转文本技术,”Trint公司CEO兼创始人JeffKofman说。人类是这个等式的一部分。他补充说:“Trint是一个人机混合模型:我们突破了AI技术的界限,让人类在需要的时候做最后一步

  • 美大学推出人工智能助教

    2016年5月9日,美国乔治亚理工学院发布消息称,该校推出了人工智能助教。该校计算学院的教授AshokGoel每学期都开设基于知识的人工智能(KBAI)课程,这是佐治亚理工学院计算机科学在线硕士项目的核心课程。Goel估计,每次他开设这项课程,他的300名学生会在网上论坛发布大约10000则消息——他和他的八个助教(TA)根本无法处理这么多问题。这就是Goel在本学期增加了第九名助教的原因。她的名字叫吉尔.沃森(JillWatson),而她与世界上任何其他助教都不一样。事实上,吉尔是在IBM的Watson平台上实现的计算机程序——一个虚拟助教。“全世界有很多在线课程,但它们都受到留不住学生的困扰,”Goel说,“许多学生辍学的主要原因之一是他们没有得到足够的教学支持。我们创造了吉尔,使其作为一种能够提供更快回答和反馈的方式。”Goel和他在佐治亚理工的研究生团队从2015年开始构建这个虚拟助教。他们跟踪了自2014年秋季该课程开设以来,所有曾在KBAI中提出的问题(共约4万个问题)。然后,他们开始向吉尔输入问题和答案。“在线课程一个的秘密是,你的学生越多,问题就会越多,但不同问题的数量

  • 【深入解析】DRM和read-mostly locking

    作者简介何剑敏OracleACS华南区售后团队,首席技术工程师。多年从事第一线的数据库运维工作,有丰富项目经验、维护经验和调优经验,专注于数据库的整体运维。1了解DRM(DynamicResourceRemastering)讲DRM(DynamicResourceRemastering),首先一定说说cachefusion的机制,cachefusion是在8iOPS中引入,解决的目的是原来在OPS中,instanceA读某个block,instanceB也要读时,instanceA必须把该block写入到磁盘,然后由instanceB从磁盘读取。当时在8i中引入cachefusion,使得“读”能跨节点的“读”,但是“写”(或者说修改),还是要写入到磁盘,再在另一个节点读出来,然后修改。在9i中,“写”得到了改进,脏块也能跨节点的传输。这就是常说的Write/WriteCacheFusion。10gR1引入DRM,但当时的DRM功能很有限,只有在instance变化的时候(如instance被踢出集群,instance加入集群)才进行资源的remastering。10gR2引入Affi

  • 故障分析 | MySQL 启动遭遇 Permission denied 失败案例一则

    作者:任坤现居珠海,先后担任专职Oracle和MySQLDBA,现在主要负责MySQL、mongoDB和Redis维护工作。本文来源:原创投稿*爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。背景OS:centos7.9MySQL:5.7首次使用某海外云,申请云主机自建mysql,servicemysqldstart启动报错Jobformysqld.servicefailedbecausethecontrolprocessexitedwitherr orcode.See"systemctlstatusmysqld.service"and"journalctl‐xe"fordet ails.复制诊断journalctl-xe查看详细日志。Oct0906:57:42mysqld[30507]:2022‐10‐09T06:57:42.953987Z0[Warning]Ca n'tcreatetestfile/data/var/.lower‐test Oct0906:57:42mysqld[30507]:2022‐1

  • 监控ckeditor内容变化,删除编辑器内图片,ueditor同样适用

    letbody=document.querySelector("iframe").contentDocument.body; letobserver=newMutationObserver((mutationsList,observer)=>{ for(letmutationofmutationsList){ if(mutation.removedNodes.length>0){ console.log(mutation); console.log(mutation.removedNodes) } } }); observer.observe(body,{subtree:true,childList:true});复制 以上是监控代码; 删除图片的代码没有包含在内,自己控制

  • 开始使用树莓派

    树莓派上手 目录树莓派上手烧录系统第一次无屏幕启动开启ssh服务设置WIFI局域网SSH登录Bonjour互联网登录SSH 烧录系统 首先需要将操作系统烧录到TF卡 软件balenaEtcher 读卡器,TF卡 官网下载好系统镜像镜 第一次无屏幕启动 对于大多数玩家并没有闲置的显示器,因此第一次启动,并连接到网络便成为了一个麻烦的问题。首先我们要开启树莓派的SSH服务,并提前设置好wifi账户密码。以后每次开机树莓派都会自动连接这个wifi。稍后再介绍如何为树莓派设置多个备用wifi。 将IF放入读卡器。插入USB电脑端如下显示,当前TF卡内有两个分区,注意我们接下来的操作都在boot分区 开启ssh服务 在boot根目录下创建ssh空文件 touchssh 复制 设置WIFI 同样在根目录下创建文件wpa_supplicant.conf,并写入如下内容 vimwpa_supplicant.conf 复制 country=CN ctrl_interface=DIR=/var/run/wpa_supplicantGROUP=netdev update_

  • 把 Notepad++ 打造成一款易用的C#脚本编辑器

    以前一直用Linqpad在写小程序脚本,但是Linqpad自动完成功能要收费,且不开源,这样的话就不方便扩展了。今天在 http://csscriptnpp.codeplex.com/ 发现了一款C#自动完成的插件:CS-Script for Notepad++(http://csscriptnpp.codeplex.com/),遂下载下来试用。 试用感觉很不错,不过还有点小缺陷: (1)不支持指针的自动完成(这个一般人用不上,但图像开发需要!); (2)显示自动完成列表的快捷键是 Ctrl+Space,很不爽。 于是,下载了它的源码,进行了修改,将显示自动完成列表的快捷键修改为 Ctrl+/,并且,支持指针的自动完成。 环境要求:需要.Net 4.0环境。修改后的插件文件及源码下载地址: https://files.cnblogs.com/xiaotie/CSScriptNpp-Modify.zip 下载后,将解压缩后的插件文件安装到Notpad++的plugin目录下,重启Notpad++即可。安装后的

  • YDWE Keynote

    【YDWEKeynote】 1、使用YDWE制作的地图,需要在禁用黑色阴影、迷雾。否则进入游戏将漆黑一片,什么都看不到。    2、 3、 4、 5、 6、

  • 解决 Jackson反序列化 Unexpected token ... , expected VALUE_STRING: need JSON String that contains type id (for subtype of ...)

    首先检查是否是 objectMapper.enableDefaultTyping(); 的受害者。优先考虑删除该配置。   使用Jackson把数组的json字符串反序列化为List时候报了个JsonMappingException。 java.lang.UnsupportedOperationException:com.fasterxml.jackson.databind.JsonMappingException:Unexpectedtoken(START_OBJECT),expectedVALUE_STRING:needJSONStringthatcontainstypeid(forsubtypeofjava.util.List)at[Source:[......   找到问题代码,粗看似乎没什么问题? List<MyObject>objectList=objectMapper.readValue(jsonString,newTypeReference<List<MyObject>>(){}); //js

  • (6)MSP430F5529 统一时钟系统UCS

    实验二:将MCLK和SMCLK配置为XT1(F5529的XT1为32.768KHZ) /*1.配置IO口5.4和5.5为XT1功能。*/ /*2.配置XCAP为XCAP_3,即12PF的电容。*/ /*3.清除XT1OFF标志位。*/ /*4.等待XT1起振。*/ #include<msp430.h>   void main(void){      P1SEL|=BIT0;P1DIR|=BIT0;//测量ACLK用      P2SEL|=BIT2;P2DIR|=BIT2;//测量SMCLK用      P7SEL|=BIT7;P7DIR|=BIT7;//测量MCLK用      P5SEL|=BIT4|BIT5;      //配置为XT1功能,电路板上晶振接于这两脚      

  • iOS11适配tableView顶部空白

    MJRefresh和继承自UIScrollView的视图的iOS11适配 背景:前两天一个同行问我了一个问题: 问题 还有就是说如果你使用了MJRefresh进行刷新,并且你隐藏了导航栏,就会出现下拉刷新错乱的问题。这跟我这哥们问的问题是一种类型的,因为iOS11上废除了automaticallyAdjustsScrollViewInsets这个方法,使用UIScrollView'scontentInsetAdjustmentBehavior来代替,解决办法就是一段代码: OC: if(@available(iOS11.0,*)){ self.collectionView.contentInsetAdjustmentBehavior=UIScrollViewContentInsetAdjustmentNever; }else{ self.automaticallyAdjustsScrollViewInsets=NO; } 复制 swift: if#available(iOS11.0,*){ tableView.contentInsetAdjustmentBehavio

  • 申论大纲

    一、申论能力考查 申论考试大纲阅读理解能力——要求全面把握给定资料的内容,准确理解给定资料的含义,准确提炼事实所包含的观点,并揭示其所反映的本质问题。综合分析能力——要求对给定资料的全部或部分的内容、观点或问题进行分析和归纳,多角度地思考资料内容,作出合理的推断或评价。提出和解决问题能力——要求借助自身的实践经验或生活体验,在对给定资料理解分析的基础上,发现和界定问题,作出评估或权衡,提出解决问题的方案或措施。文字表达能力——要求熟练使用指定的语种,运用说明、陈述、议论等方式,准确规范、简明畅达地表述思想观点   二、答题要素与基本题型 1.要素:问题、原因、影响(意义、危害)、对策等。 (1)问题:是指不好的事,这是申论考试中最基本的要素(2)原因:在生活中,原因就是为什么发生了。(3)影响:其本质是一种结果,即做了一件事的结果。  ①做了一件事有好的结果,叫做意义。  ②做了一件事有不好的结果,叫做危害。  ③例如报了一个公务员培训班,一直学习、听课,好的结果是有利于大家上岸、获得成功,这就是好处、意义;     坏的结果,可能是浪费了时间,造成了经济

  • Jquery实现下拉列表联动

    在查询与列表显示的时候经常用到联动列表显示,比如一级选项是国家,二级选项是省,三级是市,这样的联动是联系的实时导出的,比如你不可能选择了四川省却在三级联动栏中出现济南市,这样的联动实现方法如下: 效果图示: 实现源代码: <!DOCTaYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><htmlxmlns="http://www.w3.org/1999/xhtml"><head><metahttp-equiv="Content-Type"content="text/html;charset=utf-8"/><title></title><metaname="keywords"content="keywords"/><metaname="description"content="description"/></head&

相关推荐

推荐阅读