一个C#开发者重温Java的心路历程kiba518

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

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

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

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

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

为什么要学习Java

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

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

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

Java重温

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

在NewProject界面里,选择SpringIntinalizr,然后勾选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项目和其子选项中的SpringWeb,然后点击下一步。

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

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

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

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

项目简介

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

文件夹

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

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

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

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

文件

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

Web项目开发

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

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

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

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

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

吐槽一下

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

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

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

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

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

我们接着看代码。

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

我们知道在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包的位置。

图中的Localrepository就是保存已下载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管理工具,如下图:

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

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

最后我们回到实体类,将鼠标放到@Data上,点击Alt+Enter,然后在弹出的浮动窗上点击Importclass,然后系统会为我们引入@Data注解所属的Jar包—importlombok.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和为其他注解提供配置信息的注解。

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

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

publicclassArtifactApplication{publicstaticvoidmain(String[]args){SpringApplication.run(ArtifactApplication.class,args);}}可以看到,该类是一个拥有Main函数的入口类,类里Main函数主要实现一个功能调用SpringApplication命名空间下的静态方法Run。

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

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

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

创建一个Api

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

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

@RestControllerpublicclassHelloController{@RequestMapping(value="/GetName",method=RequestMethod.GET)publicStringGetName(){return"我是Kiba518";}@RequestMapping(value="/GetAge",method=RequestMethod.GET)publicintGetAge(){return518;}}可以看到,代码中在类的上面加了一个注解@RestController,该注解表示当前类是一个遵循REST风格的Api类;类似于Net里的Controller继承ApiController。

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

现在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使用继承。

THE END
1.千万别被骗了!这些网红智商税产品,都是些什么鸡肋?吐槽理由: 不知道是我的香皂太大 还是太硬的关系 用一用笑脸磁贴和香皂就会分离 可能是香皂遇水就会变软变滑 最后导致这个原因? 去翻了下评论,发现也不乏 有跟我遇到同样情况的买家 但令人费解的是在购买评论区 仍有很多小伙伴说非常好用 我内心:? http://www.360doc.com/content/20/0708/12/70780240_922957621.shtml
2.吐槽一下,荣耀智慧空间真的很鸡肋,什么功能都没有游戏空间还不是简陋鸡肋 https://club-api.c.hihonor.com/thread-26932603-1-1.html
3.吐槽一下帕萨特鸡肋的无线充电功能帕萨特社区更是会留下的印?,?知道为啥会用这样一?材质。https://baa.yiche.com/passat/thread-46980217.html
4.吐槽一下:奥迪Q5L非常鸡肋的微信互联功能简介: 吐槽一下:奥迪Q5L非常鸡肋的微信互联功能 展开 声明:本文由车市号作者撰写,仅代表个人观点,不代表网上车市。文中部分图片来源网络,感谢原作者。作者信息 车界江湖 关注 7194作品 是非黑白终须明,车行江湖自有道。车界江湖,聚焦车界为您而来!Ta的视频 ...https://cheshihao.cheshi.com/video/1526174.html
5.颐家家居这5大鸡肋产品,你家有吗? 可好用呼? 小细节,你家做到了几点? 装修 如何省钱?给你6大黄金秘籍,至少省3万; 可以买吗?到底安全吗?改如何选择呢? 聊聊 建材圈的事! 室内木门怎么选? 给你几个品牌网购参考一下! 轻奢加入中式元素的极简风,也可极具性价比 墨绿色真的很抓眼球! 好用且性价比高的壁挂锅炉怎...http://www.e-jjj.com/video.html?type=10&id=6874398017416367374
1.美妆吐槽Vol.1:失望的美妆产品DisappointingBeautyProducts所以这一篇美妆吐槽就是这么多了。写完从头看了一遍,感觉自己挑剔得过分。但是其实这些产品里面我还是很多都在用,只是整理出来显得很多,写起来也是觉得自己乱花钱。这篇吐槽也是提醒我自己,买东西之前要好好做功课,尽量先试用再下手。 当然这些产品在我这不好用不代表在你手上也会不好用,希望我的这一点吐槽能对读...https://www.douban.com/note/611273346/
2.项目开发总结(吐槽)(2021612)产品研发测试的吐槽最近又参与了一个项目的开发,感觉槽点颇多,特此记录。毕竟人总是更容易发现别人的缺点,但是我希望这些问题在我自己遇到的时候可以更好地解决,而不只是停留在无脑吐槽上。当然,对于好的地方我也该化为己用。多说无益,下面进入主题: 1.产品迭代周期过短 https://blog.csdn.net/gongjianbo1992/article/details/117842432
3.315快到了,家长们快来吐槽曾经买过的“鸡肋”母婴产品“315”消费者权益日即将到来之际,我们想问大家,是否买过堪称“鸡肋”的母婴产品?不管是受到广告蛊惑一时冲动“剁手”的奶粉冲调机,还是宝宝只玩一次就彻底抛弃的玩具,我们欢迎你留言吐槽那些买来就后悔的东西,让更多新手爸妈们长个心眼,理智消费。 用来隔离辐射波的孕妇罩衣 ...https://www.thepaper.cn/newsDetail_forward_1635737
4.利润点太低流量费太贵玩不起...商家吐槽平台促销成“鸡肋”导读:奥一实测研究院历时三个月监测天猫(淘宝)、京东、拼多多、唯品会等电商平台、500余件商品发现存在“先提价再打折”等众多乱象。参与调查的1000多名消费中,有近8成的人吐槽这届6.18“价格不划算”“促销套路多”,有专家指出平台内卷普陷过度营销,购物节正面临信任危机... 本期...https://static.nfapp.southcn.com/content/202108/06/c5609792.html
5.昆仑用车一个半月,吐槽一下受不了的缺点星瑞车友圈来捋一捋缺点吧: 1、继续吐槽车机,很不幸的我的车机是353版本的,目前无法安装各类第三方软件,已知唯一的办法是拆机刷机破解,真不想折腾了。没有高版本的高德地图是QQ音乐是真的难受啊。另外之前开车进了一趟秦岭分水岭后,车机网络就开始不好使了,在市区经常无缘无故断网,四儿子店支支吾吾说不出来原因只知道让...https://www.dongchedi.com/article/1794003409276939
6.DALL第三种情况举例来说,输入“一匹斑马和一条街道”,输出的结果中一直都有斑马线。 在这里,DALL-E 2把斑马同时解释了两次。 在针对这些情况都重复试验后,作者计算出DALL-E 2在三种情况下,出现失误的概率都超过80%。 其中第二种情况的失误率最高,达到97.2%。 https://cloud.tencent.com/developer/article/2188751
7.年度盘点:2017年度八大“智障”AI产品2017年被称为“人工智能落地元年”,然而,诸多AI产品看起来高大上,实质上并没有真正解决用户痛点,反而深受用户吐槽。本文根据用户反馈盘点出2017年度八大“智障”AI产品,以飨读者。 2017年被称为“人工智能落地元年”。AI正在渗透到人们生活的各个角落,意味着AI硬件和应用产品将进入大爆发时期。 https://www.51cto.com/article/562234.html