如果开发这个功能的同事没有接口意识、抽象思维,那这种暴露实现细节的命名方式就不足为奇了,毕竟最初我们只考虑将图片存储在阿里云上。...我们对上传(或下载)流程进行封装,对外提供一个包裹所有上传(或下载)细节的方法,给调用者使用。 为实现类定义抽象的接口。具体的实现类都依赖统一的接口定义,遵从一致的上传功能协议。...使用者依赖接口,而不是具体的实现类来编程。 我们按照这个思路,把代码重构一下。...而且,在设计接口的时候,我们要多思考一下,这样的接口设计是否足够通用,是否能够做到在替换具体的接口实现的时候,不需要任何接口定义的改动。 是否需要为每个类定义接口?...从这个设计初衷上来看,如果在我们的业务场景中,某个功能只有一种实现方式,未来也不可能被其他实现方式替换,那我们就没有必要为其设计接口,也没有必要基于接口编程,直接使用实现类就可以了。
3、注意:通过源代码发现,Serializable接口只是一个 标志接口: public interface Serializable { } 这个接口当中什么代码都没有。...2 Serializable接口起什么作用呢? 起到 标识 的作用,标志的作用,java虚拟机看到这个类实现了这个接口,可能会对这个类进行特殊待遇。...Serializable这个标志接口是给java虚拟机参考的,java虚拟机看到这个接口之后,会为该类自动生成一个序列化版本号。 3 序列化版本号有什么用呢? 区分两个类是否相同。...这个时候序列化版本就起上作用了。 对于java虚拟机来说,java虚拟机是可以区分开这两个类的,因为这两个类都实现了Serializable接口,都有默认的序列化版本号,他们的序列化版本号不一样。...6 结论 凡是一个类实现了Serializable接口,建议给该类提供一个固定不变的序列化版本号。 这样,以后这个类即使代码修改了,但是版本号不变,java虚拟机会认为是同一个类。
为了在StartupToolset示例中创建我们的工具窗,我们需要做下面的工作: 设计工具窗的界面 实现工具窗的功能 设置工具窗需要的资源 创建ToolWindowPane类,以便将这个工具窗嵌入到...正如我们在第4篇看到的那样,为了创建一个工具窗,我们至少需要两个类。...所以,把用户控件嵌入到IDE的关键,是去创建一个Window pane的类,这个类继承自ToolWindowPane,ToolWindowPane实现了IVsWindowPane接口。...COM类的形式被IDE调用,所以我们需要为它指定一个GUID。...在这个类的构造函数里,我们创建了一个CalculationControl控件的实例,并利用Window属性来返回该控件实例的Win32句柄。
摄影:产品经理 感谢小何的上等牛肉 当我们创建一个Python 类并初始化时,一般代码这样写: class People: def __init__(self, name): self.name...__(self): raise Exception('不能实例化这个类') kingname = People() kingname.say() 一旦初始化就会报错,如下图所示:...但是 在写 Mixins 类的时候,我们不会写__init__方法,也不会写类属性。并且 Mixin 类中的方法看起来更像是工具方法。 我们可以写很多个 Mixin 类,然后用一个子类去继承他们。...最后,我们对比一下抽象类(Abstract Class)、接口(Interface)和混入(Mixins)的区别: 抽象类: 包含一个或多个抽象方法。 允许包含状态(实例变量)和非抽象方法。...接口: 只能包含抽象方法。 混入: 不能包含状态(实例变量)。 包含一个或多个非抽象方法。
面试题: 什么是不可变类? 为什么String是不可变类?...如何创建一个不可变类 不可变类 当类的对象创建后,它的值就不可以再更改了 相比于可变对象,不可变对象有很多优势 不可变对象可以提高String Pool(字符串常量池)的效率和安全性。...,因为这样的话,如果变量改变了它的值,那么其它指向这个值的变量的值也会一起改变。 ---- 如果字符串是可变的,那么会引起很严重的安全问题。...譬如你想加载java.sql.Connection类,而这个值被改成了myhacked.Connection,那么会对你的数据库造成不可知的破坏。...如何创建一个不可变类 将类声明为final,所以它不能被继承 将所有的成员声明为私有的,这样就不允许直接访问这些成员 对变量不要提供setter方法 将所有可变的成员声明为final,这样只能对它们赋值一次
快速创建一个springboot项目 我们创建一个maven项目,看看和springboot项目的目录结构有什么区别?...以下是创建的maven项目 回顾 我们已经学习了spring springmvc mybatis,并且可以搭建ssm框架的项目 看具体系列: Spring框架(一) 为什么要学spring框架,这个框架里面有什么...所以现在就有了springboot框架,人家把这些配置文件给你封装好了,我们只要使用了这个springboot框架,很快就可以创建一个项目。...所以现在springboot就有了自己的一个配置文件,我们把那些数据写到这个springboot的配置文件里面就可以了。...以下是创建的maven项目 我们创建的maven项目,里面只是一个简单的目录结构,对于springboot项目,比我们创建的maven的项目多了一个启动类,还有就是springboot的依赖
目录 创建一个空的vue项目 安装element-ui插件 项目里面引入element-ui插件 将我们准备好的全局样式和字体放到对应的目录下 将我们准备的样式和字体引入到项目里面 创建登录页面 安装axios...创建一个空的vue项目 ?...以上就创建了一个空项目 在vscode软件里面打开 ? ? 点击上面的那个,就启动项目了, ? 以上就是启动成功的界面 ? 安装element-ui插件 打开官网 ? ?...安装成功,我们就可以看到 ? 项目里面引入element-ui插件 在main.js里面引入 ? 将我们准备好的全局样式和字体放到对应的目录下 ? ? 将我们准备的样式和字体引入到项目里面 ?...创建登录页面 在组件文件夹下创建一个登录的vue页面 ? 里面开始写东西 有了页面,开始写路由 ? 我们启动项目 ? ? 我们要访问跟目录,就到登录页面,可以重定向 ?
ckafka这个消费者参数配置后, 为什么Kafka rebalance时间好长, 超过一个小时 还没有完成问题描述:这个消费者参数配置后, 为什么Kafka rebalance时间好长, 超过一个小时...heartbeat_interval_ms这个值必须小于 session.timeout.ms,一般小于它的三分之一结果:修改heartbeat_interval_ms 后 relbance 时间快多了
为什么我们的项目里出现两个配置类继承WebMvcConfigurationSupport时,只有一个会生效。...大家基本遇到过一种情况,就是我配置类中已经配置了,为什么就是没有生效呢?...其中一种原因就是,自己写的配置类也继承了WebMvcConfigurationSupport,当项目出现两个配置类都继承该类时,只会讲第一个配置类生效,至于为什么,就是今天博主需要讲解的,我们必须了解一些...,第二个配置类重写的任何方法基本没什么用了,因为父类所有的bean已经在第一个配置类中解析扫描到了,就剩下如何去创建bean了。...我直接把这个问题用源码的方式讲解清楚,方便大家明白为什么配置两个WebMvcConfigurationSupport类,只有一个生效。我正在参与2024腾讯技术创作特训营最新征文,快来和我瓜分大奖!
swagger,自动的生成项目的api接口 springboot项目集成swagger的步骤: 1 创建一个springboot的项目 2 导入swagger的依赖 ?...以上是多了一个接口,但是现在 的问题是,我们在后端不管写几个接口,在swagger都会显示,这个是不好的,我们现在相的是,可以控制显示的接口,想让哪个接口显示那么就让哪个接口显示,这个怎么做,这个就又要到...以上的配置是扫描包,但是现在我想要扫描一个类里面的一个方法,这个类里面有很多的方法 ? ?...2 我们希望上线的时候不使用这个swagger,开发的时候使用,这个咋处理 yml文件是一般项目里面有两个,一个是测试yml,一个是上线的yml,那么我们就需要在swagger配置类里面配置了,看看现在使用的是什么...也就是在swagger配置类里面获取当前的生产环境 现在有两个环境 ? ? 配置API分组 什么是api分组,我们先看swagger界面,最最有上面有一个这个。 ?
MyEclipse中,当我们写一个类实现一个接口时,会自动生成重写该接口的方法,但是,方法的参数提示不够好,如下图所示: ? 说明我们没有导入相应的源码包,如何证明我们没有导入源码呢?...例如:我们按住Ctrl后点击 BeanPostProcessor,查看源码,如下图所示: ? 由上图可知,说明我们没有导入相应的源码包,那我们导入相应的源码包,我们看看效果: ? ?
接口和抽象类的选择: 既然接口是一种特殊的抽象类,那么在开发中应该如何选择呢? 优先选用接口 在既要定义子类行为,又要为子类提供公共的功能时,选择抽象类。...案例解释为什么需要工厂 回忆一下,以前时如何使用接口的,假设有一个接口叫Api,然后有一个实现类ApiImpl实现了它,在客户端怎么使用这个接口呢?...通常都是在客户端创建一个Api类型的ApiImpl的实例对象,然后通过这个对象来操作接口中的功能(方法)。 Api api = new ApiImpl(); // 调用Api接口中的功能。...,然后面向接口编程,从客户端的角度来看,它根本不知道具体的实现类是什么,也不知道是如何实现的,只知道通过工厂来获得了一个接口对象,然后通过这个接口来获取想要的功能。...使用反射+配置文件 核心逻辑: //创建一个Factory.properties的配置文件,其中ImplClass为配置内容 ImplClass = com.xxx.Impl;//类的全类名路径 用反射创建接口对象
为什么会有面向切面编程(AOP)?...我们知道Java是一个面向对象(OOP)的语言,但它有一些弊端,比如当我们需要为多个不具有继承关系的对象引入一个公共行为,例如日志、权限验证、事务等功能时,只能在在每个对象里引用公共行为。...如果要代理的方法很多,势必要为每一种方法都进行代理。再者,如果增加一个方法,除了实现类需要实现这个方法外,所有的代理类也要实现此方法。增加了代码的维护成本。那么要如何解决呢?答案是使用动态代理。...使用 JDK 生成的动态代理的前提是目标类必须有实现的接口。但这里又引入一个问题,如果某个类没有实现接口,就不能使用 JDK 动态代理。所以 CGLIB 代理就是解决这个问题的。...优秀的 Spring 框架把两种方式在底层都集成了进去,我们无需担心自己去实现动态生成代理。那么,Spring是如何生成代理对象的? 创建容器对象的时候,根据切入点表达式拦截的类,生成代理对象。
创建可被发现的bean 案例:使用CD与CD播放器来实现为什么有注入跟依赖。 ...CD:作为一个接口,定义了CD播放器对CD的一系列操作,同时将CD播放器与CD本身的耦合降到最低 public interface CompactDisc { void play(); } ...这个注解表明该类会作为组件类,并告知Spring要为这个类创建bean。...} 设置组件扫描的基础包 我们目前没有为@ComponentScan设置任何属性,默认会以配置类所在的包为基础包来扫描组件。 ... 注:@Configuration表明该类是一个配置类,该类应该包含Spring应用上下文中如何创建bean的细节。
创建格式如下: new 父类构造器(参数列表)|实现接口() { //匿名内部类的类体部分 } 在这里我们看到使用匿名内部类我们必须要继承一个父类或者实现一个接口...,当然也仅能只继承一个父类或者实现一个接口。...所以在mian方法中直接使用匿名内部类来创建一个Bird实例。 由于匿名内部类不能是抽象类,所以它必须要实现它的抽象父类或者接口里面所有的抽象方法。 ...二、注意事项 在使用匿名内部类的过程中,我们需要注意如下几点: 1、使用匿名内部类时,我们必须是继承一个类或者实现一个接口,但是两者不可兼得,同时也只能继承一个类或者实现一个接口。...为什么必须要为final呢? 首先我们知道在内部类编译成功后,它会产生一个class文件,该class文件与外部类并不是同一class文件,仅仅只保留对外部类的引用。
我们知道Java是一个面向对象(OOP)的语言,但它有一些弊端,比如当我们需要为多个不具有继承关系的对象引入一个公共行为,例如日志,权限验证,事务等功能时,只能在在每个对象里引用公共行为,这样做不便于维护...,代理对象的一个接口只服务于一种类型的对象,如果要代理的方法很多,势必要为每一种方法都进行代理。...IUserDao proxy = (IUserDao)new ProxyFactory(target).getProxyInstance(); 其实是JDK动态生成了一个类去实现接口,隐藏了这个过程:...但这里又引入一个问题,如果某个类没有实现接口,就不能使用JDK动态代理,所以Cglib代理就是解决这个问题的。 ...: 1.创建容器对象的时候,根据切入点表达式拦截的类,生成代理对象。 2.如果目标对象有实现接口,使用jdk代理。如果目标对象没有实现接口,则使用Cglib代理。
原型模式的基本介绍 原型模式是一种创建型模式。通过给出一个原型对象来指明所要创建的对象的类型,然后用复制这个原型对象的方法创建出更多同类型的对象。...意图 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。 结构 原型模式的基本结构如下: 这里涉及的参与者有如下几种: Prototype(抽象原型) 通常由一个接口或者抽象类实现。...为什么要使用Clone呢? 在Java中,使用clone()方法可以创建一个新的对象副本,对它进行修改不会影响原始对象。在某些情况下,使用clone()方法可以比创建新的对象更快。...如果要使克隆出来的对象和原始对象是独立的,我们需要采用深拷贝实现。 在本示例中,如果要实现深拷贝,我们需要让Question类也实现Cloneable接口。...缺点: (1):需要为每一个类配置一个克隆方法,而且该克隆方法位于类的内部,当对已有类进行改造的时候,需要修改代码,违反了开闭原则。
我们知道Java是一个面向对象(OOP)的语言,但它有一些弊端,比如当我们需要为多个不具有继承关系的对象引入一个公共行为,例如日志、权限验证、事务等功能时,只能在在每个对象里引用公共行为。...静态代理虽然保证了业务类只需关注逻辑本身,代理对象的一个接口只服务于一种类型的对象,如果要代理的方法很多,势必要为每一种方法都进行代理。...在运行测试类中创建测试类对象代码中 IUserDao proxy = (IUserDao)new ProxyFactory(target).getProxyInstance(); 其实是JDK动态生成了一个类去实现接口...但这里又引入一个问题,如果某个类没有实现接口,就不能使用JDK动态代理,所以Cglib代理就是解决这个问题的。...: 1.创建容器对象的时候,根据切入点表达式拦截的类,生成代理对象。 2.如果目标对象有实现接口,使用jdk代理。如果目标对象没有实现接口,则使用Cglib代理。
接口继承关系 由于BeanPostProcessor这个接口Spring本身内置的实现类就有很多,所以这里我们暂且不分析其实现类,就从接口的定义上来分析它的作用,其接口的UML类图如下: ?...这个就跟我们将要分析的第三行代码相关 添加一个BeanPostProcessorChecker,主要用于日志记录 我们看下BeanPostProcessorChecker这个类的源码: private...其实意思就是说在创建这个Bean时容器中的后置处理器还没有完全创建完。这个判断也能解释我们上面遗留的一个问题。之所以要加1是为了方便判断,否则还需要进行等号判断。...第10段代码中又添加了一个后置处理器,添加的这个后置处理器主要为了可以检测到所有的事件监听器,我们看下它的代码(这里只分析下它的几个核心方法): // 1.singletonNames保存了所有将要创建的...,为什么Spring不直接根据这些名字去过滤创建的Bean,而要通过一个特定的后置处理器去进行处理呢?
接口继承关系 由于BeanPostProcessor这个接口Spring本身内置的实现类就有很多,所以这里我们暂且不分析其实现类,就从接口的定义上来分析它的作用,其接口的UML类图如下: BeanPostProcessor...这个就跟我们将要分析的第三行代码相关 添加一个BeanPostProcessorChecker,主要用于日志记录 我们看下BeanPostProcessorChecker这个类的源码: private...其实意思就是说在创建这个Bean时容器中的后置处理器还没有完全创建完。这个判断也能解释我们上面遗留的一个问题。之所以要加1是为了方便判断,否则还需要进行等号判断。...第10段代码中又添加了一个后置处理器,添加的这个后置处理器主要为了可以检测到所有的事件监听器,我们看下它的代码(这里只分析下它的几个核心方法): // 1.singletonNames保存了所有将要创建的...,为什么Spring不直接根据这些名字去过滤创建的Bean,而要通过一个特定的后置处理器去进行处理呢?
领取专属 10元无门槛券
手把手带您无忧上云