前言

我们都知道软件开发是工科,不是理科;本质上和电工、钳工是一样的。

也就是说,软件技术成长也与电工、钳工的技术成长是一样的,靠的是练,而不是学。

所以,很多时候,我们称应届大学生是一张白纸,啥也不会。

不论他在学校学的多好,都没用,因为他没练过,不能干活;同理,不论他在学校学的多差,进入工作岗位后,只要肯练,工作也不成问题。

即,刚毕业的学生,只要你做的是工科的软件开发,不是科学类的理科研发;那么,本质上,大家是不存在优秀与普通的差别的。

为什么要学习Java?

在Web端,Java是毫无疑问的领头羊;所以,从事Web开发的Net开发者学习一下Java,其实还是很有益处的,取长补短嘛。

而且,在工作中我们难免是要遇到和Java接口对接的情况的;如果你足够了解Java,那么,对方是否假配合你很快就能发觉了;如果被人搞到离职了,还跟人称兄道弟的,就有点Low了。

下面,我以IDEA(Java的VisualStudio),创建一个Spring项目,重温一下Java。

Java重温

首先打开IDEA,点击File-New-Project(我手上只有英文版IDEA);如下图:

在NewProject界面里,选择Spring Intinalizr,然后勾选Default,点击Next;

然后我们会经历一个【等待界面】,该界面是用来下载Spring模板的;这是因为Spring的模板不在IDEA中集成,所以创建时,需要在网上下载。

由于VisualStudio集成了大量模板,所以,我们几乎不用自己去找模板下载;如果情况特殊,我们需要找模板的话,那也是到网站上下载,然后手动安装。比如MVC2的时代,你想用MVC3的模板。

所以,对于Net开发而言,这种IDE提供下载模板渠道的模式,我们还是比较陌生的。不过IDEA也提供手动安装模板的功能,勾选Custom就可以使用手动安装模式了。

【等待界面】结束后,进入下图界面:

这个界面里有两个参数需要设置,一个是Group,一个是Artifact。那么这两个参数的作用是什么呢?

从字面上我是理解不了的,于是我百度了一下。。。然后,呃。。。我还是很混乱。。。

调查后,我大概得出一个结果,就是Group和Artifact是这个项目的唯一标识,Group是组织唯一标识,Artifact是项目唯一标识。

呃。。。我想,对于对于Net开发而言,这应该是很难理解的。项目唯一标识?这是什么鬼?唯一标识这个词怎么听起来像主键呢。。。项目怎么还需要唯一标识呢。。。

那到底要如何解释他们呢?

我想,应该是这样的,Java创建者的初始目的可能是想创建一个地球村共荣圈。。。所以,每一个Java项目都被期待着被共享,如果项目被共享,那么项目就需要唯一标识Artifact。如果一个公司共享了多个项目,那要证明这些项目都从属于该公司,那就需要组织(公司)唯一标识Group。

换成Net的描述就是,你创建的每一个Net项目都被微软期待着,共享到Nuget上,所以你创建项目之前,要先创建这个项目在Nuget上的唯一标识。(很显然微软没有这个期待)

这样,似乎就很好理解Group和Artifact了。

但是,因为现实中,不论Java还是Net都不可能每个项目都共享,所以,当我们做一个非开源项目时,这两个属性设置,就有点鸡肋了。

----------------------------------------------------------------------------------------------------

下面看一下,我认为这个界面中第三个重要的属性配置—Package。

可以在图中看到,系统默认把Package赋值成了Group+Artifact的值了—kibagroup.kibaarifact。

这里的Package大约等于C#里的命名空间。呃。。。然后,这个默认赋值我就觉得很奇葩了。。。

比如,你做了唯一标识,Group等于公司名kibacompany,Artifact等于项目kibatest;然后,你项目的默认命名空间就是kibacompany.kibatest。。。

很显然,这件事,对我而言很难理解,还好,IDEA支持我们去修改默认Package。

----------------------------------------------------------------------------------------------------

这里我们修改Package为KibaJavaStart。

修改完Package后,我们点击Next继续,如下图:

选择图中的Web项目和其子选项中的Spring Web,然后点击下一步。

如上图所示,我们创建项目已经到了最后一步了,因为右下角不在是Next,而是Finish了。

在最后的这个界面里,系统提示我们设置ProjectName(项目名称)。

根据Net的习惯,项目名称通常和默认命名空间一样,所以这里我也赋值KibaJavaStart。

点击Finish,项目创建完成,界面如下:

项目简介

在上图中有三个大文件夹,和若干文件。

文件夹

