idea监控平台网页原码,代码怎么保存成文件?
代码保存成文件 需要经过预处理,编译,汇编,链接一:预处理
预处理主要是处理源代码中以#开始的预编译指令,比如#include,#define
将所有的#define删除,展开宏定义
处理所有的条件编译指令#if,#ifdef,#elif,#else,#endif
处理#include预编译指令,将被包含的头文件插入该预编译指令的位置,是个递归的过程
删除所有的注释 //与/**/
添加行号与文件名表示,用于调试符号与编译错误或警告报错
保留#pragma编译指令,改指令 编译器需要使用
二:编译
编译过程就是把预编译生成的文件进行一系列词法分析(也叫扫描),语法分析,语义分析,源代码优化,汇编代码生成,目标代码优化
词法分析:根据分隔符,将代码分割成一系列的记号
比如: int a = (a+3)*(2+5);
将会 变成以下记号: int,a,=,(,a,+,3,),(,2,+,5,)
词法分析产生的记号可以分为:关键字,标识符,字面量(数字,字符串,即常量),特殊符号(加号,等号等),在识别记号时,会将标识符放入符号表,字面量放入文字表
语法分析:根据记号进行语法分析,产生语法树,整个分析过程采用上下文无关语法(语法树就是以表达式为节点的树),仅仅是完成对表达式的语法层面进行分析
语义分析:语义分析对语法树中的表达式标识类型,对于类型不匹配,编译器将会报错,如果有些类型需要做隐式转换,将会在语法树中插入对应的节点
源代码优化生成汇编代码:int a = (a+3)*(2+5); 将会被优化为int a = (a+3)*(7)
三:汇编
汇编即根据汇编指令翻译为机器指令
四:链接
链接主要包含 地址和空间分配,符号决议,重定位
该如何学习spring源码以及解析bean定义的注册?
谢谢邀请!我将从以下几点介绍源码及Spring是怎样解析Bean定义并注册的
目录:
学习源码的重要性?
学习Spring源码需要基础吗?
怎样把Spring源码在本地运行?
Bean定义的加载过程
bean定义加载的流程图
总结
学习源码的重要性?(1) 可以提升技术功底,Spring源码也沉淀了很多年,有非常多的精华所在,不管我们什么水平,通过不断的阅读源码,能对我们的技术有很大的提升,并且工作中遇到类似问题的时候,可以借鉴源码中是怎么处理的。
(2) 深度的掌握技术框架:源码看多了,对于新的框架的学习和掌握都是很快的,看下框架的demo,就知道底层是怎么实现的。
比如,学习了Spring 中的AOP,就知道底层是用了JDK的动态代理。然后我们学习mybatis的时候,就在想Mybatis 为什么Service可以直接嗲用Dao接口,就可以直接查询数据库了呢 ?其实也是Spring底层对给接口做了动态代理。
(3) 对线上的问题可以进行快速的定位: 当生产上遇到问题时,能够快速的进行定位,这个能力可以快速秒杀别人。
(4) 对面试有很大的好处,特别是BAT大厂,一般都是问道源码级别的,你如果不会,可能第一轮就会被刷掉。
学习Spring源码需要基础吗?答案是肯定的,需要,那么需要哪些基础呢?
(1)Java 的技术功能
(2) 反射
(3) 设计模式: 简单工厂、工厂方法、单例模式、原型模式、代理模式、策略模式、模板方法模式、委派模式、适配器模式、装饰器模式、观察者模式
(4) Lambda表达式的知识
怎样把Spring源码在本地运行?(1) git clone https://github.com/spring-projects/spring-framework.git
(2) gradle下载,gradle需要JDK8版本
(3) 到下载的spring源码路径执行gradle命令,gradlew :spring-oxm:compileTestJava
(4) 用idea打开spring源码工程,在idea中安装插件kotlin,重启idea
(5) 把编译好的源码导入到工程中
Bean定义的加载过程1、首先找到程序的入口
① 找到其构造方法:
② 调用 AnnotationConfigApplicationContext 构造方法,最终会调用父类 GenericApplicationContext的无参方法
③ 调用父类 AnnotationConfigApplicationContext 无参构造方法,生成bean定义读取器和Bean定义扫描器
上面方法的功能是: 实例化注解的Bean定义扫描器,定义类类路径下的bean定义扫描器
3.1 为Bean定义读取器赋值
3.1.1 为容器 中注册系统的Bean定义信息
上面代码主要是注册系统的Bean定义信息,包含以下几种:
① ConfigurationClassPostProcessor
是一个BeanFactory的后置处理器,主要功能是参与BeanFactory的构建,在这个类中,会解析@Configuration的配置类,解析@ComponentScan、@ComponentScans注解扫描的包,以及解析@Import等注解。
② AutowiredAnnotationBeanPostProcessor
AutowiredAnnotationBeanPostProcessor 实现了BeanPostProcessor,当Spring容器启动的时候,AutowiredAnnotationBeanPostProcessor 将扫描Spring容器中的所有Bean,当发现Bean中拥有
@Autowired 注解的时候就会找到与其匹配的Bean,并注入到对应的中去。
那么在什么时候调用的呢?我们可以看下debug堆栈;
③ RequiredAnnotationBeanPostProcessor
RequiredAnnotationBeanPostProcessor 是BeanPostProcessor实现.的,注释应用于bean属性的setter方法,它表明 受影响的bean 属性在配置时是否必须,如果配置了,没有此bean,则容器就会抛出一个BeanInitializationException 异常。
④ .CommonAnnotationBeanPostProcessor
CommonAnnotationBeanPostProcessor 这个BeanPostProcessor 通过继承 InitDestroyAnnotationBeanPostProcessor 对 @PostConstruct 和 @PreDestroy注解的支持,以及对bean的依赖注入@Resource的支持。
⑤ EventListenerMethodProcessor
使用EventListenerMethodProcessor处理器来解析方法上的 @EventListener;
执行时机: 实在所有Bean都实例化以后执行的
④ 创建类路径下的bean定义扫描器
上述方法 是注册默认的扫描规则
⑤ 读取配置类
上述方法annotatedClasses为我们配置的mainConfig
annotatedClasses 就是MainConfig
此时上面主要解析 MainConfig,解析成BeanDefinition对象
上述的字段都是什么意思呢?
id: Bean的唯一标识名name: 用来为id 创建一个或者多个别名。class : 用来定义类的全限定名(包名 + 类名)parent: 子类bean定义它所引用它的父类的bean。abstract : 默认为false,用来定义bean是否为抽象bean,它表示这个Bean将不会被实例化,一般用于父类Bean,因为父类bean主要供子类bean继承使用。lazy-init: 用来定义这个bean是否实现懒初始化。如果为true,它将在BeanFactory启动时初始化所有的单例bean,反之,如果为false,它只在Bean请求使用时才开始创建SingletonBean。autowired : 自动装配,它定义了Bean 的自动装配方式。depends-on:依赖对象:这个Bean在初始化时依赖的对象,这个对象会在这个Bean初始化之前创建。init-method: 用来定义Bean的初始化方法,它会在Bean组装之后调用,它必须是一个无参的构造 方法。destroy-method: 用来定义Bean的销毁方法,它在BeanFactory关闭时调用。同样,它也必须是一个无参 的构造方法。只能适用于单例Bean.factory-method: 定义创建该Bean对象的 工厂方法。factory-bean:定义创建该 Bean对象的工厂类。那么 BeanDefinitionHolder 又是什么意思呢?
BeanDefinitionHolder 只是封装了BeanDefinition对象,并且添加了beanName 和 alias 属性。
为什么这样设计呢?因为 我们定义bean时,可以定义多个别名的。
BeanDefinitionRegistry 又是什么呢?
BeanDefintion属性来看,我们并没有看到id 和 name属性没有体现在定义中,原因是ID其左右当前Bean的存储key注册到BeanDefinitionRegistry注册器中。name作为别名key注册到AliasRegistry注册中心。最后都是指向其对应的BeanDefinition。
2、AnnotatedBeanDefinitionReader(Bean定义读取)
BeanDefinition 中存储了Bean的信息,而BeanDefintiionRegistry是基于ID和name保存了Bean的定义。从Bean到BeanDefinition然后再注册到BeanDefintionRegistry整个过程。
从上图看出Bean的定义是由AnnotatedBeanDefinitionReader从@Bean的注解中构建出的,然后基于别名注册到BeanDefinitionRegistry。
BeanDefintionReader 的结构图如下:
2.1 bean定义的加载过程
(1) org.springframework.context.support.AbstractApplicationContext#refresh
注册Bean的 代码
invokeBeanFactoryPostProcessors(beanFactory);
(2) org.springframework.context.support.AbstractApplicationContext
#invokeBeanFactoryPostProcessors
然后实例化 容器初始化 的 ConfigurationClassPostProcessor Bean,然后调用其 的postProcessBeanDefinitionRegistry方法
BeanDefinitionRegistryPostProcessor 这个接口的调用分为三部分:
(1) 调用实现PriorityOrdered 排序接口
(2) 调用实现了Ordered排序接口
(3) 没有实现接口的调用
这个接口的理解如下: 获取BeanDefinition 对象,获取到这个对象就可以获取这个对象中注册的 所有BeanDefiniton对象,我们拥有这个对象后,我们就可以对里面所有的BeanDefinition 对象进行修改。
org.springframework.context.annotation.ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry 方法
最终调用
org.springframework.context.annotation.ConfigurationClassParser
最终调用 org.springframework.context.annotation.ConfigurationClassParser
#doProcessConfigurationClass 方法
下面方法主要功能如下:
解析 @PropretySource注解解析@ComponentScan注解解析@Import解析@ImportResource解析@Bean methods处理其他bean定义加载的流程图总结Spring 对注解的处理有两种方式:
1、直接将注解Bean注册到容器中
可以在初始化容器的时候注册,也可以在容器创建之后手动调用注册方法向容器中注册,然后通过手动刷新容器,使得容器对注册的注解Bean进行处理
2、通过扫描指定的 包及其子包下的所有类
在初始化注解容器的时指定要自动扫描的路径。如果容器创建以后,如果再向容器中添加注解Bean,则 需要手动调用容器扫描的方法,然后手动刷新容器,使得容器对所注册的Bean进行处理。
如何高效地增强编程特别是debug能力?
一、要有设计良好数据结构的概念
数据结构的优良设计可以说占到好的程序设计因素的一半,许多人重视编程的工具、语言和算法,经常忽视程序里的数据结构,甚至许多人都没有数据结构设计的概念,常常遇到没有编写过的程序不知道怎么编、怎么设计,不知道从何下手,其实多数是因为没有设计数据结构的概念,尤其是用c语言或者c++语言编写的嵌入式软件及硬件底层类型的软件。软件常常是现实世界的模型,数据结构更是现实世界的映射,许多时候数据结构更是现实世界的抽象,编程是对数据的加工处理,对于数据来说,好的的数据结构设计能够使程序对数据的加工处理既目标明确清晰、又可使处理逻辑清晰,没有数据结构设计的程序则会导致程序处理数据逻辑不清、目标不明。
二、多阅读优秀的开源项目代码
能力是需要逐步培养和锻炼的,编程能力更是,为了提高编程能力,可以深入和广泛越多成熟软件的源代码,学习优秀项目的软件设计架构和编程方法,进而提高自己的编程能力。比如可以阅读linux的源代码、或者是java、dotnet框架的源代码,或者是nginx的源代码等等,通过对这些源代码的研究和学习,一定会高效的提高编程能力,例如以下书籍:
三、要养成编写测试代码的习惯
编写测试代码更是高效提升编程能力的一大有力活动,编写测试代码可以使程序功能和目的明确化和具体化,可使编程思路清晰,可有效提高程序的质量,现代的软件开发活动中,正规和重视质量、程序有使用价值的公司才会有编写测试代码的要求,入门的程序员常常没有编写测试代码的意识和习惯,可以看看这些优秀的项目是如何编写测试代码的。
四、选择使用优秀的开发调试IDE软件
比如Visual Studio 2022、visual studio code、IAR、Keil等等。
1、Visual Studio 的一些调试特点功能:
可远程调试c++、dotnent,可任意断点调试,可任意指定代码执行的行。
2、visual studio code的调试功能主流语言都支持,比如python:
用什么工具系统查看源代码比较好?
静态源代码安全检测工具比较
1. 概述
随着网络的飞速发展,各种网络应用不断成熟,各种开发技术层出不穷,上网已经成为人们日常生活中的一个重要组成部分。在享受互联网带来的各种方便之处的同时,安全问题也变得越来越重要。黑客、病毒、木马等不断攻击着各种网站,如何保证网站的安全成为一个非常热门的话题。
根据IT研究与顾问咨询公司Gartner统计数据显示,75%的黑客攻击发生在应用层。而由NIST的统计显示92%的漏洞属于应用层而非网络层。因此,应用软件的自身的安全问题是我们信息安全领域最为关心的问题,也是我们面临的一个新的领域,需要我们所有的在应用软件开发和管理的各个层面的成员共同的努力来完成。越来越多的安全产品厂商也已经在考虑关注软件开发的整个流程,将安全检测与监测融入需求分析、概要设计、详细设计、编码、测试等各个阶段以全面的保证应用安全。
对于应用安全性的检测目前大多数是通过测试的方式来实现。测试大体上分为黑盒测试和白盒测试两种。黑盒测试一般使用的是渗透的方法,这种方法仍然带有明显的黑盒测试本身的不足,需要大量的测试用例来进行覆盖,且测试完成后仍无法保证软件是否仍然存在风险。现在白盒测试中源代码扫描越来越成为一种流行的技术,使用源代码扫描产品对软件进行代码扫描,一方面可以找出潜在的风险,从内对软件进行检测,提高代码的安全性,另一方面也可以进一步提高代码的质量。黑盒的渗透测试和白盒的源代码扫描内外结合,可以使得软件的安全性得到很大程度的提高。
源代码分析技术由来已久,Colorado 大学的 Lloyd D. Fosdick 和 Leon J. Osterweil 1976 年的 9 月曾在 ACM Computing Surveys 上发表了著名的 Data Flow Analysis in Software Reliability,其中就提到了数据流分析、状态机系统、边界检测、数据类型验证、控制流分析等技术。随着计算机语言的不断演进,源代码分析的技术 也在日趋完善,在不同的细分领域,出现了很多不错的源代码分析产品,如 Klocwork Insight、Rational Software Analyzer 和 Coverity、Parasoft 等公司的产品。而在静态源代码安全分析方面,Fortify 公司和 Ounce Labs 公司的静态代码分析器都是非常不错的产品。对于源代码安全检测领域目前的供应商有很多,这里我们选择其中的三款具有代表性的进行对比,分别是 Fortify公司的Fortify SCA,Security Innovation公司的Checkmarx Suite和Armorize公司的CodeSecure。
2. 工具介绍
2.1. Fortify SCA(Source Code Analysis)
Fortify Software公司是一家总部位于美国硅谷,致力于提供应用软件安全开发工具和管理方案的厂商。Fortify为应用软件开发组织、安全审计人员和应用 安全管理人员提供工具并确立最佳的应用软件安全实践和策略,帮助他们在软件开发生命周期中花最少的时间和成本去识别和修复软件源代码中的安全隐患。 Fortify SCA是Fortify360产品套装中的一部分,它使用fortify公司特有的X-Tier Dataflow™ analysis技术去检测软件安全问题。
优点:目前全球最大静态源代码检测厂商、支持语言最多
缺点:价格昂贵、使用不方便
2.2. Checkmarx CxSuite
Checkmarx 是以色列的一家高科技软件公司。它的产品CheckmarxCxSuite专门设计为识别、跟踪和修复软件源代码上的技术和逻辑方面的安全风险。首创了以查询语言定位代码安全问题,其采用独特的词汇分析技术和CxQL专利查询技术来扫描和分析源代码中的安全漏洞和弱点。
优点:利用CxQL 查询语言自定义规则
缺点:输出报告不够美观、语言支持种类不全面
2.3. Armorize CodeSecure
阿码科技成立于2006年,总部设立于美国加州圣克拉拉市,研发中心位于台湾的南港软件工业园区。阿码科技提供全方位网络安全解决方案,捍卫企业免于受到黑客利用 Web 应用程序的漏洞所发动的攻击。阿码科技 CodeSecure可有效地协助企业与开发人员在软件开发过程及项目上线后找出 Web 应用程序风险,并清楚交代风险的来龙去脉 (如何进入程序,如何造成问题) 。CodeSecure内建语法剖析功能无需依赖编译环境,任何人员均可利用 Web操作与集成开发环境双接口,找出存在信息安全问题的源代码,并提供修补建议进行调整。CodeSecure依托于自行开发的主机进行远程源代码检 测,在保证速度稳定的同时方便用户进行Web远程操作。
优点:Web结合硬件,速度快、独具特色的深度分析
缺点:支持语言种类较少、价格不菲
3. 对比
Fortify SCA简写为SCA,Checkmarx CxSuite简写为CxSuite,Armonize CodeSecure简写为CodeSecure。
SCA CxSuite CodeSecure
厂商 Fortify Software Checkmarx 阿码科技
支持语言 Java,JSP,ASP.NET,C#,
VB.NET,C,C++,COBOL,
ColdFusion,Transact-SQL,
PL/SQL,JavaScript/Ajax,
Classic,ASP,VBScript,VB6,PHP JAVA、ASP.NET(C#、VB.NET)、JavaScript、Jscript、C/C++、APEX ASP.NET(C#、VB.NET)、ASP、JAVA、PHP
风险种类 400种 300种 参考CWE
风险类型参考来源 CWE、OWASP CWE、OWASP CWE、OWASP
漏报率 最低 低 低
误报率 稍高 低 低
是否支持SaaS 否 否 是
软硬件类型 纯软件 纯软件 Web结合硬件设备
运行平台 无限制 WindowsNET Framework 2.0 无限制
运行速度 取决于电脑配置速度不定 取决于电脑配置速度不定 由主机配置决定速度恒定
报告格式 PDF PDF、XML、CSV、HTML Web、PDF
报告内容 完整按照风险级别不同分为多个文件 核心内容完整扫描信息等缺失 非常完整但修改建议放于最后
报价 100万/软件 70万/软件 100万/软硬件
性价比 中 高 低
从软件支持的源代码语言上来说,Fortify SCA(下文简称SCA)支持多达17种语言,Checkmarx CxSuite(下文简称CxSuite)其次,而Armonize CodeSecure(下文简称CodeSecure)在三款软件中支持的最少,仅仅支持几种最常见语言,不过这几种基本涵盖了绝大多数应用中使用的编程语言,基本上可以支持现在大多数应用的源代码扫描。
从风险的分类来说,各个厂商都有其自己独特的分类方式和不同的种类数量,不过从实际应用中可以看出,总体上仍为OWASP公布的几类风险,如SQL注入、跨站脚本等,已经可以满足实际中开发人员和测试人员的需求,对于各个厂商不同的部分,一般来说主要的区别在于理解不同,看问题的角度不同,并无谁错谁对之原则性问题。
从运行平台 的角度,CodeSecure这个产品目前看来已经将SaaS的理念很好的融合进来,整个软件的操作界面为Web方式,用户可以通过网页进行操作,B/S 的方式可以将操作系统的影响降到最低,只要有一台可以上网的电脑和浏览器,无论什么操作系统都可以使用CodeSecure远程进行源代码扫描,CodeSecure依托的是一台Armonize自行研制的主机,使用硬件设备的好处在于可以适用于多种场合,不会因为测试人员或是开发人员的电脑配置影响扫描速度,扫描的速度完全取决于主机的性能。而SCA和CxSuite主要还是单机软件,但目前也在不断地向SaaS的方向进行过渡,并且提供了相当全面的贯彻整个软件开发流程(SDLC)的解决方案与服务给用户。其中CxSuite这个产品标明了使用该软件的硬件配置,为Windows操作系统 和.NET框架,这个产品目前应该为利用.NET框架进行开发,所以运行环境有一定的局限性。同时,SCA和CxSuite因为是单机软件,一方面在使用 前需要安装,另一方面其运行速度取决于运行软件的电脑性能,对于使用该软件的电脑配置有一定的要求。
三种产品都使用了各自的技术对于威胁进行检测,SCA使用的是已获得专利的X-Tier™数据流分析器,这三种产品中只有CxSuite声称可以达到零误报率,因为 其对于风险的理解是风险必须在外形上呈现出来才被考虑为实际的风险,这种理解方式可以说是别出心裁,从代码安全的角度来说,检测的目的是为了发现问题并及时改正,同时要针对于最关键的问题进行改正,这也是这三款软件都包含TOP X的统计的目的,从这一点上讲,CxSuite的风险报告是非常谨慎的。SCA在以前的使用中发现有一定的误报率,不过换个角度想,误报相比漏报是可以容 忍的,规则越严格,误报率就会相应的上升而漏报率就会相应的下降,源代码检测工具目前均为静态的进行代码的扫描,即所有的检测均是按照“规则”来进行,任 何一款产品都不可能达到真正的零误报、零漏报。所以可以说SCA的规则检查稍显简单,CxSuite和CodeSecure的检查比较谨慎。
而从漏报率上来看,谨慎的查找势必会导致漏报率的提升,这一点上SCA和CodeSecure只说明了低漏报率,而CxSuite内部包含了一种类似于C#称为 CxQL的查询语言,支持使用这种语言进行查询,方便用户进行特定的查找。另两款软件使用的都是规则的方式,其本质上应该是相类似的,这一点上规则似乎更 容易被用户接收,但是CxQL的方式确实增强了用户的操作性。
从结果输出 上来说,三款软件都支持多种输出方式,而作为报告PDF格式可以说是最书面的一种格式。在这一点上,三款软件输出格式略有不同。
SCA报告构成如下:扫描概述、按风险的分类进行详细描述,包括每个风险的发现位置,代码上下文,风险源和风险输出,以及改进方法,各类风险描述之后是按照风险类别 的所有风险的统计和按照风险等级的统计图表。SCA的每种类型的文件生成一个PDF文件,便于用户对于风险严重程度的不同采取不同的策略。
CxSuite 报告构成如下:风险按照不同分类方式的统计图、风险的数据统计情况、风险最高的文件TOP 10、按照类别进行风险详述,包括风险的名称、描述、常见危害、在软件开发各阶段的相应处理方式、详细示例,列举每一个风险的传输路径和相应位置代码。
CodeSecure 报告构成如下:目录、重点精华,包括检测信息、弱点密度规范分布趋势、弱点最多的文件TOP 5,弱点索引,弱点的详细信息,包括弱点的全程跟踪,最后是弱点信息及修改建议、所有的进入点。
三款软件的 报告中以SCA的最有特色,将不同级别的风险分文件显示对于程序员进行修改是极为方便的;CodeSecure的报告最为规范,整个文档包括目录,结构完 整,唯一的不足是将风险的修改建议放在了最后,查阅有些不便;CxSuite的内容可以说是最概要的,只包含了风险的最关键内容,对于程序员来说应该是最 简洁的。
4. 总结
这三款静态源代码扫描工具都有其各自特色,SCA支持的语言多达17种,基本上涵盖了绝大多数的应用,具有相 当广泛的适用性,但同时也使得其价格非常昂贵;CxSuite支持的语言包括常见Web应用的语言,适用范围基本上包括了大部分的应用,其使用独创的语言来自定义规则非常有特色,价格较之SCA有一定的优势;CodeSecure支持的语言较少,不过基本上可以适用于当前大多数的B/S结构应用,它是唯一 的软硬件结合的产品,在免除用户安装步骤的同时将扫描运行于特定设备之上,有助于提高运行速度,也因为包括硬件的缘故,其价格不菲。
SCA极广的适用性使其适用于横跨多种语言的开发和测试人员,CxSuite的较高性价比使其适于基于Web 的开发人员和测试人员,CodeSecure稳定的速度和B/S的独特结构使得Web开发或测试的多人同时使用变得极为方便。
随着应用的安全性越来越受到人们的重视,静态源代码扫描和动态扫描将逐渐融合,未来将会有更多更优秀的源代码扫描工具诞生,让我们拭目以待吧。
附录A 其他静态源代码检测产品
公司 产品 支持语言
art of defence Hypersource JAVA
Coverity Prevent JAVA .NET C/C++
开源 Flawfinder C/C++
Grammatech CodeSonar C/C++
HP DevInspect JAVA
KlocWork Insight JAVA .NET C/C++,C#
Ounce Labs Ounce 6 JAVA .NET
Parasoft JTEST等 JAVA .NET C/C++
SofCheck Inspector for JAVA JAVA
University of Maryland FindBugs JAVA
Veracode SecurityReview JAVA .NET
FindBug PMD/Lint4
idea为什么看不到代码?
idea中看不到代码提示,很可能是源码目录没有被idea识别,只需要标记源码目录即可,操作如下:
1.打开idea,进入idea的项目编辑界面。
2.鼠标选中项目源码所在的父目录,然后鼠标右键,在呼出的选项中选择“Make Directory as --> Source Root”即可看到代码提示了。