暂无个人介绍
能力说明:
了解变量作用域、Java类的结构,能够创建带main方法可执行的java应用,从命令行运行java程序;能够使用Java基本数据类型、运算符和控制结构、数组、循环结构书写和运行简单的Java程序。
阿里云技能认证
详细说明
说明:本文所用的SpringMVC版本为4.3.4.RELEASE,应用服务器为TomCat8.0.33。下面我们先回顾一下我们在用SpringMVC进行开发时在web.
我们在上一篇文章中说了JAVA内存模型中原子性可见性的相关概念(点这里查看),我们在这一篇文章里说一下java内存模型中的重排序的内容。 重排序 重排序是指编译器和处理器为了优化程序性能而对指令序列进行重新排序的一种手段。
在上篇文章中我们简单的说了一下jvm的内存布局(点这里查看),在这篇文章中我们继续java内存模型方面的东西。 原子性 注意这里的原子性不是数据库事务中的原子性。
在上篇的文章中简单的说了一下SpringMVC请求大致处理的过程(点这里查看),说了一下SpringMVC为我们提供好的一些相关的组件。在这篇文章中我们接着看一下SpringMVC初始化这些组件的过程。
最近在做的东西中有这样一个需求要把一个文件上传到服务器A上,再由服务器A上传到服务器B上,而服务器A上传到服务器B的这个请求是通过HttpClient发送的。
SpringBoot我们大多数的时候是当做服务提供者来使用的,但是在一些场景中还是要用到一些文件上传下载这种"非常规"操作的。那么怎么在SpringBoot中实现文件的上传下载功能呢?想象一些我们在SpringMVC中是怎么做的。
我们都在使用SpringMVC,那么SpringMVC处理一个请求的大致流程是怎样的呢?请看下面图所示: 文字描述的话大致是这样的一个流程: 用户首先发送请求到前端控制器(DispatcherServlet),在doDispatch这个方...
在上一篇文章中我们说了BeanFactory中Bean的生命周期(点击这里查看),在这一篇文章中我们说一下ApplicationContex中Bean的生命周期。
在上一篇(点击这里观看上一篇)中我们用的BeanPostProcessor、@PostConstruct、InitializingBean等都属于Spring Bean生命周期的内容。
前几天在做项目的时候同事说,在使用AOP进行拦截的时候发现有些方法有时候能输出拦截的日志有时候不输出拦截的日志。发现在单独调用这些方法的时候是有日志输出,在被同一个类中的方法调用的时候没有日志输出。
在我们日常开发中可能经常会遇到jar冲突的问题,特别是在使用Maven进行项目管理的时候。在这里参考别人的文章写了一个用来测试class是从哪个jar中加载的demo(参考自:http://stamen.iteye.com/blog/2314940)。
今天开始Spring学习(希望发展的是Spring的源码学习的系列)的第一章。 资源的抽象接口(Resource) 我们在用Spring做开发的时候,总免不了读取各种各样的资源文件,比如说Spring的xml配置文件、属性的配置文件properties文件等。
本文内容总结自周志明先生所编著的《深入理解Java虚拟机-JVM高级特性与最佳实践》此书的经典不必多说。本节内容是对象的定位访问。 在java中我们无时无刻不在创建对象,我们创建对象的目的当然是为了使用它了。但是我们怎么才能使用操作创建的对象呢?我们的java程序会通过栈上的reference数据(指向对象的引用)来操作堆上的具体对象。那这个对象的引用是通过什么方式去定位、访问堆中的对象
本文内容总结自周志明先生所编著的《深入理解Java虚拟机-JVM高级特性与最佳实践》此书的经典不必多说。本节内容是对象的内存布局。 在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区域:对象头、实例数据、对齐填充(Padding)。在32位虚拟机中对象头的大小是8个字节,在64位虚拟机中对象头的大小是16个字节, 如果开启压缩的话,对象头的大小是12个字节。对象头包含两部分的
本文内容总结自周志明先生所编著的《深入理解Java虚拟机-JVM高级特性与最佳实践》此书的经典不必多说。本节内容是对象的创建.、分配的内容。 对象的创建 java对象的创建有几种方式呢(这里所说的java对象仅限于普通java对象不包含数据和Class对象)?大致有以下四种方式: new关键字。这应该是我们最常见和最常用最简单的创建对象的方式。 使用newInstance方法
对于做过web开发的人来说,Servlet中的过滤器肯定都不会陌生。这里我尝试着分析一下TomCat服务器中对于Filter是怎么组装的。在这之前,先把主要的几个类列一下: Filter 过滤器接口 FilterChain 过滤器链 FilterConfig 过滤器的配置 FilterDef 过滤器的配置和描述 ApplicationFilterChain 调用过滤器链
之前看过一次周志明写的《深入理解Java虚拟机-JVM高级特性与最佳实践》但是看过之后很多东西就忘了如同失忆了一般,所以这次在看的时候做一个读书笔记,以后也便于复习。
之前看过一次周志明写的《深入理解Java虚拟机-JVM高级特性与最佳实践》但是看过之后很多东西就忘了如同失忆了一般,所以这次在看的时候做一个读书笔记,以后也便于复习。先奉上一副自己总结的小图: Java虚拟机所管理的内存将会包括以下几个运行时数据区域:程序计数器(PC Register)、Java虚拟机栈、本地方法栈、Java堆、方法区。栈大致包括:程序计数器、Java虚拟机栈、本地方法
上篇文章中写了一个JDBC的小例子,这篇文章写个数据库连接池的小例子吧。 package com.zkn.newlearn.jdbc.mysql.third; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManage
前几天没事翻看了一下JDBC,顺便写了一个小demo。demo代码如下: package com.zkn.newlearn.jdbc.mysql.first; import org.junit.Test; import java.io.IOException; import java.io.InputStream; import java.sql.*; import java.ut
这几天在熟悉Swagger的时候,发现它没有提供为自定义对象属性赋随机值的功能(如果有的话,请告知一下),于是自己就写了一个能生成对象随机属性值的工具类,主要用到了反射机制、注解、随机类。具体的代码如下所示: 随机生成对象属性值的类: public class RandomObjectValue { public static <T> T getObject(
我们在项目中有时候需要跟踪记录sql的执行情况,有时候跟踪的日志中的sql是预编译之后的,参数是带问号的,所以我们需要跟踪到真正的sql执行语句,P6spy正好可以满足我们的需要。先来看一下P6Spy的介绍: P6Spy 是针对数据库访问操作的动态监测框架(为开源项目,github地址为https://github.com/p6spy/p6spy)它使得数据库数据可无缝截取和操纵,而不必
这几年都在搞前后端分离、RESTful风格,我们项目中也在这样用。前几天有人遇到了解析JSON格式的请求数据的问题,然后说了一下解析的方式,今天就写篇文章简单的分析一下后台对于JSON格式请求数据是怎么解析的。 先把例子的代码贴出来: 前端 <input type="button" value="测试JSON数据" onclick="testJSON()" /> &l
我想做过web开发的程序员大部分都做过文件上传的功能,大多数时候我们都是借助于commons-fileupload这样的jar包实现的。下面我试着通过读取Socket的输入流来实现一个文件上传的功能。 在做文件上传之前我们需要先了解一下HTTP POST的附件上传协议。HTTP附件上传协议是RFC1876协议,RFC1876协议是在HTTP协议的基础上为INPUT标签增加了file属性,
需求:利用Fork/Join框架来统计某个字符串在某个文件夹的文件中出现的次数。主要用到的技术点:JDK8的Stream、Lambda表达式、Fork/Join框架. 如果对于Fork/Join不了解的话可以参考这里:http://www.infoq.com/cn/articles/fork-join-introduction、http://ifeve.com/fork-
需求:计算某个字符串在某个文件夹中出现的次数。**这篇文章利用了JDK1.8的新特性Stream流和Lambda表达式并结合了线程池的使用。** package com.zkn.fullstacktraining.seventh; import javafx.util.Pair; import java.io.IOException; import java.nio.f
在上一章中我们加载Servlet用的是URLClassLoader,在这一章中我们使用自定义的类加载器来替换URLClassLoader。关于类加载器的文章请参考这里:深入探讨 Java 类加载器。这篇文章写得很棒。 具体的代码如下: package com.zkn.imitate.tomcat.secondchapter.first; import com.zkn.imitate
Web服务器也称为超文本传输协议(HTTP)服务器,因为它使用HTTP来跟客户端进行通信的。既然说到通信那就离不了Java里的两个重要的类java.net.Socket和java.net.ServerSocket。这里浏览器一方可以认为是一个客户端,接收HTTP请求的一方可以认为是服务端。在这之前我们先说一下HTTP协议。 HTTP协议允许web服务器和浏览器通过网络来进行发送和接收数据
最近现在在做的项目需要前后端分离,并且还有一些国际化的原因,需要动态替换页面上的一些元素,我简单的和前端同学说了一下我的思路,但是前端同学貌似没太明白,于是自己写了个demo。 大致思路是这样的:先从异步请求业务系统中取到业务数据,再将业务数据中相关的Code替换成对应的中英文。实现代码如下: 前台代码: <%@page pageEncoding="UTF-8" conten
关于tomcat的源码下载可以从这里下载: tomcat90:https://github.com/apache/tomcat(tomcat9.0)或者http://download.csdn.net/detail/zknxx/9720415(编译之后的) tomcat80:https://github.com/apache/tomcat80 或者 http://download.
如果不被重写(原生)的hashCode和equals是什么样的? 不被重写(原生)的hashCode值是根据内存地址换算出来的一个值。 不被重写(原生)的equals方法是严格判断一个对象是否相等的方法(object1 == object2)。 为什么需要重写equals和hashCode方法? 在我们的业务系统中判断对象时有时候需要的不是
Map: 1、Map的一级接口大概有这三个:SortedMap、ConcurrentMap(1.5)、和Bindings(1.6). SortedMap: 1)、SortedMap的直接接口有NavigableMap(1.6)、间接接口有ConcurrentNavigableMap(1.6)。主要实现类有TreeMap、 ConcurrentSkipListMap(1.6)。
Collection这个接口中大概可以分为这样三种类型的接口:List、Set、Queue(JDK1.5之后新增)。 Set: 1、Set是一个不包含重复元素的Collection。 2、Set的底层是由Map实现的。 3、Set的实现主要分为HashSet、LinkedHashSet、TreeSet三种。JDK1.5之后又新增了EnumSet及它的
今天在家没事看了一下集合框架,画了常用的类图。Collection大致可以分为set、List、Queue三种(Map不属于Collection体系中的,它是一个独立的数据结构。但是Collection和Map的实现上又互相依赖)。类图如下: Collections是一个包装类,它可以看做是Collection的辅助类。在这个类中提供了包装集合的一些类和有关集合操作的一些静态方法。它包含
字节输入流(InputStream): SequenceInputStream: SequenceInputStream可以把两个输入流合并成一个输入流。主要用作合并输入流。 内部有一个Enumeration属性,来存放两个输入流。 内部有一个nextStream方法,来指示En
程序中的所有数在计算机内存中都是以二进制的形式储存的。所以有时候我们还是有必要学习一下位运算的。我们知道在java中一个整型是占用四个字节32位的,而一 个byte类型占用一个字节8位的。所以我们可以用一个整型来最多表示一个长度为4的byte数组,同样我们可以用一个长度为4的byte数组来表示一个整型。下面我们就 看一下怎么用代码怎么去写整型和byte数组的相互转换。 字节数组表示一
Java中的IO大致可以分为两类,字节流和字符流。字节流又可以分为字节输入流和字节输出流,字符流又可以分为字节输入流和字符输入流。下面我们看一下他们的体系结构(UML类图表示)。 字节输入流 字节输入流的UML类图如下所示: 字节输出流 字符输入流 字符输出流 IO大致总图: 在IO的体系结构中所有字节输入流的父类都是InputStream,
昨天在做项目的时候遇到了一个坑,没错,就是获取MyBatis自增长主键值的坑。因为之前一直用ibatis,所以惯性的用了ibatis的写法,结果返回的值一直是1(受影响的行数)。于是去翻了翻MyBatis的源码,发现它把主键值放到了参数对象上,获取主键值需要用参数对象去get主键值。真是坑。我先把解决办法放出来,然后再接着分析MyBatis的源码是怎么做的。 环境: 数据库MySql、
在我们做项目的过程中,有可能会遇到跨域请求,所以需要我们自己组装支持跨域请求的JSONP数据,而在4.1版本以后的SpringMVC中,为我们提供了一个AbstractJsonpResponseBodyAdvice的类用来支持jsonp的数据(SpringBoot接收解析web请求是依赖于SpringMVC实现的)。下面我们就看一下怎么用AbstractJsonpResponseBodyA
有时候我们可能需要启动不止一个SpringBoot,而SpringBoot默认的端口号是8080,所以这时候我们就需要修改SpringBoot的默认端口了。修改SpringBoot的默认端口有两种方式。下面就分别说一下这两种方式。 修改application.properties 第一种方式我们只需要在application.properties中加这样的一句话就可以了:server.
在SpringBoot中启用热部署是非常简单的一件事,因为SpringBoot为我们提供了一个非常方便的工具spring-boot-devtools,我们只需要把这个工具引入到工程里就OK了,下面我就说一下怎么引入spring-boot-devtools。 修改pom.xml 我们只需要在pom.xml里,引入相应的jar包就行了。 <dependency>
在SpringBoot中加载静态资源和在普通的web应用中不太一样。默认情况下,Spring Boot从classpath下一个叫/static(/public,/resources或/META-INF/resources)的文件夹或从ServletContext根目录提供静态内容。下面我们来写个例子看一下就会一目了然了:首先看一下项目的目录结构: 我们在resources下面的te
在SpringBoot里添加单元测试是非常简单的一件事,我们只需要添加SpringBoot单元测试的依赖jar,然后再添加两个注解就可搞定了。 首先我们来添加单元测试所需要的jar <dependency> <groupId>org.springframework.boot</groupId>
在开始之前,我们先把需要的jar包添加到工程里。新增Maven依赖如下: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</art
装饰模式(Decorator Pattern)的定义是:在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象来包裹真实的对象。就增加功能来说,装饰模式相比于生成子类更为灵活。使用java的动态代理实现装饰模式会具有更强的灵活性、适应性。下面我们就来写一个使用java动态代理来实现装饰模式效果的例子。 定义一个职责的接口: /** * 能力 */
在上一章中我们概述了一下线程池,这一章我们看一下创建newFixedThreadPool的源码。例子还是我们在上一章中写的那个例子。 创建newFixedThreadPool的方法: public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolEx
每个线程都运行在java栈内存中,每个线程都有自己的工作内存。线程的计算一般是通过工作内存进行交互的。如图所示: 从上图中我们可以看到,线程在初始化时从主内存中加载所需的变量值到工作内存中,然后在线程运行时,如果是读取,则直接从工作内存中读取,如果是写入则先写到工作内存中,之后再刷新到主内存中,这个可以看做是JVM的一个简单的内存模型,但是这样的结构在多线程
在java中Timer是java.util包中的一个工具类,提供了定时器的功能。我们可以创建一个Timer对象,然后调用其schedule方法在某个特定的时间去执行一个特定的任务。并且你可以让其以特定频率一直执行某个任务,这个任务是用TimerTask来描述的,我们只需要将要进行的操作写在TimerTask类的run方法中即可。先附上两个小例子一遍让读者了解什么是定时器。接着再分析其中的一
在java中给我们提供了三种方式来创建多线程。前两种是我们比较常见的,第三种是JDK1.5之后提供给我们的。接下来我们详细的看一下这三种创建线程的写法。 继承Thread类 第一种方式是继承Thread类的写法,代码如下: Thread thread = new Thread(){ @Override public
近日在做RocketMQ的时候,mqnamesrv和mqbroker都正常启动了,但是在运行生产者的时候,报了个No route info of this topic的异常,让我很是郁闷。上网找了一些资料,现把解决办法记录如下,如果还有其他的原因导致这个问题的,后续会补充。 Linux系统下: 在启动mqbroker的时候需要指定autoCreateTopicEnable=true