其中前两个.idea和.mvn分别是IDEA开发工具和Maven管理工具的配置文件、管理文件等等(Maven类似nuget,但它还管理代码的生成和发布。。。貌似比IEDA还好用。。。这里Net开发就需要转变一下观念了,因为Java不是C#一家独大,所以他的相关工具存在的功能重复的问题,所以Java开发通常都是用组合工具在开发,不像我们一个VisualStudio走天下)

第三个src是我们项目的核心文件,java代码都在这里;src我猜就是source的意思,不知道为什么它不用全拼。。。

我们可以看到,在展开的src文件夹中,有着一层,两层,三层。。。呃。。。好多层文件夹。。。谁说的臃肿。。。

呃。。。我们可以看到其中java这个文件夹的颜色是不一样的,它代表的着,它下面的代码是核心Java代码。

与java文件夹同级的resources文件夹,顾名思义,存的是资源文件;不过他这个资源文件几乎什么都可以存储,比如图片,配置字符串,XML数据,SQL查询语句等等。(可能Net项目很少如此集中的存储资源,所以感官上可能会有些奇怪,但我觉得java的这种资源集中的做法是很科学的,非常值得Net开发借鉴学习)

----------------------------------------------------------------------------------------------------

文件

在剩下的若干文件中,我们暂时只关注Pom.xml文件;它是Java的配置文件,不过他并不类似于Net的App.config,他相对的更接近Net的.csproj工程文件,里面存储引用了那些Jar包(Net里就是dll)。

Java的Web是有类似于Net的App.config文件的文件的,他叫做web.xml,不过,很明显,我们在这里看不到,我们暂时不关注他,后文会讲到它。

Java里还有个数据配置文件,在这里配置的信息可以在Java代码里被访问;他就是java的数据配置文件在resources文件夹下的application.properties(类似App.config的AppSettings使用configSource把配置文件外放)如下图:

Web项目开发

首先,我们找到我们的默认命名空间,Java里的默认包—KibaJavaStart,如下图:

可以看到,在KibaJavaStart包下只有一个类ArtifactApplication,类里只有一个方法Main。

Main方法?不是Web项目吗?怎么还有Main方法?

如果你这么想,那一定是你Low了,嘿嘿;学一下Asp.Net Core吧,我们的Core也有Main函数了。

Asp.Net Core学习导航

学习了Asp.Net Core我们就了解了,这个承载Main函数的Application类,就是Asp.Net Core的Program类。

吐槽一下

1,现在项目创建完成后,系统在生成一个Main函数启动类时,使用了Arifact的值来做开头;这事很奇怪,Arifact是和Group在第一步一起创建的,两者是上下级关系;但现在Arifact又突然的和最后一步创建默认包名成了上下级关系,这感觉太诡异了,为什么不直接用Application命名呢,非要这样结合一下呢?

2,项目创建完成后自带的项目文件也太少了吧,就一个Main函数启动类,这让人怎么自学啊,逼着我们去看教程啊。

----------------------------------------------------------------------------------------------------

言归正传,一起看代码。。。

首先第一行代码,声明包名称。

package KibaJavaStart;

意义很简单,就是声明类所在的包名;不过,这里与C#不同的是,这个包名是固定的,不可修改的。

也就是说,这个类文件在文件夹KibaJavaStart下,他的包名就必须是KibaJavaStart;如果是在文件夹KibaJavaStart/Test下,他的包名就必须是KibaJavaStart.Test。

是的,这的确很不方便,不过,我们换一个角度考虑,Java文件夹的设置已经很臃肿了,刚刚创建就来了好几层,如果不强制包名称和文件夹名一致,那只怕会带来更多的不便。

我们接着看代码。

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

声明包名后,引入两个Spring包,理由很简单,因为Main函数要使用这两个包里的内容。

这里import与C#里的Using引用命名空间的用法类似。

因为创建的是Spring项目,所以一些相关的Spring的Jar依赖(类似C#的Dll)已经被默认引用进来了,可以在项目的External Libraries下找到相关引用;如下图:

我们知道在C#项目中,被引用的DLL会被复制一份到本地目录。

不过,在Java项目却不是这样的,我们打开项目的所在文件目录,会发现,目录里并没有这些Jar文件。

所以我猜想,被引用的Jar还在原来的位置,只有被编译的时候才会被调用。

----------------------------------------------------------------------------------------------------

在Java里,JDK自带的Jar包相对比Net而言,还是较少的,所以,在开发Java时,通常要引用很多很多个Jar包。

比如Spring框架就不在JDK自带的Jar包里,所以,使用Spring框架开发项目,就要先下载其相应的Jar包。

因为,我们是使用IDEA开发工具开发,而IDEA默认的下载Jar包的工具是Maven,那么下载的Jar包自然是由Maven管理;即,它们应该在Maven工具的所在目录下。

Maven管理工具好像是没有界面的,只能用命令行来操作;不过IDEA为我们提供了操作Maven的界面,现在我们打开IDEA提供的Maven操作界面。

File—Settings—Build,Execution,Deployment—BuildTools—Maven,如下图:

可以看到Maven不仅支持下载Jar包,还支持自定义保存下载Jar包的位置。

图中的Local repository就是保存已下载Jar包的位置了。

----------------------------------------------------------------------------------------------------

回到代码。

@SpringBootApplication

这种@开头的东西叫注解,它使用方式与C#的特性类似,要放在类,函数,属性上面;然后在注解(特性)的定义里去找到它的宿主(类or函数or属性),然后为他增加特性;当然,也可设置成只支持类或者只支持函数的模式。

不过Java里的注解实在是太多了、太强大了、太复杂了;注解不仅拥有各种各样的功能,还互相依赖,甚至注解和注解之间还有嵌套;目前Java已经发展到了不使用注解,开发就举步维艰的地步了。

有些注解在Net开发看来,真的有些奇葩,比如这个@Data注解,你都想象不到他是干什么的。

如上图所示,我们定义了一个实体类DataTest ;类里定义两个私有字段,然后我们在类的头上加了一个Data注解,然后。。。然后。。。

然后,这个Data注解就会自动给这两个私有字段变成属性。。。

也许是因为我定义实体时总是想着他要被充血,所以我才觉得这注解很奇葩吧。。。

在上图中我们还可以看到,@Data注解是红色的,这是因为,我们还没有引入他依赖的Jar包。如何引用呢?呃。。。目前我只知道一种方法。。。

打开pom.xml,找到dependencies标签,在他的下面添加@Data依赖的Jar包 (手敲的),如下图:

图中除了@Data的依赖的lombok包,还有两个依赖,一个是spring-boot-starter,一个是spring-boot-starter-web;简单介绍下,这两个依赖是Spring框架的基础依赖,如果创建项目时未帮我们自动添加这俩依赖,则需要我们手动添加一下,不然会影响项目运行。

PS:在dependency标签中,我们会发现,他的子标签是groupId和artifactId,而spring-boot-starter包和spring-boot-starter-web包的groupId又是一样的,结合我们上文创建项目时设置Group和Artifact,可以想到,spring-boot-starter包和spring-boot-starter-web包都是由org.springframework.boot组织创建的开源项目,而我们在项目中,引用这种开源项目时,需要在dependency标签下增加groupId和artifactId两个标签,并在其中填写这个项目创建时设置的Group和Artifact属性值。

----------------------------------------------------------------------------------------------------

在Java的工程文件里添加完依赖后,我们所依赖的Jar并不会被下载,还需要手动使用Maven来下载,(这个下载依赖库的方式有点倒序的意思和Net不一样)顺序如下。

1,点击左下角快捷图标,打开Maven管理工具,如下图:

点击后,右侧会弹出Maven管理工具,如下图:

点击图中红框内的下载按钮,然后弹出浮动窗,在浮动窗内点击第一项Download Source,如下图:

然后IDEA下方会出现一个下载进度条,双击进度条可以最大化,里面有详细信息(如果网速很快或者Jar包很小,该进度条可能一闪而过),如下图:

最后我们回到实体类,将鼠标放到@Data上,点击Alt+Enter,然后在弹出的浮动窗上点击Import class,然后系统会为我们引入@Data注解所属的Jar包—import lombok.Data;。

现在@Data注解就可以正常运行了,不过,这个过程好像有点。。。

----------------------------------------------------------------------------------------------------

回到注解@SpringBootApplication。。。

注解@SpringBootApplication是一个组合注解,包含@SpringBootConfiguration,@EnableAutoConfiguration,@ComponentScan。

@SpringBootConfiguration:将当前类标记为配置类。上文我提到了Java项目里有个web.xml配置文件(类似app.config),不过创建项目时并没有自动生成;其原因就是这个注解了。

Spring框架项目编译时会检测这个注解(组合注解@SpringBootApplication也会被检测),检测到后会把这个类下的函数,全部提取出来,然后在逐个处理; 怎么处理呢?我猜,是通过反射找到函数的函数名,参数,然后执行一下得到返回值;然后把这些字符串组成复合规则的Xml标签,再写进web.xml配置文件。

这样做的好处就是繁琐的XML文件配置,被转化成了代码编写,而且java项目的web.xml最终好像是会被编译进jar,所以这种动态生成web.xml的模式好想也没什么问题。

@EnableAutoConfiguration,@ComponentScan简单理解就是使其他注解生效,如@Controller等;换言之,是使其他注解状态为Enable和为其他注解提供配置信息的注解。

即该注解是其他注解的依赖。。。。。。

----------------------------------------------------------------------------------------------------

我们接着看代码,现在到了类的主体代码了,代码如下:

public class ArtifactApplication {

	public static void main(String[] args) {
SpringApplication.run(ArtifactApplication.class, args);
}
}

可以看到,该类是一个拥有Main函数的入口类,类里Main函数主要实现一个功能调用SpringApplication命名空间下的静态方法Run。

我猜测,该方法的主要功能和AspNetCore的 WebHost.CreateDefaultBuilder(args).UseStartup<Startup>().Build();这句话是一个意思,都是启动一个服务器进程。

服务进程启动以后,就可以把我们的Web搭建进去了,我们可以看到Run函数第一个参数就要求主类的类名,这代表服务器启动后,会通过这个入参来启动Web项目。

这里Srping和Core的区别就是Spring启动的服务器是Tomcat,而Core启动的服务器是Kestrel。

创建一个Api

现在Java项目我们已经创建完了,该了解的基础我们也了解了,那么让我们一起创建一个Api,然后运行一下看看效果吧。

首先我们创建一个ApiController的文件夹,然后添加一个HelloController文件,然后编写代码如下:

@RestController
public class HelloController
{
@RequestMapping(value = "/GetName", method = RequestMethod.GET)
public String GetName()
{
return "我是Kiba518";
}
@RequestMapping(value = "/GetAge", method = RequestMethod.GET)
public int GetAge()
{
return 518;
}
}

可以看到,代码中在类的上面加了一个注解@RestController,该注解表示当前类是一个遵循REST风格的Api类;类似于Net里的Controller继承ApiController。

接着我们创建了两个函数GetName和GetAge;他们的头上使用@RequestMapping注解,该注解的作用是设置访问该函数的地址。

即,函数GetName和GetAge的访问地址为 http://127.0.0.1:8010/GetName和 http://127.0.0.1:8010/GetAge;访问时,我们需要注意,GetName和GetAge这个地址是区分大小写的。。。

现在Shift+F10运行下项目,测试一下我们的WebApi。

如上图,WebApi访问成功。不过我们访问的端口是8010。

还记得上面说的Spring启动时会创建一个服务器吗,这个端口就是服务器监听的端口。

当然了,这个端口是可配置的,配置的位置就在application.properties里。

不过.properties文件编写和阅读不太方便,我们把他改为.yml,然后修改代码如下:

server:
port: 8010

这个配置文件里的内容是可以被Java访问的,而且Spring框架项目编译时也会先读这里的内容,找到同名的配置,就会替换默认的配置。

PS:Java中控制访问地址的注解非常多,控制地址访问的模式也非常多,多到有点夸张的地步。。。

结语

从开发工具的角度来看,Java的开发工具的使用相较Net而言,是比较怪异的,因为,它有一些工具的设计和使用是倒序的。

而Java工具又比较多,因此,这种正序工具和倒序工具同时存在同时使用,感觉上就有一点怪,不过习惯了以后倒也没什么。

从开发的角度来看,Java的主流Spring和Net几乎没有什么区别,唯一的区别就是Java使用注解而Net使用继承。

----------------------------------------------------------------------------------------------------

代码已经传到Github上了,欢迎大家下载。

Github地址:https://github.com/kiba518/KibaJavaStart

----------------------------------------------------------------------------------------------------

注:此文章为原创,任何形式的转载都请联系作者获得授权并注明出处!
若您觉得这篇文章还不错,请点击下方的【推荐】,非常感谢!

https://www.cnblogs.com/kiba/p/12052925.html

一个C#开发者重温Java的心路历程的更多相关文章

  1. 一个C#开发者重温C++的心路历程

    不知道为什么,似乎很多人理解跑偏了,在这里我要说明一下. 首先,我并没有对C++语言有偏见,我只是单纯的在学习时,在理解时,对C++语言进行一些吐槽,我相信,很多学习C++的人,也会有类似的吐槽. 其 ...

  2. 一个C#开发编写Java框架的心路历程

    前言 这一篇絮絮叨叨,逻辑不太清晰的编写Java框架的的一个过程,主要描述我作为一个java初学者,在编写Java框架时的一些心得感悟. 因为我是C#的开发者,所以,在编写Java框架时,或多或少会带 ...

  3. G彩娱乐网一个程序员到一个销售高手的心路历程

    0.引言 我大学本科读的是理工科,后来毕业以后,我逐渐走上了程 序员的道路.每天面对电脑一行一行的敲代码,这被我们程序员们戏称为"搬砖头",因为我们所做的事跟民工搬砖头砌墙本质上是 ...

  4. 我的Java历程_maven配置的心路历程

    从github上download了个maven管理的开源项目,接下来随笔下安装maven的心路历程: 异常尴尬的是import进ide之后一个红色的感叹号!震惊!google一下知道了,maven没配 ...

  5. 一个ETF基金经理的心路历程

    简介: 鹏华沪深300ETF拟任基金经理崔俊杰先生,金融工程专业管理学硕士,5年证券基金从业经验.2008年7月加盟鹏华基金管理有限公司,历任产品规划部产品设计师.量化投资部量化研究员,先后从事产品设 ...

  6. 【react native】有关入坑3个月RN的心路历程

    由于一些原因,笔者最近变更到了RN的团队,回归到了hybrid app的开发的圈子中,固然是有蛮多新鲜感和新机遇的,不过遥想起以前在hybrid中各种view之前跳转的头疼等各种问题,笔者怀着忐忑的心 ...

  7. 就这么漂来漂去---一个毕业三个月的java程序员的裸辞风波

    注:这并不是一篇技术文章,而是记录了我这几个月经历的入职,裸辞,找工作的心路历程,简单介绍一个博主的情况,我是16年毕业生,校招进了一家北京的公司,java开发,和很多年轻人一样,干了一段时间,我发现 ...

  8. Java的发展历程

    Java的发展历程充满了传奇色彩. 最初,Java是由Sun公司的一个研究小组开发出来的, 该小组起先的目标是想用软件实现对家用电器进行集成控制的小型控制装置. 开始,准备采用C++,但C++太复杂, ...

  9. 顶级项目孵化的故事系列——Kylin的心路历程【转】

    现在已经名满天下的 Apache Kylin,是 Hadoop 大数据生态系统不可或缺的一部分,要知道在 Kylin 项目早期,可是以华人为主的开源团队,一路披荆斩棘经过几年的奋斗,才在 Apache ...

随机推荐

  1. 2019-9-2-git-需要知道的1000个问题

    title author date CreateTime categories git 需要知道的1000个问题 lindexi 2019-09-02 10:12:31 +0800 2018-2-13 ...

  2. uva 624 CD (01背包)

      CD  You have a long drive by car ahead. You have a tape recorder, but unfortunately your best musi ...

  3. 2018-8-10-WPF-好看的矢量图标

    title author date CreateTime categories WPF 好看的矢量图标 lindexi 2018-08-10 19:16:53 +0800 2018-5-16 11:4 ...

  4. electron-vue 窗口拖拽及自定义边框,及关闭缩小放大化方法

    1.窗口的最小化按钮和关闭按钮以及标题栏自定义,不使用 electron 自身携带的原生标题栏 在src文件夹下main下index.js文件添加 mainWindow = new BrowserWi ...

  5. 2019-4-6-VisualStudio-2019-如何离线下载

    title author date CreateTime categories VisualStudio 2019 如何离线下载 lindexi 2019-04-06 09:26:11 +0800 2 ...

  6. 超容易理解的call()、apply()、bind()的区别

    call().apply().bind()是用来改变this的指向的. 一 举个例子 一个叫喵喵的猫喜欢吃鱼,一个叫汪汪的小狗喜欢啃骨头,用代码实现如下: 有一天,小狗汪汪和喵喵共进午餐的时候,汪汪说 ...

  7. VUE框架思想

    学习VUE的第一步就是先了解这个框架的的核心思想 Vue.js的核心思想就是,它是一套__渐进式的自底层向上增量开发__的__MVVM__结构的框架 什么是框架? 简单的讲,框架就是将与业务无关的重复 ...

  8. 牛客wannafly 挑战赛14 B 前缀查询(trie树上dfs序+线段树)

    牛客wannafly 挑战赛14 B 前缀查询(trie树上dfs序+线段树) 链接:https://ac.nowcoder.com/acm/problem/15706 现在需要您来帮忙维护这个名册, ...

  9. FreeSql取多表数据

    该篇内容由个人博客点击跳转同步更新!转载请注明出处! 以文章随笔与分类为例. 表结构 部分字段如下,其他省略,为了展示一对多关联,一个分类下可以有多个文章.一个文章属于一个分类. blog_artic ...

  10. Text Style Transfer论文笔记

    Text Style Transfer主要是指Non-Parallel Data条件下的,具体的paper list见: https://github.com/fuzhenxin/Style-Tran ...