文章列表

Tomcat优化 tomcat启动gzip压缩

作者:じ☆ve宝贝

使用方法:修改tomcat根目录下conf中的server.xml 修改后:tomcat的server.xml文件中: ``` <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" compression="on" compressionMinSize="2048" noCompressionUserAgents="gozilla, traviata" compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain" /> ``` 添加内容为: compression="on" compressionMinSize="2048" noCompressionUserAgents="gozilla, traviata" compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain" 添加的内容的解释: compression="on" 为启用tomcat的gzip压缩 compressionMinSize="2048" 为当文件大小不小于2kb时候开始压缩 noCompressionUserAgents="gozilla, traviata" 为不支持压缩的浏览器 compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain" 为支持压缩的文件格式

你才工作两年,哪来三年工作经验?加班!

作者:じ☆ve宝贝

1、有一个小伙子在一个办公大楼的门口抽着烟,一个妇女路过他身边,并对他说,“你知道不知道这个东西会危害你的健康?我是说,你有没有注意到香烟盒上的那个警告(Warning)?” 小伙子说,“没事儿,我是一个程序员”。 那妇女说,“这又怎样?” 程序员说,“我们从来不关心Warning,只关心Error” 2、某次喝醉,老王搬出5个手指头问我,这是几,我数了数答说“4”。他说你醉了,我嘴硬说没有,再丢出3个手指头问我是几,我说是2。他说你真醉了,你好好数数,于是我就指着第一根指头,0,1,2… 老王突然老泪纵横,你果然是个杯具的程序员… 3、一程序员去面试,面试官问:“你毕业才两年,这三年工作经验是怎么来的?!”程序员答:“加班。” 4、爱情就是死循环,一旦执行就陷进去了。 爱上一个人,就是内存泄露–你永远释放不了。 真正爱上一个人的时候,那就是常量限定,永远不会改变。 女朋友就是私有变量,只有我这个类才能调用。 情人就是指针用的时候一定要注意,要不然就带来巨大的灾难。 5、波音777是有史以来第一架完全在电脑虚拟现实中设计制造的飞机,所用的设备完全由IBM公司所提供。试飞前,波音公司的总裁非常热情的邀请IBM的技术主管去参加试飞,可那位主管却说道:“啊,非常荣幸,可惜那天是我妻子的生日,所以…”![] 波音公司的总载一听就生气了:“胆小鬼,我还没告诉你试飞的日期呢!” 6、某电视片播映引起轰动,演员均为业余人士,角色把握都很到位而且自然。 记者问:“那个店小二是谁演的? 任劳任怨,随叫随到,加班还不给钱,从没怨言。” 答:“嗯,是很到位,以前干IT的” ![程序员 java c#](http://7xl64u.com1.z0.glb.clouddn.com/photo_13855379402271_948_620-300x162120150817222722.jpg)

Java设计模式(转)——13.策略模式

作者:じ☆ve宝贝

我们接着讨论设计模式,这章开始,我将讲行为型模式,共11种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。 先来张图,看看这11中模式的关系: 第一类:通过父类与子类的关系进行实现。第二类:两个类之间。第三类:类的状态。第四类:通过中间类 ![策略设计模式](/upload/content23.png "策略设计模式") ##13.策略模式(strategy) 策略模式定义了一系列算法,并将每个算法封装起来,使他们可以相互替换,且算法的变化不会影响到使用算法的客户。需要设计一个接口,为一系列实现类提供统一的方法,多个实现类实现该接口,设计一个抽象类(可有可无,属于辅助类),提供辅助函数,关系图如下: ![策略设计模式](/upload/content241.png "策略设计模式") 图中ICalculator提供统一的方法,AbstractCalculator是辅助类,提供辅助方法,接下来,依次实现下每个类: 首先统一接口: ``` public interface ICalculator { public int calculate(String exp); } ``` 辅助类: ``` public abstract class AbstractCalculator { public int[] split(String exp,String opt){ String array[] = exp.split(opt); int arrayInt[] = new int[2]; arrayInt[0] = Integer.parseInt(array[0]); arrayInt[1] = Integer.parseInt(array[1]); return arrayInt; } } ``` 三个实现类: ``` public class Plus extends AbstractCalculator implements ICalculator { @Override public int calculate(String exp) { int arrayInt[] = split(exp,"\\+"); return arrayInt[0]+arrayInt[1]; } } ``` ``` public class Minus extends AbstractCalculator implements ICalculator { @Override public int calculate(String exp) { int arrayInt[] = split(exp,"-"); return arrayInt[0]-arrayInt[1]; } } ``` ``` public class Multiply extends AbstractCalculator implements ICalculator { @Override public int calculate(String exp) { int arrayInt[] = split(exp,"\\*"); return arrayInt[0]*arrayInt[1]; } } ``` 简单的测试类: ``` public class StrategyTest { public static void main(String[] args) { String exp = "2+8"; ICalculator cal = new Plus(); int result = cal.calculate(exp); System.out.println(result); } } ``` 输出:10 策略模式的决定权在用户,系统本身提供不同算法的实现,新增或者删除算法,对各种算法做封装。因此,策略模式多用在算法决策系统中,外部用户只需要决定用哪个算法即可。

SpringBoot 注解大全,收藏了!

作者:微信小助手

<p data-mpa-powered-by="yiban.io"><strong style="text-align: center; font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif; letter-spacing: 0.544px; color: rgb(57, 137, 31);"><img class="rich_pages" data-copyright="0" data-ratio="0.6666666666666666" data-s="300,640" data-type="jpeg" data-w="1280" src="/upload/398d99ea818be829b0277e1b59a977c8.jpg" style="letter-spacing: 0.544px; box-shadow: rgb(170, 170, 170) 0em 0em 1em 0px; visibility: visible !important; width: auto !important; height: auto !important;"></strong></p> <p style="margin-top: 25px;margin-bottom: 15px;white-space: normal;font-family: -apple-system-font, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Hiragino Sans GB, Microsoft YaHei UI, Microsoft YaHei, Arial, sans-serif;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);line-height: 2em;text-align: center;"><span style="font-size: 20px;">扫描下方二维码<span style="color: rgb(201, 56, 28);"><strong>试读</strong></span></span></p> <p style="margin-bottom: 15px;white-space: normal;font-family: -apple-system-font, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Hiragino Sans GB, Microsoft YaHei UI, Microsoft YaHei, Arial, sans-serif;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);text-align: center;"><span style="color: rgb(57, 137, 31);"><strong><img class="" data-ratio="0.6666666666666666" data-type="png" data-w="600" src="/upload/3f6bb75371fa02356c9a40f699003d25.png" style="border-radius: 0em;width: 216.625px;visibility: visible !important;"></strong></span></p> <hr style="white-space: normal;border-style: solid;border-right-width: 0px;border-bottom-width: 0px;border-left-width: 0px;border-color: rgba(0, 0, 0, 0.0980392);transform-origin: 0px 0px 0px;transform: scale(1, 0.5);"> <p style="white-space: normal;"><br></p> <ul class=" list-paddingleft-2" style=""> <li><p style="line-height: 2em;"><span style="font-size: 14px;">一、注解(annotations)列表</span></p></li> <li><p style="line-height: 2em;"><span style="font-size: 14px;">二、注解(annotations)详解</span></p></li> <li><p style="line-height: 2em;"><span style="font-size: 14px;">三、JPA注解</span></p></li> <li><p style="line-height: 2em;"><span style="font-size: 14px;">四、springMVC相关注解</span></p></li> <li><p style="line-height: 2em;"><span style="font-size: 14px;">五、全局异常处理</span></p></li> </ul> <hr style="margin-top: 16px;margin-bottom: 16px;box-sizing: content-box;letter-spacing: 0.544px;white-space: normal;border-width: 0px;border-style: none;border-color: initial;height: 2px;background-color: rgb(231, 231, 231);color: rgb(52, 73, 94);font-family: Source Sans Pro, Helvetica Neue, Arial, sans-serif;font-size: 16px;text-align: start;"> <h1 style="margin-top: 35px;margin-bottom: 15px;padding-bottom: 0.5em;font-weight: bold;font-size: 1.2rem;letter-spacing: 0.544px;white-space: normal;line-height: 1.225;cursor: text;border-bottom: 1px solid rgb(221, 221, 221);color: rgb(52, 73, 94);font-family: Source Sans Pro, Helvetica Neue, Arial, sans-serif;text-align: start;background-color: rgb(255, 255, 255);">一、注解(annotations)列表</h1> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@S</strong><strong style="color: rgb(0, 0, 0);">pringBootApplication</strong>:包含了@ComponentScan、@Configuration和@EnableAutoConfiguration注解。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;">其中@ComponentScan让spring Boot扫描到Configuration类并把它加入到程序上下文。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@Configuration</strong>&nbsp;等同于spring的XML配置文件;使用Java代码可以检查类型安全。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@EnableAutoConfiguration</strong>&nbsp;自动配置。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@ComponentScan</strong>&nbsp;组件扫描,可自动发现和装配一些Bean。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@Component</strong>可配合CommandLineRunner使用,在程序启动后执行一些基础任务。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@RestController</strong>注解是@Controller和@ResponseBody的合集,表示这是个控制器bean,并且是将函数的返回值直 接填入HTTP响应体中,是REST风格的控制器。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@Autowired</strong>自动导入。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@PathVariable</strong>获取参数。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@JsonBackReference</strong>解决嵌套外链问题。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@RepositoryRestResourcepublic</strong>配合spring-boot-starter-data-rest使用。</p> <h1 style="margin-top: 35px; margin-bottom: 15px; padding-bottom: 0.5em; font-weight: bold; font-size: 1.2rem; letter-spacing: 0.544px; white-space: normal; cursor: text; border-bottom: 1px solid rgb(221, 221, 221); color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;">二、注解(annotations)详解</h1> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@SpringBootApplication</strong>:申明让spring boot自动给程序进行必要的配置,这个配置等同于:@Configuration ,@EnableAutoConfiguration 和 @ComponentScan 三个配置。</p> <pre style="letter-spacing: 0.544px;color: rgb(52, 73, 94);font-size: 16px;text-align: start;background-color: rgb(255, 255, 255);"><p style="padding: 0.5em; display: block; font-family: Consolas, Inconsolata, Courier, monospace; overflow-x: auto; font-size: 11px; word-spacing: -3px; letter-spacing: 0px; background: rgb(29, 31, 33); color: rgb(197, 200, 198); line-height: 2em; overflow-wrap: normal !important; word-break: normal !important; overflow-y: auto !important;"><span class="" style="color: rgb(178, 148, 187);overflow-wrap: inherit !important;word-break: inherit !important;">package</span>&nbsp;com.example.myproject;<br style="overflow-wrap: inherit !important;word-break: inherit !important;"><span class="" style="color: rgb(178, 148, 187);overflow-wrap: inherit !important;word-break: inherit !important;">import</span>&nbsp;org.springframework.boot.SpringApplication;<br style="overflow-wrap: inherit !important;word-break: inherit !important;"><span class="" style="color: rgb(178, 148, 187);overflow-wrap: inherit !important;word-break: inherit !important;">import</span>&nbsp;org.springframework.boot.autoconfigure.SpringBootApplication;<br style="overflow-wrap: inherit !important;word-break: inherit !important;"><br style="overflow-wrap: inherit !important;word-break: inherit !important;"><span class="" style="color: rgb(222, 147, 95);overflow-wrap: inherit !important;word-break: inherit !important;">@SpringBootApplication</span>&nbsp;<span class="" style="color: rgb(150, 152, 150);overflow-wrap: inherit !important;word-break: inherit !important;">//&nbsp;same&nbsp;as&nbsp;@Configuration&nbsp;@EnableAutoConfiguration&nbsp;@ComponentScan</span><br style="overflow-wrap: inherit !important;word-break: inherit !important;"><span class="" style="color: rgb(178, 148, 187);overflow-wrap: inherit !important;word-break: inherit !important;">public</span>&nbsp;<span class="" style="overflow-wrap: inherit !important;word-break: inherit !important;"><span class="" style="color: rgb(178, 148, 187);overflow-wrap: inherit !important;word-break: inherit !important;">class</span>&nbsp;<span class="" style="color: rgb(129, 162, 190);overflow-wrap: inherit !important;word-break: inherit !important;">Application</span>&nbsp;</span>{<br style="overflow-wrap: inherit !important;word-break: inherit !important;">&nbsp;&nbsp;&nbsp;&nbsp;<span class="" style="overflow-wrap: inherit !important;word-break: inherit !important;"><span class="" style="color: rgb(178, 148, 187);overflow-wrap: inherit !important;word-break: inherit !important;">public</span>&nbsp;<span class="" style="color: rgb(178, 148, 187);overflow-wrap: inherit !important;word-break: inherit !important;">static</span>&nbsp;<span class="" style="color: rgb(178, 148, 187);overflow-wrap: inherit !important;word-break: inherit !important;">void</span>&nbsp;<span class="" style="color: rgb(129, 162, 190);overflow-wrap: inherit !important;word-break: inherit !important;">main</span><span class="" style="color: rgb(222, 147, 95);overflow-wrap: inherit !important;word-break: inherit !important;">(String[]&nbsp;args)</span>&nbsp;</span>{<br style="overflow-wrap: inherit !important;word-break: inherit !important;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SpringApplication.run(Application.class,&nbsp;args);<br style="overflow-wrap: inherit !important;word-break: inherit !important;">&nbsp;&nbsp;&nbsp;&nbsp;}<br style="overflow-wrap: inherit !important;word-break: inherit !important;">}<br style="overflow-wrap: inherit !important;word-break: inherit !important;"></p></pre> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@</strong><strong style="color: rgb(0, 0, 0);">ResponseBody</strong>:表示该方法的返回结果直接写入HTTP response body中,一般在异步获取数据时使用,用于构建RESTful的api。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;">在使用@RequestMapping后,返回值通常解析为跳转路径,加上@responsebody后返回结果不会被解析为跳转路径,而是直接写入HTTP response body中。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;">比如异步获取json数据,加上@responsebody后,会直接返回json数据。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;">该注解一般会配合@RequestMapping一起使用。示例代码:</p> <pre style="letter-spacing: 0.544px;color: rgb(52, 73, 94);font-size: 16px;text-align: start;background-color: rgb(255, 255, 255);"><p style="padding: 0.5em; display: block; font-family: Consolas, Inconsolata, Courier, monospace; overflow-x: auto; font-size: 11px; word-spacing: -3px; letter-spacing: 0px; background: rgb(29, 31, 33); color: rgb(197, 200, 198); line-height: 2em; overflow-wrap: normal !important; word-break: normal !important; overflow-y: auto !important;"><span class="" style="color: rgb(222, 147, 95);overflow-wrap: inherit !important;word-break: inherit !important;">@RequestMapping(“/test”)</span><br style="overflow-wrap: inherit !important;word-break: inherit !important;"><span class="" style="color: rgb(222, 147, 95);overflow-wrap: inherit !important;word-break: inherit !important;">@ResponseBody</span><br style="overflow-wrap: inherit !important;word-break: inherit !important;"><span class="" style="color: rgb(178, 148, 187);overflow-wrap: inherit !important;word-break: inherit !important;">public</span>&nbsp;String&nbsp;test(){<br style="overflow-wrap: inherit !important;word-break: inherit !important;">&nbsp;&nbsp;&nbsp;&nbsp;<span class="" style="color: rgb(178, 148, 187);overflow-wrap: inherit !important;word-break: inherit !important;">return</span>”ok”;<br style="overflow-wrap: inherit !important;word-break: inherit !important;">}<br style="overflow-wrap: inherit !important;word-break: inherit !important;"></p></pre> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@Controller</strong>:用于定义控制器类,在spring 项目中由控制器负责将用户发来的URL请求转发到对应的服务接口(service层)</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;">一般这个注解在类中,通常方法需要配合注解@RequestMapping。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;">示例代码:</p> <pre style="letter-spacing: 0.544px;color: rgb(52, 73, 94);font-size: 16px;text-align: start;background-color: rgb(255, 255, 255);"><p style="padding: 0.5em; display: block; font-family: Consolas, Inconsolata, Courier, monospace; overflow-x: auto; font-size: 11px; word-spacing: -3px; letter-spacing: 0px; background: rgb(29, 31, 33); color: rgb(197, 200, 198); line-height: 2em; overflow-wrap: normal !important; word-break: normal !important; overflow-y: auto !important;"><span class="" style="color: rgb(222, 147, 95);overflow-wrap: inherit !important;word-break: inherit !important;">@Controller</span><br style="overflow-wrap: inherit !important;word-break: inherit !important;"><span class="" style="color: rgb(222, 147, 95);overflow-wrap: inherit !important;word-break: inherit !important;">@RequestMapping(“/demoInfo”)</span><br style="overflow-wrap: inherit !important;word-break: inherit !important;">publicclass&nbsp;DemoController&nbsp;{<br style="overflow-wrap: inherit !important;word-break: inherit !important;">&nbsp;&nbsp;&nbsp;&nbsp;<span class="" style="color: rgb(222, 147, 95);overflow-wrap: inherit !important;word-break: inherit !important;">@Autowired</span><br style="overflow-wrap: inherit !important;word-break: inherit !important;">&nbsp;&nbsp;&nbsp;&nbsp;<span class="" style="color: rgb(178, 148, 187);overflow-wrap: inherit !important;word-break: inherit !important;">private</span>&nbsp;DemoInfoService&nbsp;demoInfoService;<br style="overflow-wrap: inherit !important;word-break: inherit !important;"><br style="overflow-wrap: inherit !important;word-break: inherit !important;">&nbsp;&nbsp;&nbsp;&nbsp;<span class="" style="color: rgb(222, 147, 95);overflow-wrap: inherit !important;word-break: inherit !important;">@RequestMapping(<span class="" style="overflow-wrap: inherit !important;word-break: inherit !important;">"/hello"</span>)</span><br style="overflow-wrap: inherit !important;word-break: inherit !important;">&nbsp;&nbsp;&nbsp;&nbsp;<span class="" style="color: rgb(178, 148, 187);overflow-wrap: inherit !important;word-break: inherit !important;">public</span>&nbsp;String&nbsp;hello(Map <string,object> &nbsp;map){ <br style="overflow-wrap: inherit !important;word-break: inherit !important;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System. <span class="" style="color: rgb(178, 148, 187);overflow-wrap: inherit !important;word-break: inherit !important;">out</span>.println( <span class="" style="color: rgb(181, 189, 104);overflow-wrap: inherit !important;word-break: inherit !important;">"DemoController.hello()"</span>); <br style="overflow-wrap: inherit !important;word-break: inherit !important;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;map.put( <span class="" style="color: rgb(181, 189, 104);overflow-wrap: inherit !important;word-break: inherit !important;">"hello"</span>, <span class="" style="color: rgb(181, 189, 104);overflow-wrap: inherit !important;word-break: inherit !important;">"from&nbsp;TemplateController.helloHtml"</span>); <br style="overflow-wrap: inherit !important;word-break: inherit !important;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="" style="color: rgb(150, 152, 150);overflow-wrap: inherit !important;word-break: inherit !important;">//会使用hello.html或者hello.ftl模板进行渲染显示.</span> <br style="overflow-wrap: inherit !important;word-break: inherit !important;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="" style="color: rgb(178, 148, 187);overflow-wrap: inherit !important;word-break: inherit !important;">return</span> <span class="" style="color: rgb(181, 189, 104);overflow-wrap: inherit !important;word-break: inherit !important;">"/hello"</span>; <br style="overflow-wrap: inherit !important;word-break: inherit !important;">&nbsp;&nbsp;&nbsp;&nbsp;} <br style="overflow-wrap: inherit !important;word-break: inherit !important;">} <br style="overflow-wrap: inherit !important;word-break: inherit !important;"> </string,object></p></pre> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@RestController</strong>:用于标注控制层组件(如struts中的action),@ResponseBody和@Controller的合集。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;">示例代码:</p> <pre style="letter-spacing: 0.544px;color: rgb(52, 73, 94);font-size: 16px;text-align: start;background-color: rgb(255, 255, 255);"><p style="padding: 0.5em; display: block; font-family: Consolas, Inconsolata, Courier, monospace; overflow-x: auto; font-size: 11px; word-spacing: -3px; letter-spacing: 0px; background: rgb(29, 31, 33); color: rgb(197, 200, 198); line-height: 2em; overflow-wrap: normal !important; word-break: normal !important; overflow-y: auto !important;"><span class="" style="color: rgb(178, 148, 187);overflow-wrap: inherit !important;word-break: inherit !important;">package</span>&nbsp;<span class="" style="color: rgb(178, 148, 187);overflow-wrap: inherit !important;word-break: inherit !important;">com</span><span class="" style="color: rgb(204, 102, 102);overflow-wrap: inherit !important;word-break: inherit !important;">.kfit.demo.web</span>;<br style="overflow-wrap: inherit !important;word-break: inherit !important;"><br style="overflow-wrap: inherit !important;word-break: inherit !important;"><span class="" style="color: rgb(178, 148, 187);overflow-wrap: inherit !important;word-break: inherit !important;">import</span>&nbsp;<span class="" style="color: rgb(178, 148, 187);overflow-wrap: inherit !important;word-break: inherit !important;">org</span><span class="" style="color: rgb(204, 102, 102);overflow-wrap: inherit !important;word-break: inherit !important;">.springframework.web.bind.annotation.RequestMapping</span>;<br style="overflow-wrap: inherit !important;word-break: inherit !important;"><span class="" style="color: rgb(178, 148, 187);overflow-wrap: inherit !important;word-break: inherit !important;">import</span>&nbsp;<span class="" style="color: rgb(178, 148, 187);overflow-wrap: inherit !important;word-break: inherit !important;">org</span><span class="" style="color: rgb(204, 102, 102);overflow-wrap: inherit !important;word-break: inherit !important;">.springframework.web.bind.annotation.RestController</span>;<br style="overflow-wrap: inherit !important;word-break: inherit !important;"><br style="overflow-wrap: inherit !important;word-break: inherit !important;">@<span class="" style="color: rgb(178, 148, 187);overflow-wrap: inherit !important;word-break: inherit !important;">RestController</span><br style="overflow-wrap: inherit !important;word-break: inherit !important;">@RequestMapping(“/demoInfo2”)<br style="overflow-wrap: inherit !important;word-break: inherit !important;">publicclass&nbsp;DemoController2&nbsp;{<br style="overflow-wrap: inherit !important;word-break: inherit !important;"><br style="overflow-wrap: inherit !important;word-break: inherit !important;">&nbsp;&nbsp;&nbsp;&nbsp;@<span class="" style="color: rgb(178, 148, 187);overflow-wrap: inherit !important;word-break: inherit !important;">RequestMapping</span>("/<span class="" style="color: rgb(178, 148, 187);overflow-wrap: inherit !important;word-break: inherit !important;">test</span>")<br style="overflow-wrap: inherit !important;word-break: inherit !important;">&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;String&nbsp;test(){<br style="overflow-wrap: inherit !important;word-break: inherit !important;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="" style="color: rgb(178, 148, 187);overflow-wrap: inherit !important;word-break: inherit !important;">return</span>"<span class="" style="color: rgb(178, 148, 187);overflow-wrap: inherit !important;word-break: inherit !important;">ok</span>";<br style="overflow-wrap: inherit !important;word-break: inherit !important;">&nbsp;&nbsp;&nbsp;&nbsp;}<br style="overflow-wrap: inherit !important;word-break: inherit !important;">}<br style="overflow-wrap: inherit !important;word-break: inherit !important;"></p></pre> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@RequestMapping</strong>:提供路由信息,负责URL到Controller中的具体函数的映射。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@EnableAutoConfiguration</strong>:Spring Boot自动配置(auto-configuration):尝试根据你添加的jar依赖自动配置你的Spring应用。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;">例如,如果你的classpath下存在HSQLDB,并且你没有手动配置任何数据库连接beans,那么我们将自动配置一个内存型(in-memory)数据库”。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;">你可以将@EnableAutoConfiguration或者@SpringBootApplication注解添加到一个@Configuration类上来选择自动配置。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;">如果发现应用了你不想要的特定自动配置类,你可以使用@EnableAutoConfiguration注解的排除属性来禁用它们。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@ComponentScan</strong>:表示将该类自动发现扫描组件。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;">个人理解相当于,如果扫描到有@Component、@Controller、@Service等这些注解的类,并注册为Bean,可以自动收集所有的Spring组件,包括@Configuration类。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;">我们经常使用@ComponentScan注解搜索beans,并结合@Autowired注解导入。可以自动收集所有的Spring组件,包括@Configuration类。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;">如果没有配置的话,Spring Boot会扫描启动类所在包下以及子包下的使用了@Service,@Repository等注解的类。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@Configuration</strong>:相当于传统的xml配置文件,如果有些第三方库需要用到xml文件,建议仍然通过@Configuration类作为项目的配置主类——可以使用@ImportResource注解加载xml配置文件。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@Import</strong>:用来导入其他配置类。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@ImportResource</strong>:用来加载xml配置文件。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@Autowired</strong>:自动导入依赖的bean</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@Service</strong>:一般用于修饰service层的组件</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@Repository</strong>:使用@Repository注解可以确保DAO或者repositories提供异常转译,这个注解修饰的DAO或者repositories类会被ComponetScan发现并配置,同时也不需要为它们提供XML配置项。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@Bean</strong>:用@Bean标注方法等价于XML中配置的bean。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@Value</strong>:注入Spring boot application.properties配置的属性的值。示例代码:</p> <pre style="letter-spacing: 0.544px;color: rgb(52, 73, 94);font-size: 16px;text-align: start;background-color: rgb(255, 255, 255);"><p style="padding: 0.5em; display: block; font-family: Consolas, Inconsolata, Courier, monospace; overflow-x: auto; font-size: 11px; word-spacing: -3px; letter-spacing: 0px; background: rgb(29, 31, 33); color: rgb(197, 200, 198); line-height: 2em; overflow-wrap: normal !important; word-break: normal !important; overflow-y: auto !important;">@Value(<span class="" style="color: rgb(178, 148, 187);overflow-wrap: inherit !important;word-break: inherit !important;">value</span>&nbsp;=&nbsp;“<span class="" style="color: rgb(222, 147, 95);overflow-wrap: inherit !important;word-break: inherit !important;">#{message}”)</span><br style="overflow-wrap: inherit !important;word-break: inherit !important;"><span class="" style="color: rgb(178, 148, 187);overflow-wrap: inherit !important;word-break: inherit !important;">private</span>&nbsp;String&nbsp;message;<br style="overflow-wrap: inherit !important;word-break: inherit !important;"></p></pre> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@Inject</strong>:等价于默认的@Autowired,只是没有required属性;</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@</strong><strong style="color: rgb(0, 0, 0);">Component</strong>:泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@Bean</strong>:相当于XML中的,放在方法的上面,而不是类,意思是产生一个bean,并交给spring管理。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@AutoWired</strong>:自动导入依赖的bean。byType方式。把配置好的Bean拿来用,完成属性、方法的组装,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。当加上(required=false)时,就算找不到bean也不报错。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@Qualifier</strong>:当有多个同一类型的Bean时,可以用@Qualifier(“name”)来指定。与@Autowired配合使用。@Qualifier限定描述符除了能根据名字进行注入,但能进行更细粒度的控制如何选择候选者,具体使用方式如下:</p> <pre style="letter-spacing: 0.544px;color: rgb(52, 73, 94);font-size: 16px;text-align: start;background-color: rgb(255, 255, 255);"><p style="padding: 0.5em; display: block; font-family: Consolas, Inconsolata, Courier, monospace; overflow-x: auto; font-size: 11px; word-spacing: -3px; letter-spacing: 0px; background: rgb(29, 31, 33); color: rgb(197, 200, 198); line-height: 2em; overflow-wrap: normal !important; word-break: normal !important; overflow-y: auto !important;"><span class="" style="color: rgb(222, 147, 95);overflow-wrap: inherit !important;word-break: inherit !important;">@Autowired</span><br style="overflow-wrap: inherit !important;word-break: inherit !important;"><span class="" style="color: rgb(222, 147, 95);overflow-wrap: inherit !important;word-break: inherit !important;">@Qualifier(value&nbsp;=&nbsp;“demoInfoService”)</span><br style="overflow-wrap: inherit !important;word-break: inherit !important;"><span class="" style="color: rgb(178, 148, 187);overflow-wrap: inherit !important;word-break: inherit !important;">private</span>&nbsp;DemoInfoService&nbsp;demoInfoService;<br style="overflow-wrap: inherit !important;word-break: inherit !important;"></p></pre> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@Resource(name=”name”,type=”type”)</strong>:没有括号内内容的话,默认byName。与@Autowired干类似的事。</p> <h1 style="margin-top: 35px; margin-bottom: 15px; padding-bottom: 0.5em; font-weight: bold; font-size: 1.2rem; letter-spacing: 0.544px; white-space: normal; cursor: text; border-bottom: 1px solid rgb(221, 221, 221); color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;">三、JPA注解</h1> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@Entity</strong>:@Table(name=”“):表明这是一个实体类。一般用于jpa这两个注解一般一块使用,但是如果表名和实体类名相同的话,@Table可以省略</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@MappedSuperClass</strong>:用在确定是父类的entity上。父类的属性子类可以继承。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@</strong><strong style="color: rgb(0, 0, 0);">NoRepositoryBean</strong>:一般用作父类的repository,有这个注解,spring不会去实例化该repository。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@Column</strong>:如果字段名与列名相同,则可以省略。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@Id</strong>:表示该属性为主键。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@GeneratedValue(strategy = GenerationType.SEQUENCE,generator = “repair_seq”)</strong>:表示主键生成策略是sequence(可以为Auto、IDENTITY、native等,Auto表示可在多个数据库间切换),指定sequence的名字是repair_seq。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@SequenceGeneretor(name = “repair_seq”, sequenceName = “seq_repair”, allocationSize = 1)</strong>:name为sequence的名称,以便使用,sequenceName为数据库的sequence名称,两个名称可以一致。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@Transient</strong>:表示该属性并非一个到数据库表的字段的映射,ORM框架将忽略该属性。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;">如果一个属性并非数据库表的字段映射,就务必将其标示为@Transient,否则,ORM框架默认其注解为@Basic。@Basic(fetch=FetchType.LAZY):标记可以指定实体属性的加载方式</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@JsonIgnore</strong>:作用是json序列化时将Java bean中的一些属性忽略掉,序列化和反序列化都受影响。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@JoinColumn(name=”loginId”)</strong>:一对一:本表中指向另一个表的外键。一对多:另一个表指向本表的外键。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@OneToOne、@OneToMany、@ManyToOne</strong>:对应hibernate配置文件中的一对一,一对多,多对一。</p> <h1 style="margin-top: 35px; margin-bottom: 15px; padding-bottom: 0.5em; font-weight: bold; font-size: 1.2rem; letter-spacing: 0.544px; white-space: normal; cursor: text; border-bottom: 1px solid rgb(221, 221, 221); color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;">四、springMVC相关注解</h1> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@RequestMapping</strong>:@RequestMapping(“/path”)表示该控制器处理所有“/path”的UR L请求。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;">RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;">用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。该注解有六个属性:</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">params</strong>:指定request中必须包含某些参数值是,才让该方法处理。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">headers</strong>:指定request中必须包含某些指定的header值,才能让该方法处理请求。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">value</strong>:指定请求的实际地址,指定的地址可以是URI Template 模式</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">method</strong>:指定请求的method类型, GET、POST、PUT、DELETE等</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">consumes</strong>:指定处理请求的提交内容类型(Content-Type),如application/json,text/html;</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">produces</strong>:指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@RequestParam</strong>:用在方法的参数前面。<br>@RequestParam<br>String a =request.getParameter(“a”)。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@PathVariable</strong>:路径变量。如</p> <pre style="letter-spacing: 0.544px;color: rgb(52, 73, 94);font-size: 16px;text-align: start;background-color: rgb(255, 255, 255);"><p style="padding: 0.5em; display: block; font-family: Consolas, Inconsolata, Courier, monospace; overflow-x: auto; font-size: 11px; word-spacing: -3px; letter-spacing: 0px; background: rgb(29, 31, 33); color: rgb(197, 200, 198); line-height: 2em; overflow-wrap: normal !important; word-break: normal !important; overflow-y: auto !important;">RequestMapping(“user/<span class="" style="color: rgb(178, 148, 187);overflow-wrap: inherit !important;word-break: inherit !important;">get</span>/mac/{macAddress}”)<br style="overflow-wrap: inherit !important;word-break: inherit !important;">public&nbsp;<span class="" style="color: rgb(222, 147, 95);overflow-wrap: inherit !important;word-break: inherit !important;">String</span>&nbsp;getByMacAddress(<span class="" style="color: rgb(222, 147, 95);overflow-wrap: inherit !important;word-break: inherit !important;">@PathVariable</span>&nbsp;<span class="" style="color: rgb(222, 147, 95);overflow-wrap: inherit !important;word-break: inherit !important;">String</span>&nbsp;macAddress){<br style="overflow-wrap: inherit !important;word-break: inherit !important;">&nbsp;&nbsp;&nbsp;&nbsp;<span class="" style="color: rgb(150, 152, 150);overflow-wrap: inherit !important;word-break: inherit !important;">//do&nbsp;something;</span><br style="overflow-wrap: inherit !important;word-break: inherit !important;">}<br style="overflow-wrap: inherit !important;word-break: inherit !important;"></p></pre> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;">参数与大括号里的名字一样要相同。</p> <h1 style="margin-top: 35px; margin-bottom: 15px; padding-bottom: 0.5em; font-weight: bold; font-size: 1.2rem; letter-spacing: 0.544px; white-space: normal; cursor: text; border-bottom: 1px solid rgb(221, 221, 221); color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;">五、全局异常处理</h1> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@ControllerAdvice</strong>:包含@Component。可以被扫描到。统一处理异常。</p> <p style="margin-top: 0.8em; margin-bottom: 0.8em; letter-spacing: 0.544px; white-space: normal; color: rgb(52, 73, 94); font-family: &quot;Source Sans Pro&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif; font-size: 16px; text-align: start; background-color: rgb(255, 255, 255); line-height: 2em;"><strong style="color: rgb(0, 0, 0);">@ExceptionHandler(Exception.class)</strong>:用在方法上面表示遇到这个异常就执行以下方法。</p> <p style="white-space: normal; text-align: center;"><strong style="font-family: 微软雅黑; text-align: center; white-space: normal; color: rgb(57, 137, 31); letter-spacing: 0.544px;"><span style="font-size: 24px;">End</span></strong></p> <p style="white-space: normal;"><span style="font-size: 12px;">作者:tanwei81<br></span></p> <p style="white-space: normal;"><span style="font-size: 12px;">来源:</span></p> <p style="white-space: normal;"><span style="font-size: 12px;">https://www.cnblogs.com/tanwei81/p/6814022.html</span></p> <p style="white-space: normal;"><span style="font-size: 12px;">本文版权归作者所有</span></p> <p style="margin-right: 5px;margin-left: 5px;white-space: normal;font-family: 微软雅黑;background-color: rgb(255, 255, 255);font-size: 16px;line-height: 1.75em;letter-spacing: 0.5px;text-align: center;overflow-wrap: break-word !important;"><br></p> <hr> <ol class=" list-paddingleft-2" style=""></ol> <p style="white-space: normal;font-family: -apple-system-font, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Hiragino Sans GB, Microsoft YaHei UI, Microsoft YaHei, Arial, sans-serif;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);line-height: 2em;text-align: center;"><span style="font-size: 14px;">长按下图二维码,即刻关注【<span style="color: rgb(241, 136, 35);"><strong>狸猫技术窝</strong></span>】</span></p> <p style="white-space: normal;font-family: -apple-system-font, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Hiragino Sans GB, Microsoft YaHei UI, Microsoft YaHei, Arial, sans-serif;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);line-height: 2em;text-align: center;"><span style="color: rgb(0, 0, 0);font-size: 14px;letter-spacing: 0.544px;">阿里、京东、美团、字节跳动</span><br></p> <p style="white-space: normal;font-family: -apple-system-font, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Hiragino Sans GB, Microsoft YaHei UI, Microsoft YaHei, Arial, sans-serif;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);line-height: 2em;text-align: center;"><span style="font-size: 14px;"><strong><span style="font-size: 13px;color: rgb(0, 0, 0);">顶尖技术专家</span></strong><span style="font-size: 13px;color: rgb(0, 0, 0);">坐镇</span></span></p> <p style="white-space: normal;font-family: -apple-system-font, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Hiragino Sans GB, Microsoft YaHei UI, Microsoft YaHei, Arial, sans-serif;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);line-height: 2em;text-align: center;"><span style="color: rgb(0, 0, 0);font-size: 14px;">为IT人打造一个 “有温度” 的技术窝!</span></p> <section class="" data-tools-id="79539" style="white-space: normal; font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif; letter-spacing: 0.544px; background-color: rgb(255, 255, 255);"> <section style="margin: 10px auto;display: flex;justify-content: center;align-items: center;"> <section style="padding: 30px;background-image: url(https://mmbiz.qpic.cn/mmbiz_gif/vnOqylzBGCQHu6jrGZMlKlQlriarYFuN2jzLbPCJRlbydFZSlxHHLALHPenWJGC9WFtiaRFyMvicibKbv6nwdHibbiaw/640?wx_fmt=gif);background-position: center center;background-repeat: repeat;"> <p style="text-align: center;"><img class="rich_pages" data-copyright="0" data-ratio="0.6666666666666666" data-s="300,640" data-type="jpeg" data-w="258" src="/upload/578288c965b89f74b583291d3fc98c86.jpg" style="visibility: visible !important;width: 258px !important;"></p> <p><br></p> </section> </section> </section>

一份还热乎的蚂蚁金服面经(已拿Offer)!附答案!!

作者:微信小助手

<p><img class="rich_pages" data-copyright="0" data-ratio="0.66640625" data-s="300,640" src="/upload/888cc7a35e601796be214b7d2c9a96b0.jpg" data-type="jpeg" data-w="1280" style=""></p> <p><span style="font-size: 15px;"></span><br></p> <p><span style="font-size: 15px;">经历了漫长一个月的等待,终于在前几天通过面试官获悉已被蚂蚁金服录取,这期间的焦虑、痛苦自不必说,知道被录取的那一刻,一整年的阴霾都一扫而空了。作者面的是阿里的Java研发工程师岗,面试流程是3轮技术面+1轮hr面。由于面试过程中高度紧张,本文中只列出了还记得的部分题目。</span></p> <p><span style="font-size: 15px;"><br></span></p> <section xmlns="http://www.w3.org/1999/xhtml"> <section label="Copyleft 2018 iPaiban All lefts Reserved (本样式已做版权保护,未经正式授权不允许任何第三方编辑器、企业、个人使用,违者必纠)" style="width: 24rem;border-width: initial;border-color: initial;border-style: none;margin: 0.5rem auto;" donone="shifuMouseDownPayStyle('shifu_imi_59')"> <section style="width: 100%;display: flex;flex-direction: row;justify-content: center;align-items: center;"> <section style="width:1.2rem;height:1px;border-top: 1px solid #000;" class="ipaiban-btc"></section> <section style="margin-right: 0.8rem;margin-left: 0.8rem;font-size: 1.3rem;"> <p>01</p> </section> <section style="width:1.2rem;height:1px;border-top: 1px solid #000;" class="ipaiban-btc"></section> </section> <section style="font-size: 0.875rem;width: 100%;text-align: center;"> <p><span style="font-size: 16px;"><strong>意外的一面</strong></span></p> </section> </section> </section> <p><span style="font-size: 15px;"></span><br></p> <p><span style="font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;">一面的时候大概是3月12号,面完等了差不多半个月才突然接到二面面试官的电话。</span><span style="font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;">一面可能是简历面,所以问题比较简单。</span><br></p> <p><span style="font-size: 15px;"><br></span></p> <p><strong><span style="font-size: 15px;">ArrayList和LinkedList区别</span></strong><span style="font-size: 15px;"></span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">ArrayList 是一个可改变大小的数组。当更多的元素加入到ArrayList中时,其大小将会动态地增长。内部的元素可以直接通过get与set方法进行访问,因为ArrayList本质上就是一个数组,</span><span style="font-size: 15px;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;">LinkedList 是一个双链表,在添加和删除元素时具有比ArrayList更好的性能,但在get与set方面弱于ArrayList。</span></p> <p><span style="font-size: 15px;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;"><br></span></p> <p><span style="font-size: 15px;">当然,这些对比都是指数据量很大或者操作很频繁的情况下的对比,如果数据和运算量很小,那么对比将失去意义。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><strong><span style="font-size: 15px;">什么情况会造成内存泄漏</span></strong><span style="font-size: 15px;"></span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">在Java中,内存泄漏就是存在一些被分配的对象,这些对象有下面两个特点:</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">首先,这些对象是可达的,即在有向图中,存在通路可以与其相连;</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">其次,这些对象是无用的,即程序以后不会再使用这些对象。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">如果对象满足这两个条件,这些对象就可以判定为Java中的内存泄漏,这些对象不会被GC所回收,然而它却占用内存。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><strong><span style="font-size: 15px;">什么是线程死锁,如何解决&nbsp;</span></strong></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">产生死锁的条件有四个:</span></p> <p><span style="font-size: 15px;"><br></span></p> <ol class=" list-paddingleft-2" style="list-style-type: decimal;"> <li><p><span style="font-size: 15px;">互斥条件:所谓互斥就是进程在某一时间内独占资源。</span></p></li> <li><p><span style="font-size: 15px;">请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。</span></p></li> <li><p><span style="font-size: 15px;">不剥夺条件:进程已获得资源,在末使用完之前,不能强行剥夺。</span></p></li> <li><p><span style="font-size: 15px;">循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。</span></p></li> </ol> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">线程死锁是因为多线程访问共享资源,由于访问的顺序不当所造成的,通常是一个线程锁定了一个资源A,而又想去锁定资源B;在另一个线程中,锁定了资源B,而又想去锁定资源A以完成自身的操作,两个线程都想得到对方的资源,而不愿释放自己的资源,造成两个线程都在等待,而无法执行的情况。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">要解决死锁,可以从死锁的四个条件出发,只要破坏了一个必要条件,那么我们的死锁就解决了。在java中使用多线程的时候一定要考虑是否有死锁的问题哦。</span></p> <p><strong><span style="font-size: 15px;"><br></span></strong></p> <p><strong><span style="font-size: 15px;">红黑树是什么?怎么实现?时间复杂度</span></strong></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">红黑树(Red-Black Tree,简称R-B Tree),它一种特殊的二叉查找树。红黑树是特殊的二叉查找树,意味着它满足二叉查找树的特征:任意一个节点所包含的键值,大于等于左孩子的键值,小于等于右孩子的键值。除了具备该特性之外,红黑树还包括许多额外的信息。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">红黑树的每个节点上都有存储位表示节点的颜色,颜色是红(Red)或黑(Black)。红黑树的特性:</span></p> <p><span style="font-size: 15px;"><br></span></p> <ol class=" list-paddingleft-2" style=""> <li><p><span style="font-size: 15px;">每个节点或者是黑色,或者是红色。</span></p></li> <li><p><span style="font-size: 15px;">根节点是黑色。</span></p></li> <li><p><span style="font-size: 15px;">每个叶子节点是黑色。</span></p></li> <li><p><span style="font-size: 15px;">如果一个节点是红色的,则它的子节点必须是黑色的。</span></p></li> <li><p><span style="font-size: 15px;">从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点。</span></p></li> </ol> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">关于它的特性,需要注意的是:</span></p> <p><span style="font-size: 15px;"><br></span></p> <ol class=" list-paddingleft-2" style="list-style-type: decimal;"> <li><p><span style="font-size: 15px;">特性(3)中的叶子节点,是只为空(NIL或null)的节点。</span></p></li> <li><p><span style="font-size: 15px;">特性(5),确保没有一条路径会比其他路径长出俩倍。因而,红黑树是相对是接近平衡的二叉树。</span></p></li> </ol> <p><span style="font-size: 15px;"><br></span></p> <p><img class="" data-ratio="0.4870689655172414" data-type="jpeg" data-w="928" src="/upload/3147f67dad148f243376a295f05e6711.jpg" style="box-sizing: border-box !important;overflow-wrap: break-word !important;width: 677px !important;visibility: visible !important;"></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">具体实现代码这里不贴了,要实现起来,需要包含的基本操作是添加、删除和旋转。在对红黑树进行添加或删除后,会用到旋转方法。旋转的目的是让树保持红黑树的特性。旋转包括两种:左旋 和 右旋。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">红黑树的应用比较广泛,主要是用它来存储有序的数据,它的查找、插入和删除操作的时间复杂度是O(lgn)。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><strong><span style="font-size: 15px;">TCP三次握手&nbsp;</span></strong></p> <p><strong><span style="font-size: 15px;"><br></span></strong></p> <p><span style="font-size: 15px;">三次握手(three times handshake;three-way handshake)所谓的“三次握手”即对每次发送的数据量是怎样跟踪进行协商使数据段的发送和接收同步,根据所接收到的数据量而确定的数据确认数及数据发送、接收完毕后何时撤消联系,并建立虚连接。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">为了提供可靠的传送,TCP在发送新的数据之前,以特定的顺序将数据包的序号,并需要这些包传送给目标机之后的确认消息。TCP总是用来发送大批量的数据。当应用程序在收到数据后要做出确认时也要用到TCP。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><img class="" data-ratio="0.6007802340702211" data-type="jpeg" data-w="769" src="/upload/247aa212bdb0d092495152631548499a.jpg" style="box-sizing: border-box !important;overflow-wrap: break-word !important;width: 677px !important;visibility: visible !important;"></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers);</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。</span></p> <p><span style="font-size: 15px;"><br></span></p> <section class="" mpa-from-tpl="t"> <section xmlns="http://www.w3.org/1999/xhtml"> <section label="Copyleft 2018 iPaiban All lefts Reserved (本样式已做版权保护,未经正式授权不允许任何第三方编辑器、企业、个人使用,违者必纠)" style="width: 24rem;border-width: initial;border-color: initial;border-style: none;margin: 0.5rem auto;" donone="shifuMouseDownPayStyle('shifu_imi_59')"> <section style="width: 100%;display: flex;flex-direction: row;justify-content: center;align-items: center;"> <section style="width:1.2rem;height:1px;border-top: 1px solid #000;" class="ipaiban-btc"></section> <section style="margin-right: 0.8rem;margin-left: 0.8rem;font-size: 1.3rem;"> <p>02</p> </section> <section style="width:1.2rem;height:1px;border-top: 1px solid #000;" class="ipaiban-btc"></section> </section> <section style="font-size: 0.875rem;width: 100%;text-align: center;"> <p><span style="font-size: 16px;"><strong>突然的二面</strong></span></p> </section> </section> </section> <p><span style="font-size: 15px;"></span><br></p> <p><span style="font-size: 15px;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;">一面的时候大概是3月12号,面完等了差不多半个月才突然接到二面面试官的电话。</span><br><span style="font-size: 15px;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;"></span></p> </section> <p><span style="font-size: 15px;"><br></span></p> <p><strong><span style="font-size: 15px;">介绍项目</span></strong><span style="font-size: 15px;"></span></p> <p><span style="font-size: 15px;"><br></span></p> <p><strong><span style="font-size: 15px;">Storm怎么保证一致性&nbsp;</span></strong></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">Storm是一个分布式的流处理系统,利用anchor和ack机制保证所有tuple都被成功处理。如果tuple出错,则可以被重传,但是如何保证出错的tuple只被处理一次呢?Storm提供了一套事务性组件Transaction Topology,用来解决这个问题。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">Transactional Topology目前已经不再维护,由Trident来实现事务性topology,但是原理相同。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">参考:https://dwz.cn/8bXRPexB</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><strong><span style="font-size: 15px;">说一下hashmap以及它是否线程安全</span></strong><span style="font-size: 15px;"></span></p> <p><strong><span style="font-size: 15px;"><br></span></strong></p> <p><span style="font-size: 15px;">HashMap基于哈希表的 Map 接口的实现。HashMap中,null可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为null。HashMap中hash数组的默认大小是16,而且一定是2的指数。Hashtable、HashMap都使用了 Iterator。而由于历史原因,Hashtable还使用了Enumeration的方式 。HashMap 实现 Iterator,支持fast-fail。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">哈希表是由数组+链表组成的,它是通过把key值进行hash来定位对象的,这样可以提供比线性存储更好的性能。</span></p> <p><span style="font-size: 15px;"><br></span></p> <figure> <img class="" data-ratio="0.607421875" data-type="jpeg" data-w="1024" title="" src="/upload/a2bfaa000b92e758a77670a5fa3e1267.jpg" style="margin-right: auto;margin-left: auto;font-size: inherit;color: inherit;line-height: inherit;display: block;box-sizing: border-box !important;overflow-wrap: break-word !important;width: 677px !important;visibility: visible !important;"> </figure> <p><br></p> <p><span style="font-size: 15px;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;">HashMap不是线程安全的。</span><br></p> <p><span style="font-size: 15px;"><br></span></p> <p><strong><span style="font-size: 15px;">十亿条淘宝购买记录,怎么获取出现最多的前十个&nbsp;</span></strong></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">这是一道典型的有限内存的海量数据处理的题目。一般这类题目的解答无非是以下几种:</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">分治,hash映射,堆排序,双层桶划分,Bloom Filter,bitmap,数据库索引,mapreduce等。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">具体情形都有很多不同的方案。这类题目可以到网上搜索一下,了解下套路,后面就基本都会了。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><strong><span style="font-size: 15px;">平时有没有用linux系统,怎么查看某个进程&nbsp;</span></strong></p> <p><span style="font-size: 15px;"><br></span></p> <p style="text-align: center;"><img class="rich_pages" data-ratio="0.2297872340425532" data-s="300,640" src="/upload/2f8675fde23828cf3e36833806b0857c.png" data-type="png" data-w="940" style=""></p> <section data-mpa-preserve-tpl-color="t" data-mpa-template="t" class="" mpa-preserve="t" mpa-from-tpl="t"> <pre><span style="font-size: 15px;"></span></pre> <pre><span style="font-size: 15px;"><br></span></pre> </section> <p><strong><span style="font-size: 15px;">说一下Innodb和MySIAM的区别</span></strong><span style="font-size: 15px;"></span></p> <p><strong><span style="font-size: 15px;"><br></span></strong></p> <p><span style="font-size: 15px;">MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持。MyISAM类型的表强调的是性能,其执行数度比InnoDB类型更快,但是不提供事务支持,而InnoDB提供事务支持以及外部键等高级数据库功能。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">InnoDB不支持FULLTEXT类型的索引。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">InnoDB 中不保存表的具体行数,也就是说,执行select count(*) from table时,InnoDB要扫描一遍整个表来计算有多少行,但是MyISAM只要简单的读出保存好的行数即可。注意的是,当count(*)语句包含 where条件时,两种表的操作是一样的。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">对于AUTO_INCREMENT类型的字段,InnoDB中必须包含只有该字段的索引,但是在MyISAM表中,可以和其他字段一起建立联合索引。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">DELETE FROM table时,InnoDB不会重新建立表,而是一行一行的删除。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">LOAD TABLE FROM MASTER操作对InnoDB是不起作用的,解决方法是首先把InnoDB表改成MyISAM表,导入数据后再改成InnoDB表,但是对于使用的额外的InnoDB特性(例如外键)的表不适用。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><strong><span style="font-size: 15px;">说一下jvm内存模型,介绍一下你了解的垃圾收集器</span></strong><span style="font-size: 15px;"></span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">其实并没有jvm内存模型的概念。应该是Java内存模型或者jvm内存结构,这里面试者一定要听清楚问的是哪个,再回答。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><strong><span style="font-size: 15px;">你说你是大数据方向的,了解哪些大数据框架</span></strong><span style="font-size: 15px;"></span></p> <p><br></p> <p><span style="font-size: 15px;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;">作者回答了一些zookeeper、storm、HDFS、Hbase等</span><br></p> <p><span style="font-size: 15px;"><br></span></p> <p><strong><span style="font-size: 15px;">其他问题</span></strong><span style="font-size: 15px;"></span></p> <p><strong><span style="font-size: 15px;"><br></span></strong></p> <p><span style="font-size: 15px;">100个有序的整型,如何打乱顺序?</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">如何设计一个可靠的UDP协议?</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">二面大概就是这些,其中storm一致性这个问题被面试官怀疑了一下,就有点紧张,其实没答错,所以还是要对知识掌握得更明确才行。</span></p> <p><span style="font-size: 15px;"><br></span></p> <section xmlns="http://www.w3.org/1999/xhtml"> <section label="Copyleft 2018 iPaiban All lefts Reserved (本样式已做版权保护,未经正式授权不允许任何第三方编辑器、企业、个人使用,违者必纠)" style="width: 24rem;border-width: initial;border-color: initial;border-style: none;margin: 0.5rem auto;" donone="shifuMouseDownPayStyle('shifu_imi_59')"> <section style="width: 100%;display: flex;flex-direction: row;justify-content: center;align-items: center;"> <section style="width:1.2rem;height:1px;border-top: 1px solid #000;" class="ipaiban-btc"></section> <section style="margin-right: 0.8rem;margin-left: 0.8rem;font-size: 1.3rem;"> <p>03</p> </section> <section style="width:1.2rem;height:1px;border-top: 1px solid #000;" class="ipaiban-btc"></section> </section> <section style="font-size: 0.875rem;width: 100%;text-align: center;"> <p><strong><span style="font-size: 16px;">准备充足的三面</span></strong></p> </section> </section> </section> <p><br></p> <p><span style="font-size: 15px;">清明节的时候例外地没有回家扫墓,因为知道自己的弱项是操作系统和海量数据题这块,所以想着恶补这方面的知识,不过之后的面试意外的并没有问到这方面的内容。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><strong><span style="font-size: 15px;">介绍项目</span></strong><span style="font-size: 15px;"></span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">项目介绍完之后没问太多</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><strong><span style="font-size: 15px;">介绍一下hashmap</span></strong><span style="font-size: 15px;"></span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">HashMap真的是面试高频题,多次面试都问到了,一定要掌握。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><strong><span style="font-size: 15px;">介绍一下并发</span></strong><span style="font-size: 15px;"></span></p> <p><strong><span style="font-size: 15px;"><br></span></strong></p> <p><span style="font-size: 15px;">这里可以把整个并发的体系都说下,包括volatile、synchronized、lock、乐观悲观锁、锁膨胀、锁降级、线程池等。</span></p> <p><strong><span style="font-size: 15px;"><br></span></strong></p> <p><strong><span style="font-size: 15px;">银行账户读写怎么做</span></strong><span style="font-size: 15px;"></span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">我说了读写锁以及可能出现死锁问题</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><strong><span style="font-size: 15px;">说一下关系型数据库和非关系型数据库的区别&nbsp;</span></strong><span style="font-size: 15px;"></span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">非关系型数据库的优势:</span></p> <p><span style="font-size: 15px;"><br></span></p> <ol class=" list-paddingleft-2" style=""> <li><p><span style="font-size: 15px;">性能:NOSQL是基于键值对的,可以想象成表中的主键和值的对应关系,而且不需要经过SQL层的解析,所以性能非常高</span></p></li> <li><p><span style="font-size: 15px;">可扩展性:同样也是因为基于键值对,数据之间没有耦合性,所以非常容易水平扩展。</span></p></li> </ol> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">使用场景:日志、埋点、论坛、博客等</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">关系型数据库的优势:</span></p> <p><span style="font-size: 15px;"><br></span></p> <ol class=" list-paddingleft-2" style=""> <li><p><span style="font-size: 15px;">复杂查询:可以用SQL语句方便的在一个表以及多个表之间做非常复杂的数据查询</span></p></li> <li><p><span style="font-size: 15px;">事务支持:使得对于安全性能很高的数据访问要求得以实现。</span></p></li> </ol> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">使用场景:所有有逻辑关系的数据存储</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><strong><span style="font-size: 15px;">如何访问链表中间节点</span></strong><span style="font-size: 15px;"></span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">对于这个问题,我们首先能够想到的就是先遍历一遍整个的链表,然后计算出链表的长度,进而遍历第二遍找出中间位置的数据。这种方式非常简单。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">若题目要求只能遍历一次链表,那又当如何解决问题?</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">可以采取建立两个指针,一个指针一次遍历两个节点,另一个节点一次遍历一个节点,当快指针遍历到空节点时,慢指针指向的位置为链表的中间位置,这种解决问题的方法称为快慢指针方法。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><strong><span style="font-size: 15px;">说下进程间通信,以及各自的区别</span></strong><span style="font-size: 15px;"></span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">进程间通信是指在不同进程之间传播或交换信息。方式通常有管道(包括无名管道和命名管道)、消息队列、信号量、共享存储、Socket、Streams等。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><strong><span style="font-size: 15px;">访问淘宝网页的一个具体流程,从获取ip地址,到怎么返回相关内容</span></strong><span style="font-size: 15px;"></span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">先通过DNS解析到服务器地址,然后反向代理、负载均衡服务器等,寻找集群中的一台机器来真正执行你的请求。还可以介绍CDN、页面缓存、Cookie以及session等。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">这个过程还包括三次握手、HTTP request中包含哪些内容,状态码等,还有OSI七层分层可以介绍。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">服务器接到请求后,会执行业务逻辑,执行过程中可以按照MVC来分别介绍。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">服务处理过程中是否调用其他RPC服务或者异步消息,这个过程包含服务发现与注册,消息路由。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">最后查询数据库,会不会经过缓存?是不是关系型数据库?是会分库分表还是做哪些操作?</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">对于数据库,分库分表如果数据量大的话是有必要的,一般业务根据一个分表字段进行取模进行分表,而在做数据库操作的时候,也根据同样的规则,决定数据的读写操作对应哪张表。这种也有开源的实现的,如阿里的TDDL就有这种功能。分库分表还涉及到很多技术,比如sequence如何设置 ,如何解决热点问题等。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">最后再把处理结果封装成response,返回给客户端。浏览器再进行页面渲染。</span></p> <p><span style="font-size: 15px;"><br></span></p> <section xmlns="http://www.w3.org/1999/xhtml"> <section label="Copyleft 2018 iPaiban All lefts Reserved (本样式已做版权保护,未经正式授权不允许任何第三方编辑器、企业、个人使用,违者必纠)" style="width: 24rem;border-width: initial;border-color: initial;border-style: none;margin: 0.5rem auto;" donone="shifuMouseDownPayStyle('shifu_imi_59')"> <section style="width: 100%;display: flex;flex-direction: row;justify-content: center;align-items: center;"> <section style="width:1.2rem;height:1px;border-top: 1px solid #000;" class="ipaiban-btc"></section> <section style="margin-right: 0.8rem;margin-left: 0.8rem;font-size: 1.3rem;"> <p>04</p> </section> <section style="width:1.2rem;height:1px;border-top: 1px solid #000;" class="ipaiban-btc"></section> </section> <section style="font-size: 0.875rem;width: 100%;text-align: center;"> <p><strong><span style="font-size: 16px;">焦虑的hr面</span></strong></p> </section> </section> </section> <p><br></p> <p><span style="font-size: 15px;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;">之所以说hr面焦虑,是因为面试前我还在看IG的半决赛(实在复习不下),接到电话的时候分外紧张,在一些点上答得很差。</span><br><span style="font-size: 15px;"></span></p> <p><span style="font-size: 15px;"><br></span></p> <p><strong><span style="font-size: 15px;">遇到什么挫折</span></strong><span style="font-size: 15px;"></span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">这种问题主要考察面试者遇见困难是否能坚持下去,并且可以看出他的解决问题的能力。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">可以简单描述挫折,并说明自己如何克服,最终有哪些收获。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><strong><span style="font-size: 15px;">职业规划&nbsp;</span></strong><span style="font-size: 15px;"></span></p> <p><strong><span style="font-size: 15px;"><br></span></strong></p> <p><span style="font-size: 15px;">表明自己决心,首先自己不准备继续求学了,必须招工作了。然后说下自己不会短期内换行业,或者换工作,自己比较喜欢,希望可以坚持几年看自己的兴趣再规划之类的。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><strong><span style="font-size: 15px;">对阿里的认识&nbsp;</span></strong><span style="font-size: 15px;"></span></p> <p><strong><span style="font-size: 15px;"><br></span></strong></p> <p><span style="font-size: 15px;">这个比较简答,夸就行了。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><strong><span style="font-size: 15px;">有什么崇拜的人吗</span></strong><span style="font-size: 15px;"></span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">我说了詹姆斯哈登,hr小姐姐居然笑了。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">这个可以说一些IT大牛。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><strong><span style="font-size: 15px;">希望去哪里就业</span></strong><span style="font-size: 15px;"></span></p> <p><strong><span style="font-size: 15px;"><br></span></strong></p> <p><span style="font-size: 15px;">这个问题果断回答该公司所在的城市啊。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><strong><span style="font-size: 15px;">其他问题</span></strong></p> <p><strong><span style="font-size: 15px;"><br></span></strong></p> <p><span style="font-size: 15px;">有什么兴趣爱好,能拿得上台表演的有吗</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">记忆深刻的事情</span></p> <p><span style="font-size: 15px;"><br></span></p> <section class="" mpa-from-tpl="t"> <section xmlns="http://www.w3.org/1999/xhtml"> <section label="Copyleft 2018 iPaiban All lefts Reserved (本样式已做版权保护,未经正式授权不允许任何第三方编辑器、企业、个人使用,违者必纠)" style="width: 24rem;border-width: initial;border-color: initial;border-style: none;margin: 0.5rem auto;" donone="shifuMouseDownPayStyle('shifu_imi_59')"> <section style="width: 100%;display: flex;flex-direction: row;justify-content: center;align-items: center;"> <section style="width:1.2rem;height:1px;border-top: 1px solid #000;" class="ipaiban-btc"></section> <section style="margin-right: 0.8rem;margin-left: 0.8rem;font-size: 1.3rem;"> <p>05</p> </section> <section style="width:1.2rem;height:1px;border-top: 1px solid #000;" class="ipaiban-btc"></section> </section> <section style="font-size: 0.875rem;width: 100%;text-align: center;"> <p><span style="font-size: 16px;"><strong>总结</strong></span><br></p> </section> </section> </section> <p><span style="font-size: 15px;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;"></span><br></p> </section> <p><span style="font-size: 15px;">提前批更多的是考察基础知识,大公司都有自己在用的框架,你进去后基本上得重新学这些框架,所以对他们来说,基础是否扎实才是考察的关键。</span></p> <p><span style="font-size: 15px;background-color: rgb(253, 240, 179);"><br></span></p> <p><span style="background-color: rgb(253, 240, 179);font-size: 15px;">基础包括:操作系统、linxu、数据库、数据结构、算法、java(基础、容器、高并发、jvm)、计算机网络等。</span><strong><span style="font-size: 15px;"></span></strong></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">建议要投资知识,从寒假到现在,先后买了9个极客时间的课程、订阅了H神的知识星球、当当买了四五本相关技术书籍…</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">虽然购买的课很多还来不及读(惭愧)</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">当时我问一个java群的师兄,学不下了怎么办,他说,换种姿势继续学,还别说,有时候失眠的时候,我都在看极客时间或知识星球催眠自己…</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">要对知识做好总结,虽然以前也有记录简书的习惯,但是大多数时候都是写了不发表,自己做一个记忆的作用,3月份我给自己的要求就是,对每个知识点要做到能够有自己的理解,然后写一篇质量较好的博客总结。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">面试建议是,</span><span style="font-size: 15px;background-color: rgb(253, 240, 179);">一定要自信,敢于表达</span><span style="font-size: 15px;">,面试的时候我们对知识的掌握有时候很难面面俱到,把自己的思路说出来,而不是直接告诉面试官自己不懂,这也是可以加分的。</span></p> <p><span style="font-size: 15px;"><br></span></p> <section class="" mpa-from-tpl="t"> <section xmlns="http://www.w3.org/1999/xhtml"> <section label="Copyleft 2018 iPaiban All lefts Reserved (本样式已做版权保护,未经正式授权不允许任何第三方编辑器、企业、个人使用,违者必纠)" style="width: 24rem;border-width: initial;border-color: initial;border-style: none;margin: 0.5rem auto;" donone="shifuMouseDownPayStyle('shifu_imi_59')"> <section style="width: 100%;display: flex;flex-direction: row;justify-content: center;align-items: center;"> <section style="width:1.2rem;height:1px;border-top: 1px solid #000;" class="ipaiban-btc"></section> <section style="margin-right: 0.8rem;margin-left: 0.8rem;font-size: 1.3rem;"> <p>06</p> </section> <section style="width:1.2rem;height:1px;border-top: 1px solid #000;" class="ipaiban-btc"></section> </section> <section style="font-size: 0.875rem;width: 100%;text-align: center;"> <p><strong><span style="font-size: 16px;">最后</span></strong><br></p> </section> </section> </section> <p><span style="font-size: 15px;"></span><br></p> <p><span style="font-size: 15px;">总之,可以拿到蚂蚁金服的offer真的很意外,也很幸运,蚂蚁金服从来是我觉得很难达到的目标,但它确实发生了,也许这就是幸福来敲门吧,我可以给到自己或其他人的建议就是,一定要把握好时机。</span><span style="font-size: 15px;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;"></span><br><span style="font-size: 15px;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;"></span></p> </section> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">Don't ever let somebody tell you you can't do something, not even me. You got a dream, you gotta protect it. People can't do something by themselves,they wanna tell you you can not do it. If You want something. Go get it!</span></p> <p><span style="font-size: 15px;"><br></span></p> <p style="text-align: center;"><img class="rich_pages" data-copyright="0" data-ratio="0.5493333333333333" data-s="300,640" src="/upload/c38de56b8e12bf71c5dce5ac2524c8.png" data-type="png" data-w="750" style=""></p> <p><span style="font-size: 15px;"></span></p>

使用批处理备份桌面图标位置软件 强迫症患者福音

作者:じ☆ve宝贝

来自 作者 52P 分享的代码 简单说 你桌面的图标怎么摆放 在什么位置 都可以备份了,万一不小心搞乱了 直接还原。 强迫症的福音,对于没有强迫症的 当批处理学习了。 ![](/upload/f8dab3e5822a442482240b24251d99a7.jpg) ``` @echo off title 桌面图标备份工具v1.1 mode con lines=10 cols=40 color F0 echo.---------------------------------------- echo. echo. 输入1为备份图标位置 echo. 输入2为还原图标位置 echo. 输入3或其他退出程序 echo. echo.---------------------------------------- echo. set /p open=请选择您的操作: if "%open%"=="1" goto backups_ico if "%open%"=="2" goto restore_ico if "%open%"=="3" goto getout goto getout :backups_ico cls Regedit /E %cd%\图标位置备份.reg HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Bags\1\Desktop echo. echo. echo. echo.桌面图标已备份到当前目录 echo.文件名为"图标位置备份.reg" goto getout :restore_ico cls start /w 图标位置备份.reg tskill explorer echo. echo. echo. echo. echo.桌面图标已从当前目录还原 goto getout :getout if "%open%"=="1" ping 127.0.1 -n "3">nul if "%open%"=="2" ping 127.0.1 -n "3">nul cls echo. echo. echo.---------------------------------------- echo. echo. 按任意键退出 echo. echo.---------------------------------------- echo. pause>nul exit ::桌面图标备份工具 ::版本1.1 ::作者 52P ```

Linux 跨服务器传输文件不需要密码

作者:じ☆ve宝贝

1. 生成安全信任关系证书(客户端) ``` [root@Client root]# ssh-keygen -b 1024 -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): Enter passphrase (empty for no passphrase): <-- 直接输入回车 Enter same passphrase again: <-- 直接输入回车 Your identification has been saved in /root/.ssh/id_rsa. Your public key has been saved in /root/.ssh/id_rsa.pub. The key fingerprint is: 49:9c:8a:8f:bc:19:5e:8c:c0:10:d3:15:60:a3:32:1c root@Client ``` 注意:在程序提示输入passphrase时直接输入回车,表示无证书密码。 上述命令将生成私钥证书id_rsa和公钥证书id_rsa.pub,存放在用户home目录的.ssh子目录中。 2. 将公钥证书id_rsa.pub复制到机器服务端的root家目录的.ssh子目录中,同时将文件名更换为authorized_keys。 ``` [root@Client root]# scp -P 22 .ssh/id_rsa.pub root@10.1.87.81:/root/.ssh/authorized_keys root@192.168.3.206's password: <-- 输入机器Server的root用户密码 id_rsa.pub 100% |**************************| 218 00:00 ``` 在执行上述命令时,两台机器的root用户之间还未建立安全信任关系,所以还需要输入机器Server的root用户密码。 经过以上2步,就在机器Client的root和机器Server的root之间建立安全信任关系。下面我们看看效果: ``` [root@Client root]# scp -p text root@10.1.87.81:/root text 100% |**************************| 19 00:00 ```

Base64 java.lang.NoSuchMethodError

作者:じ☆ve宝贝

``` java.lang.NoSuchMethodError: org.apache.commons.codec.binary.Base64.encodeBase64URLSafeString([B)Ljava/lang/String; ``` 1.引入commons-codec.jar 版本较低,删除了这部分就行了.jar 2.如果使用了QQ互联,Sdk4J.jar中包含了commons-codec.jar 版本较低,删除了这部分就行了

使用ToStringBuilder重写toString方法

作者:不要哭啦

Java中对象直接打印出来的是内存地址,需要重写toString() 过程太麻烦,因此可以使用commons-lang3中的ToStringBuilder直接将对象中的参数打印出来 ``` /* * 投中信息 * Copyright 2017 (C) All Rights Reserved. */ package cn.studyjava; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; import cn.studyjava.mybatis.entity.User; /** * <p> * Description: * </p> * * @author: zsljava * @version 1.0.0 * <p> * History: * ----------------------------------------------- * @Date: 2017年5月18日 下午2:26:13 * @author: zsljava * @version 1.0.0 * @OP: Create * ----------------------------------------------- * </p> * * @since * @see */ public class Test { public static void main(String[] args) { User user = new User(); user.setName("John Doe"); user.setAge(33); System.out.println(user); System.out.println(ToStringBuilder.reflectionToString(user,ToStringStyle.NO_CLASS_NAME_STYLE)); } } ``` 结果: ``` cn.studyjava.mybatis.entity.User@52e922 [name=John Doe,age=33] ``` ToStringStyle风格展示: **DEFAULT_STYLE**:User@182f0db[name=John Doe,age=33] **MULTI_LINE_STYLE**: User@182f0db[ name=John Doe age=33 smoker=false ] **NO_FIELD_NAMES_STYLE**:User@182f0db[John Doe,33 ] **SHORT_PREFIX_STYLE**:User[name=John Doe,age=33] **SIMPLE_STYLE**:John Doe,33 **NO_CLASS_NAME_STYLE**:[name=John Doe,age=33] **JSON_STYLE**:{"name": "John Doe", "age": 33}

天天用Spring MVC,了解过它的底层源码吗?

作者:微信小助手

<p style="white-space: normal;text-align: left;" data-mpa-powered-by="yiban.io"><img class="" data-ratio="0.6666666666666666" data-type="png" data-w="127" src="/upload/4c8b91599182ea5ba1ead110e9271956.png" style="height: 41px;vertical-align: bottom;width: 76px;"></p> <p style="white-space: normal;color: rgb(153, 80, 51);line-height: normal;"><span style="font-size: 15px;letter-spacing: 1px;">还没关注?伸出中指点这里!</span><br></p> <p style="white-space: normal;color: rgb(153, 80, 51);line-height: normal;"><br></p> <section class="KolEditor" data-tools-id="85858" style="white-space: normal;"> <section class="Powered-by-KolEditor V5" powered-by="KolEditor.us"> <section class=""> <section class="" style="margin-bottom: 5px;height: 5px;background-color: rgb(154, 157, 170);"></section> <section class="" style="margin-bottom: 5px;height: 5px;background-color: rgb(154, 157, 170);"></section> <section class="" style="margin-bottom: 5px;height: 5px;background-color: rgb(154, 157, 170);"></section> <section class="" style="margin-bottom: 5px;height: 5px;background-color: rgb(154, 157, 170);"></section> <section class="" style="margin-bottom: 5px;height: 5px;background-color: rgb(154, 157, 170);"></section> <section class="" style="margin-bottom: 5px;height: 5px;background-color: rgb(154, 157, 170);"></section> <section class="" style="margin-top: -40px;margin-right: 1.5em;margin-left: 1.5em;padding: 10px;background-color: rgb(226, 230, 0);"> <section class="Powered-by-KolEditor V5" powered-by="KolEditor.us"> <section class=""> <section class="" style="text-align: center;color: rgb(255, 255, 255);"> <section> <span style="color: rgb(0, 0, 0);font-size: 15px;">聊技术、论职场!</span> </section> <section> <span style="color: rgb(0, 0, 0);"><span style="font-size: 15px;">为IT人打造一个“有温度”的</span><strong style="font-size: 15px;"><span style="color: rgb(201, 56, 28);">狸猫技术窝</span></strong></span> </section> </section> </section> </section> </section> </section> </section> </section> <p style="white-space: normal;text-align: right;line-height: normal;"><span style="color: rgb(204, 204, 204);font-size: 10px;">来源:http://yg1.top/8rTVMo</span><span style="font-size: 14px;color: rgb(204, 204, 204);"><br></span></p> <section class="KolEditor" style="white-space: normal;"> <section style="margin-right: auto;margin-left: auto;padding: 20px;background-image: url(https://mmbiz.qpic.cn/mmbiz_png/vnOqylzBGCRNRFasUZTdSrnKiasPJRbicaSnStfclB7YtR607AAtLXNU1LPQ0PJfCcZyXPxLGUz8sYIbNfYszbjg/640?wx_fmt=png);background-size: 100%;background-position: left top;background-repeat: repeat;"> <section style="padding: 5px;"> <section class="KolEditor" data-tools-id="93344" style="text-align: left;"> <section style="margin-top: 10px;margin-bottom: 10px;display: flex;justify-content: flex-start;align-items: flex-end;"> <section style="padding: 2px 10px;border-bottom: 1px solid rgb(0, 0, 0);"> <p style="font-size: 15px;text-align: center;"><strong style="font-size: 17px;text-align: justify;">目录:</strong><br></p> </section> </section> </section> <p style="white-space: normal;line-height: 2em;"><span style="font-size: 14px;">一、Spring MVC请求处理流程</span></p> <p style="white-space: normal;line-height: 2em;"><span style="font-size: 14px;">二、Spring MVC的工作机制</span></p> <p style="white-space: normal;line-height: 2em;"><span style="font-size: 14px;">三、Spring MVC核心源码分析</span></p> <p style="white-space: normal;line-height: 2em;"><span style="font-size: 14px;">四、Spring MVC的优化</span></p> <p style="white-space: normal;"><br></p> <p style="white-space: normal;line-height: 2em;"><br></p> <section class="KolEditor" data-tools-id="93344" style="white-space: normal;text-align: left;"> <section style="margin-top: 10px;margin-bottom: 10px;display: flex;justify-content: flex-start;align-items: flex-end;"> <section style="padding: 2px 10px;border-bottom: 1px solid rgb(0, 0, 0);"> <h1 style="white-space: normal;line-height: 2em;"><strong>一、Spring MVC请求处理流程</strong></h1> </section> <section style="width: 32px;flex-shrink: 0;"> <img class="" data-ratio="0.6666666666666666" data-type="png" data-w="30" src="/upload/524ef0d8d30cff0cd3a6c5ade18e1ec9.png" style="vertical-align: bottom;width:auto !important;max-width:100% !important;height:auto !important;"> </section> </section> </section> <p style="line-height: 2em;"><br></p> <p style="white-space: normal;line-height: 2em;">引用spring in action上的一张图来说明了springmvc的核心组件和请求处理流程:</p> <p style="margin: 10px auto;white-space: normal;color: rgb(0, 0, 0);font-family: verdana, ms song, 宋体, Arial, 微软雅黑, Helvetica, sans-serif;font-size: 12px;text-align: left;background-color: rgb(255, 255, 255);">         <img class="" data-ratio="0.6666666666666666" data-type="jpeg" data-w="533" src="/upload/b12a69ab58d123b89155f7b6853b93b7.jpg" style="max-border-width: 0px;border-style: initial;border-color: initial;width:auto !important;max-width:100% !important;height:auto !important;"></p> <ol class=" list-paddingleft-2" style=""> <li><p style="line-height: 2em;text-align: left;">DispatcherServlet是springmvc中的前端控制器(front controller),负责接收request并将request转发给对应的处理组件.</p><p style="line-height: 2em;"><br></p></li> <li><p style="line-height: 2em;text-align: left;">HanlerMapping是springmvc中完成url到controller映射的组件.DispatcherServlet接收request,然后从HandlerMapping查找处理request的controller.</p><p style="line-height: 2em;"><br></p></li> <li><p style="line-height: 2em;text-align: left;">Controller处理request,并返回ModelAndView对象,Controller是springmvc中负责处理request的组件(类似于struts2中的Action),ModelAndView是封装结果视图的组件.</p><p style="line-height: 2em;"><br></p></li> <li><p style="line-height: 2em;text-align: left;">④ ⑤ ⑥:视图解析器解析ModelAndView对象并返回对应的视图给客户端.</p></li> </ol> <p style="white-space: normal;line-height: 2em;"><br></p> <p style="white-space: normal;line-height: 2em;"><br></p> <p style="white-space: normal;line-height: 2em;"><br></p> <section class="KolEditor" data-tools-id="93344" style="white-space: normal;"> <section style="margin-top: 10px;margin-bottom: 10px;display: flex;justify-content: flex-start;align-items: flex-end;"> <section style="padding: 2px 10px;border-bottom: 1px solid rgb(0, 0, 0);"> <h1 style="white-space: normal;line-height: 2em;"><strong>二、Spring MVC的工作机制</strong></h1> </section> <section style="width: 32px;flex-shrink: 0;"> <img class="" data-ratio="0.6666666666666666" data-type="png" data-w="30" src="/upload/524ef0d8d30cff0cd3a6c5ade18e1ec9.png" style="vertical-align: bottom;width:auto !important;max-width:100% !important;height:auto !important;"> </section> </section> </section> <p><br></p> <p style="white-space: normal;">在容器初始化时会建立所有url和controller的对应关系,保存到Map <url,controller> 中. </url,controller></p> <p style="white-space: normal;line-height: 2em;"><br></p> <p style="white-space: normal;line-height: 2em;"> <url,controller> tomcat启动时会通知spring初始化容器(加载bean的定义信息和初始化所有单例bean). </url,controller></p> <p style="white-space: normal;line-height: 2em;"><br></p> <p style="white-space: normal;line-height: 2em;"> <url,controller> 然后springmvc会遍历容器中的bean,获取每一个controller中的所有方法访问的url,然后将url和controller保存到一个Map中; </url,controller></p> <p style="white-space: normal;line-height: 2em;"><br></p> <p style="white-space: normal;line-height: 2em;">这样,就可以根据request快速定位到controller,因为最终处理request的是controller中的方法,Map中只保留了url和controller中的对应关系,所以要根据request的url进一步确认controller中的method。</p> <p style="white-space: normal;line-height: 2em;"><br></p> <p style="white-space: normal;line-height: 2em;">这一步工作的原理就是拼接controller的url(controller上@RequestMapping的值)和方法的url(method上@RequestMapping的值),与request的url进行匹配,找到匹配的那个方法;</p> <p style="white-space: normal;line-height: 2em;">  </p> <p style="white-space: normal;line-height: 2em;">确定处理请求的method后,接下来的任务就是参数绑定,把request中参数绑定到方法的形式参数上</p> <p style="white-space: normal;line-height: 2em;"><br></p> <p style="white-space: normal;line-height: 2em;">这一步是整个请求处理过程中最复杂的一个步骤。springmvc提供了两种request参数与方法形参的绑定方法:</p> <p style="white-space: normal;line-height: 2em;"><br></p> <ol class=" list-paddingleft-2" style=""> <li><p style="line-height: 2em;">通过注解进行绑定,@RequestParam</p></li> <li><p style="line-height: 2em;">通过参数名称进行绑定.</p></li> </ol> <p style="white-space: normal;line-height: 2em;"><br>使用注解进行绑定,我们只要在方法参数前面声明@RequestParam("a"),就可以将request中参数a的值绑定到方法的该参数上.</p> <p style="white-space: normal;line-height: 2em;"><br></p> <p style="white-space: normal;line-height: 2em;">使用参数名称进行绑定的前提是必须要获取方法中参数的名称,Java反射只提供了获取方法的参数的类型,并没有提供获取参数名称的方法.</p> <p style="white-space: normal;line-height: 2em;"><br></p> <p style="white-space: normal;line-height: 2em;">Spring MVC解决这个问题的方法是用asm框架读取字节码文件,来获取方法的参数名称。asm框架是一个字节码操作框架。</p> <p style="white-space: normal;line-height: 2em;"><br></p> <p style="white-space: normal;line-height: 2em;">个人建议,使用注解来完成参数绑定,这样就可以省去asm框架的读取字节码的操作.</p> <p style="white-space: normal;line-height: 2em;"><br></p> <p style="white-space: normal;line-height: 2em;"><br></p> <section class="KolEditor" data-tools-id="93344" style="white-space: normal;"> <section style="margin-top: 10px;margin-bottom: 10px;display: flex;justify-content: flex-start;align-items: flex-end;"> <section style="padding: 2px 10px;border-bottom: 1px solid rgb(0, 0, 0);"> <h1 style="white-space: normal;line-height: 2em;"><strong>三、Spring MVC核心源码分析</strong></h1> </section> <section style="width: 32px;flex-shrink: 0;"> <img class="" data-ratio="0.6666666666666666" data-type="png" data-w="30" src="/upload/524ef0d8d30cff0cd3a6c5ade18e1ec9.png" style="vertical-align: bottom;width:auto !important;max-width:100% !important;height:auto !important;"> </section> </section> </section> <p><br></p> <p>我们根据工作机制中三部分来分析 Spring MVC 的源代码.<br></p> <p style="white-space: normal;line-height: 2em;"><br></p> <ol class=" list-paddingleft-2" style=""> <li><p style="line-height: 2em;">ApplicationContext初始化时建立所有url和controller类的对应关系(用Map保存);</p><p style="line-height: 2em;"><br></p></li> <li><p style="line-height: 2em;">根据请求url找到对应的controller,并从controller中找到处理请求的方法;</p><p style="line-height: 2em;"><br></p></li> <li><p style="line-height: 2em;">request参数绑定到方法的形参,执行方法处理请求,并返回结果视图.</p></li> </ol> <h3 style="white-space: normal;line-height: 2em;"><br></h3> <h3 style="white-space: normal;line-height: 2em;"><strong><span style="color: rgb(57, 137, 31);">第一步、建立Map</span></strong> <urls,controller> <strong><span style="color: rgb(57, 137, 31);">的关系</span></strong> </urls,controller></h3> <p style="white-space: normal;text-align: left;line-height: 2em;">首先看第一个步骤,也就是建立Map <url,controller> 关系的部分. </url,controller>第一部分的入口类为ApplicationObjectSupport的setApplicationContext方法.</p> <p style="white-space: normal;text-align: left;line-height: 2em;"><br></p> <p style="white-space: normal;text-align: left;line-height: 2em;">setApplicationContext方法中核心部分就是初始化容器initApplicationContext(context),子类AbstractDetectingUrlHandlerMapping实现了该方法,所以我们直接看子类中的初始化容器方法.</p> <p style="white-space: normal;"><br></p> <section data-mpa-preserve-tpl-color="t" data-mpa-template="t" class="mpa-template" mpa-preserve="t" mpa-from-tpl="t" style="white-space: normal;"> <pre style="background-image: none;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;"><code class="hljs-default" style="margin-right: 0.15em;margin-left: 0.15em;padding: 6px;border-radius: 4px;font-size: 0.85em;background: rgb(40, 44, 52);color: rgb(171, 178, 191);display: block;overflow-x: auto;white-space: nowrap;"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 39px;">public</span>&nbsp;<span class="hljs-default-built_in" style="color: rgb(230, 192, 123);background: rgba(0, 0, 0, 0);display: inline;width: 26px;">void</span>&nbsp;initApplicationContext() throws ApplicationContextException {<br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 33px;">&nbsp; super</span>.initApplicationContext();<br mpa-from-tpl="t">&nbsp; detectHandlers();<br mpa-from-tpl="t">}<br><br mpa-from-tpl="t"><span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 423px;font-style: italic;">/**<br mpa-from-tpl="t">* 建立当前ApplicationContext中的所有controller和url的对应关系<br mpa-from-tpl="t">*/</span><br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 60px;">protected</span>&nbsp;<span class="hljs-default-built_in" style="color: rgb(230, 192, 123);background: rgba(0, 0, 0, 0);display: inline;width: 27px;">void</span>&nbsp;detectHandlers() throws BeansException {<br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 13px;">&nbsp; if</span>&nbsp;(logger.isDebugEnabled()) {<br mpa-from-tpl="t">&nbsp; &nbsp; logger.debug(<span class="hljs-default-string" style="color: rgb(152, 195, 121);background: rgba(0, 0, 0, 0);display: inline;width: 336px;">"Looking for URL mappings in application context: "</span>&nbsp;+ getApplicationContext());<br mpa-from-tpl="t">&nbsp; }<br>&nbsp;&nbsp;<br mpa-from-tpl="t"><span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 288px;font-style: italic;">&nbsp; // 获取ApplicationContext容器中所有bean的Name</span><br mpa-from-tpl="t"><span class="hljs-default-built_in" style="color: rgb(230, 192, 123);background: rgba(0, 0, 0, 0);display: inline;width: 39px;">&nbsp; String</span>[] beanNames = (<span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 26px;">this</span>.detectHandlersInAncestorContexts ?<br mpa-from-tpl="t">&nbsp; BeanFactoryUtils.beanNamesForTypeIncludingAncestors(getApplicationContext(),&nbsp;<span class="hljs-default-built_in" style="color: rgb(230, 192, 123);background: rgba(0, 0, 0, 0);display: inline;width: 40px;">Object</span>.class) :<br mpa-from-tpl="t">&nbsp; getApplicationContext().getBeanNamesForType(<span class="hljs-default-built_in" style="color: rgb(230, 192, 123);background: rgba(0, 0, 0, 0);display: inline;width: 39px;">Object</span>.class));<br mpa-from-tpl="t"><br mpa-from-tpl="t"><span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 252px;font-style: italic;">&nbsp; // 遍历beanNames,并找到这些bean对应的url</span><br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 19px;">&nbsp; for</span>&nbsp;(<span class="hljs-default-built_in" style="color: rgb(230, 192, 123);background: rgba(0, 0, 0, 0);display: inline;width: 39px;">String</span>&nbsp;beanName : beanNames) {<br mpa-from-tpl="t"><span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 462px;font-style: italic;">&nbsp;&nbsp;<br>&nbsp; &nbsp; // 找bean上的所有url(controller上的url+方法上的url),该方法由对应的子类实现</span><br mpa-from-tpl="t"><span class="hljs-default-built_in" style="color: rgb(230, 192, 123);background: rgba(0, 0, 0, 0);display: inline;width: 40px;">&nbsp; &nbsp; String</span>[] urls = determineUrlsForHandler(beanName);<br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 13px;">&nbsp; &nbsp; if</span>&nbsp;(!ObjectUtils.isEmpty(urls)) {<br mpa-from-tpl="t"><span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 666px;font-style: italic;">&nbsp; &nbsp; &nbsp; // 保存urls和beanName的对应关系,put it to Map <urls,beanname> ,该方法在父类AbstractUrlHandlerMapping中实现 </urls,beanname></span><br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; registerHandler(urls, beanName);<br mpa-from-tpl="t">&nbsp; &nbsp; }<br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 26px;">&nbsp; &nbsp; else</span>&nbsp;{<br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 14px;">&nbsp; &nbsp; &nbsp; if</span>&nbsp;(logger.isDebugEnabled()) {<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; &nbsp; logger.debug(<span class="hljs-default-string" style="color: rgb(152, 195, 121);background: rgba(0, 0, 0, 0);display: inline;width: 145px;">"Rejected bean name '"</span>&nbsp;+ beanName +&nbsp;<span class="hljs-default-string" style="color: rgb(152, 195, 121);background: rgba(0, 0, 0, 0);display: inline;width: 185px;">"': no URL paths identified"</span>);<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; }<br mpa-from-tpl="t">&nbsp; &nbsp; }<br mpa-from-tpl="t">&nbsp; }<br mpa-from-tpl="t">}<br><br mpa-from-tpl="t"><span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 392px;font-style: italic;">/** 获取controller中所有方法的url,由子类实现,典型的模板模式 **/</span><br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 59px;">protected</span>&nbsp;<span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 53px;">abstract</span>&nbsp;<span class="hljs-default-built_in" style="color: rgb(230, 192, 123);background: rgba(0, 0, 0, 0);display: inline;width: 40px;">String</span>[] determineUrlsForHandler(<span class="hljs-default-built_in" style="color: rgb(230, 192, 123);background: rgba(0, 0, 0, 0);display: inline;width: 39px;">String</span>&nbsp;beanName);</code></pre> </section> <p style="white-space: normal;"><br></p> <p style="white-space: normal;text-align: left;line-height: 2em;">determineUrlsForHandler(String beanName)方法的作用是获取每个controller中的url,不同的子类有不同的实现,这是一个典型的模板设计模式.</p> <p style="white-space: normal;text-align: left;line-height: 2em;"><br></p> <p style="white-space: normal;text-align: left;line-height: 2em;">因为开发中用的最多的就是用注解来配置controller中的url。DefaultAnnotationHandlerMapping是AbstractDetectingUrlHandlerMapping的子类,处理注解形式的url映射.</p> <p style="white-space: normal;text-align: left;line-height: 2em;"><br></p> <p style="white-space: normal;text-align: left;line-height: 2em;">所以我们这里以DefaultAnnotationHandlerMapping来进行分析.我们看DefaultAnnotationHandlerMapping是如何查beanName上所有映射的url.</p> <p style="white-space: normal;"><br></p> <section data-mpa-preserve-tpl-color="t" data-mpa-template="t" class="mpa-template" mpa-preserve="t" mpa-from-tpl="t" style="white-space: normal;"> <pre style="background-image: none;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;"><code class="hljs-default" style="margin-right: 0.15em;margin-left: 0.15em;padding: 6px;border-radius: 4px;font-size: 0.85em;background: rgb(40, 44, 52);color: rgb(171, 178, 191);display: block;overflow-x: auto;white-space: nowrap;"><span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 201px;font-style: italic;">/**<br mpa-from-tpl="t">* 获取controller中所有的url<br mpa-from-tpl="t">*/</span><br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 59px;">protected</span>&nbsp;<span class="hljs-default-built_in" style="color: rgb(230, 192, 123);background: rgba(0, 0, 0, 0);display: inline;width: 39px;">String</span>[] determineUrlsForHandler(<span class="hljs-default-built_in" style="color: rgb(230, 192, 123);background: rgba(0, 0, 0, 0);display: inline;width: 40px;">String</span>&nbsp;beanName) {<br mpa-from-tpl="t"><span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 193px;font-style: italic;">&nbsp; // 获取ApplicationContext容器</span><br mpa-from-tpl="t">&nbsp; ApplicationContext context = getApplicationContext();<br>&nbsp;&nbsp;<br mpa-from-tpl="t"><span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 151px;font-style: italic;">&nbsp; //从容器中获取controller</span><br mpa-from-tpl="t">&nbsp; Class handlerType = context.getType(beanName);<br>&nbsp;&nbsp;<br mpa-from-tpl="t"><span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 257px;font-style: italic;">&nbsp; // 获取controller上的@RequestMapping注解</span><br mpa-from-tpl="t">&nbsp; RequestMapping mapping = context.findAnnotationOnBean(beanName, RequestMapping.class);<br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 13px;">&nbsp; if</span>&nbsp;(mapping !=&nbsp;<span class="hljs-default-literal" style="color: rgb(86, 182, 194);background: rgba(0, 0, 0, 0);display: inline;width: 26px;">null</span>) {&nbsp;<span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 134px;font-style: italic;">// controller上有注解</span><br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 26px;">&nbsp; &nbsp; this</span>.cachedMappings.put(handlerType, mapping);<br mpa-from-tpl="t"><span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 80px;font-style: italic;">&nbsp; &nbsp;&nbsp;<br>&nbsp; &nbsp; // 返回结果集</span><br mpa-from-tpl="t">&nbsp; &nbsp; Set&lt;<span class="hljs-default-built_in" style="color: rgb(230, 192, 123);background: rgba(0, 0, 0, 0);display: inline;width: 40px;">String</span>&gt; urls =&nbsp;<span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 20px;">new</span>&nbsp;LinkedHashSet&lt;<span class="hljs-default-built_in" style="color: rgb(230, 192, 123);background: rgba(0, 0, 0, 0);display: inline;width: 40px;">String</span>&gt;();<br mpa-from-tpl="t"><span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 142px;font-style: italic;">&nbsp; &nbsp;&nbsp;<br>&nbsp; &nbsp; // controller的映射url</span><br mpa-from-tpl="t"><span class="hljs-default-built_in" style="color: rgb(230, 192, 123);background: rgba(0, 0, 0, 0);display: inline;width: 40px;">&nbsp; &nbsp; String</span>[] typeLevelPatterns = mapping.value();<br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 13px;">&nbsp; &nbsp; if</span>&nbsp;(typeLevelPatterns.length &gt;&nbsp;<span class="hljs-default-number" style="color: rgb(209, 154, 102);background: rgba(0, 0, 0, 0);display: inline;width: 7px;">0</span>) {&nbsp;<span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 53px;font-style: italic;">// url&gt;0</span><br mpa-from-tpl="t"><span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 262px;font-style: italic;">&nbsp; &nbsp; &nbsp;&nbsp;<br>&nbsp; &nbsp; &nbsp; // 获取controller中所有方法及方法的映射url</span><br mpa-from-tpl="t"><span class="hljs-default-built_in" style="color: rgb(230, 192, 123);background: rgba(0, 0, 0, 0);display: inline;width: 40px;">&nbsp; &nbsp; &nbsp; String</span>[] methodLevelPatterns = determineUrlsForHandlerMethods(handlerType,&nbsp;<span class="hljs-default-literal" style="color: rgb(86, 182, 194);background: rgba(0, 0, 0, 0);display: inline;width: 27px;">true</span>);<br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 20px;">&nbsp; &nbsp; &nbsp; for</span>&nbsp;(<span class="hljs-default-built_in" style="color: rgb(230, 192, 123);background: rgba(0, 0, 0, 0);display: inline;width: 40px;">String</span>&nbsp;typeLevelPattern : typeLevelPatterns) {<br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 13px;">&nbsp; &nbsp; &nbsp; &nbsp; if</span>&nbsp;(!typeLevelPattern.startsWith(<span class="hljs-default-string" style="color: rgb(152, 195, 121);background: rgba(0, 0, 0, 0);display: inline;width: 20px;">"/"</span>)) {<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; typeLevelPattern =&nbsp;<span class="hljs-default-string" style="color: rgb(152, 195, 121);background: rgba(0, 0, 0, 0);display: inline;width: 20px;">"/"</span>&nbsp;+ typeLevelPattern;<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; &nbsp; }<br mpa-from-tpl="t"><span class="hljs-default-built_in" style="color: rgb(230, 192, 123);background: rgba(0, 0, 0, 0);display: inline;width: 46px;">&nbsp; &nbsp; &nbsp; &nbsp; boolean</span>&nbsp;hasEmptyMethodLevelMappings =&nbsp;<span class="hljs-default-literal" style="color: rgb(86, 182, 194);background: rgba(0, 0, 0, 0);display: inline;width: 33px;">false</span>;<br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 20px;">&nbsp; &nbsp; &nbsp; &nbsp; for</span>&nbsp;(<span class="hljs-default-built_in" style="color: rgb(230, 192, 123);background: rgba(0, 0, 0, 0);display: inline;width: 39px;">String</span>&nbsp;methodLevelPattern : methodLevelPatterns) {<br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 13px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if</span>&nbsp;(methodLevelPattern ==&nbsp;<span class="hljs-default-literal" style="color: rgb(86, 182, 194);background: rgba(0, 0, 0, 0);display: inline;width: 26px;">null</span>) {<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hasEmptyMethodLevelMappings =&nbsp;<span class="hljs-default-literal" style="color: rgb(86, 182, 194);background: rgba(0, 0, 0, 0);display: inline;width: 27px;">true</span>;<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 27px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else</span>&nbsp;{<br mpa-from-tpl="t"><span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 228px;font-style: italic;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // controller的映射url+方法映射的url</span><br mpa-from-tpl="t"><span class="hljs-default-built_in" style="color: rgb(230, 192, 123);background: rgba(0, 0, 0, 0);display: inline;width: 39px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String</span>&nbsp;combinedPattern = getPathMatcher().combine(typeLevelPattern, methodLevelPattern);<br mpa-from-tpl="t"><span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 111px;font-style: italic;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // 保存到set集合中</span><br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; addUrlsForPath(urls, combinedPattern);<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; &nbsp; }<br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 13px;">&nbsp; &nbsp; &nbsp; &nbsp; if</span>&nbsp;(hasEmptyMethodLevelMappings || org.springframework.web.servlet.mvc.Controller.class.isAssignableFrom(handlerType)) {<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; addUrlsForPath(urls, typeLevelPattern);<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; &nbsp; }<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; }<br mpa-from-tpl="t"><span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 237px;font-style: italic;">&nbsp; &nbsp; &nbsp; // 以数组形式返回controller上的所有url</span><br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 40px;">&nbsp; &nbsp; &nbsp; return</span>&nbsp;StringUtils.toStringArray(urls);<br mpa-from-tpl="t">&nbsp; &nbsp; }<br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 26px;">&nbsp; &nbsp; else</span>&nbsp;{<br mpa-from-tpl="t"><span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 411px;font-style: italic;">&nbsp; &nbsp; &nbsp; // controller上的@RequestMapping映射url为空串,直接找方法的映射url</span><br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 40px;">&nbsp; &nbsp; &nbsp; return</span>&nbsp;determineUrlsForHandlerMethods(handlerType,&nbsp;<span class="hljs-default-literal" style="color: rgb(86, 182, 194);background: rgba(0, 0, 0, 0);display: inline;width: 33px;">false</span>);<br mpa-from-tpl="t">&nbsp; &nbsp; }<br mpa-from-tpl="t">&nbsp; }&nbsp;<span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 233px;font-style: italic;">// controller上没@RequestMapping注解</span><br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 26px;">&nbsp; else</span>&nbsp;<span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 13px;">if</span>&nbsp;(AnnotationUtils.findAnnotation(handlerType, Controller.class) !=&nbsp;<span class="hljs-default-literal" style="color: rgb(86, 182, 194);background: rgba(0, 0, 0, 0);display: inline;width: 26px;">null</span>) {<br mpa-from-tpl="t"><span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 214px;font-style: italic;">&nbsp; &nbsp; // 获取controller中方法上的映射url</span><br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 40px;">&nbsp; &nbsp; return</span>&nbsp;determineUrlsForHandlerMethods(handlerType,&nbsp;<span class="hljs-default-literal" style="color: rgb(86, 182, 194);background: rgba(0, 0, 0, 0);display: inline;width: 33px;">false</span>);<br mpa-from-tpl="t">&nbsp; }<br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 26px;">&nbsp; else</span>&nbsp;{<br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 40px;">&nbsp; &nbsp; return</span>&nbsp;<span class="hljs-default-literal" style="color: rgb(86, 182, 194);background: rgba(0, 0, 0, 0);display: inline;width: 27px;">null</span>;<br mpa-from-tpl="t">}<br mpa-from-tpl="t">}</code></pre> </section> <p style="white-space: normal;"><br></p> <p style="white-space: normal;line-height: 2em;">到这里HandlerMapping组件就已经建立所有url和controller的对应关系。</p> <p style="white-space: normal;"><br></p> <p style="white-space: normal;line-height: 2em;"><strong><span style="color: rgb(57, 137, 31);">第二步、根据访问url找到对应controller中处理请求的方法.</span></strong></p> <p style="white-space: normal;line-height: 2em;">  下面我们开始分析第二个步骤,第二个步骤是由请求触发的,所以入口为DispatcherServlet.</p> <p style="white-space: normal;line-height: 2em;"><br></p> <p style="white-space: normal;line-height: 2em;">DispatcherServlet的核心方法为doService(),doService()中的核心逻辑由doDispatch()实现,我们查看doDispatch()的源代码.</p> <p style="white-space: normal;"><br></p> <section data-mpa-preserve-tpl-color="t" data-mpa-template="t" class="mpa-template" mpa-preserve="t" mpa-from-tpl="t" style="white-space: normal;"> <pre style="background-image: none;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;"><code class="hljs-default" style="margin-right: 0.15em;margin-left: 0.15em;padding: 6px;border-radius: 4px;font-size: 0.85em;background: rgb(40, 44, 52);color: rgb(171, 178, 191);display: block;overflow-x: auto;white-space: nowrap;"><span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 203px;font-style: italic;">/** 中央控制器,控制请求的转发 **/</span><br mpa-from-tpl="t"><span class="hljs-default-function" style="background: rgba(0, 0, 0, 0);display: inline;width: 666px;"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 59px;">protected</span>&nbsp;<span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 26px;">void</span>&nbsp;<span class="hljs-default-title" style="color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 66px;">doDispatch</span>(<span class="hljs-default-params" style="background: rgba(0, 0, 0, 0);display: inline;width: 370px;">HttpServletRequest request, HttpServletResponse response</span>) throws Exception&nbsp;</span>{<br mpa-from-tpl="t">&nbsp; HttpServletRequest processedRequest = request;<br mpa-from-tpl="t">&nbsp; HandlerExecutionChain mappedHandler =&nbsp;<span class="hljs-default-literal" style="color: rgb(86, 182, 194);background: rgba(0, 0, 0, 0);display: inline;width: 27px;">null</span>;<br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 19px;">&nbsp; int</span>&nbsp;interceptorIndex =&nbsp;<span class="hljs-default-number" style="color: rgb(209, 154, 102);background: rgba(0, 0, 0, 0);display: inline;width: 14px;">-1</span>;<br mpa-from-tpl="t"><br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 19px;">&nbsp; try</span>&nbsp;{<br mpa-from-tpl="t">&nbsp; &nbsp; ModelAndView mv;<br mpa-from-tpl="t">&nbsp; &nbsp; boolean errorView =&nbsp;<span class="hljs-default-literal" style="color: rgb(86, 182, 194);background: rgba(0, 0, 0, 0);display: inline;width: 33px;">false</span>;<br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 20px;">&nbsp; &nbsp; try</span>&nbsp;{<br mpa-from-tpl="t"><span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 177px;font-style: italic;">&nbsp; &nbsp; &nbsp; // 1.检查是否是文件上传的请求</span><br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; processedRequest = checkMultipart(request);<br mpa-from-tpl="t"><br mpa-from-tpl="t"><span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 1254px;font-style: italic;">&nbsp; &nbsp; &nbsp; // 2.取得处理当前请求的controller,这里也称为hanlder,处理器,第一个步骤的意义就在这里体现了.这里并不是直接返回controller,而是返回的HandlerExecutionChain请求处理器链对象,该对象封装了handler和interceptors.</span><br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; mappedHandler = getHandler(processedRequest,&nbsp;<span class="hljs-default-literal" style="color: rgb(86, 182, 194);background: rgba(0, 0, 0, 0);display: inline;width: 33px;">false</span>);<br mpa-from-tpl="t"><span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 176px;font-style: italic;">&nbsp; &nbsp; &nbsp; // 如果handler为空,则返回404</span><br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 14px;">&nbsp; &nbsp; &nbsp; if</span>&nbsp;(mappedHandler ==&nbsp;<span class="hljs-default-literal" style="color: rgb(86, 182, 194);background: rgba(0, 0, 0, 0);display: inline;width: 26px;">null</span>&nbsp;|| mappedHandler.getHandler() ==&nbsp;<span class="hljs-default-literal" style="color: rgb(86, 182, 194);background: rgba(0, 0, 0, 0);display: inline;width: 26px;">null</span>) {<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; &nbsp; noHandlerFound(processedRequest, response);<br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 39px;">&nbsp; &nbsp; &nbsp; &nbsp; return</span>;<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; }<br mpa-from-tpl="t"><span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 317px;font-style: italic;">&nbsp; &nbsp; &nbsp; //3. 获取处理request的处理器适配器handler adapter</span><br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());<br mpa-from-tpl="t"><span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 179px;font-style: italic;">&nbsp; &nbsp; &nbsp; // 处理 last-modified 请求头</span><br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; String method = request.getMethod();<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; boolean isGet =&nbsp;<span class="hljs-default-string" style="color: rgb(152, 195, 121);background: rgba(0, 0, 0, 0);display: inline;width: 33px;">"GET"</span>.<span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 39px;">equals</span>(method);<br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 14px;">&nbsp; &nbsp; &nbsp; if</span>&nbsp;(isGet ||&nbsp;<span class="hljs-default-string" style="color: rgb(152, 195, 121);background: rgba(0, 0, 0, 0);display: inline;width: 40px;">"HEAD"</span>.<span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 40px;">equals</span>(method)) {<br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 26px;">&nbsp; &nbsp; &nbsp; &nbsp; long</span>&nbsp;lastModified = ha.getLastModified(request, mappedHandler.getHandler());<br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 13px;">&nbsp; &nbsp; &nbsp; &nbsp; if</span>&nbsp;(logger.isDebugEnabled()) {<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String requestUri = urlPathHelper.getRequestUri(request);<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; logger.debug(<span class="hljs-default-string" style="color: rgb(152, 195, 121);background: rgba(0, 0, 0, 0);display: inline;width: 178px;">"Last-Modified value for ["</span>&nbsp;+ requestUri +&nbsp;<span class="hljs-default-string" style="color: rgb(152, 195, 121);background: rgba(0, 0, 0, 0);display: inline;width: 52px;">"] is: "</span>&nbsp;+ lastModified);<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; &nbsp; }<br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 13px;">&nbsp; &nbsp; &nbsp; &nbsp; if</span>&nbsp;(<span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 20px;">new</span>&nbsp;ServletWebRequest(request, response).checkNotModified(lastModified) &amp;&amp; isGet) {<br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 40px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return</span>;<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; &nbsp; }<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; }<br mpa-from-tpl="t"><br mpa-from-tpl="t"><span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 141px;font-style: italic;">&nbsp; &nbsp; &nbsp; // 4.拦截器的预处理方法</span><br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; HandlerInterceptor[] interceptors = mappedHandler.getInterceptors();<br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 14px;">&nbsp; &nbsp; &nbsp; if</span>&nbsp;(interceptors !=&nbsp;<span class="hljs-default-literal" style="color: rgb(86, 182, 194);background: rgba(0, 0, 0, 0);display: inline;width: 27px;">null</span>) {<br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 20px;">&nbsp; &nbsp; &nbsp; &nbsp; for</span>&nbsp;(<span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 20px;">int</span>&nbsp;i =&nbsp;<span class="hljs-default-number" style="color: rgb(209, 154, 102);background: rgba(0, 0, 0, 0);display: inline;width: 7px;">0</span>; i &lt; interceptors.length; i++) {<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; HandlerInterceptor interceptor = interceptors[i];<br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 13px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if</span>&nbsp;(!interceptor.preHandle(processedRequest, response, mappedHandler.getHandler())) {<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response,&nbsp;<span class="hljs-default-literal" style="color: rgb(86, 182, 194);background: rgba(0, 0, 0, 0);display: inline;width: 26px;">null</span>);<br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 39px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return</span>;<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; interceptorIndex = i;<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; &nbsp; }<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; }<br mpa-from-tpl="t"><br mpa-from-tpl="t"><span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 256px;font-style: italic;">&nbsp; &nbsp; &nbsp; // 5.实际的处理器处理请求,返回结果视图对象</span><br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; mv = ha.handle(processedRequest, response, mappedHandler.getHandler());<br mpa-from-tpl="t"><br mpa-from-tpl="t"><span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 128px;font-style: italic;">&nbsp; &nbsp; &nbsp; // 结果视图对象的处理</span><br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 14px;">&nbsp; &nbsp; &nbsp; if</span>&nbsp;(mv !=&nbsp;<span class="hljs-default-literal" style="color: rgb(86, 182, 194);background: rgba(0, 0, 0, 0);display: inline;width: 27px;">null</span>&nbsp;&amp;&amp; !mv.hasView()) {<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; &nbsp; mv.setViewName(getDefaultViewName(request));<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; }<br mpa-from-tpl="t"><br mpa-from-tpl="t"><span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 141px;font-style: italic;">&nbsp; &nbsp; &nbsp; // 6.拦截器的后处理方法</span><br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 14px;">&nbsp; &nbsp; &nbsp; if</span>&nbsp;(interceptors !=&nbsp;<span class="hljs-default-literal" style="color: rgb(86, 182, 194);background: rgba(0, 0, 0, 0);display: inline;width: 27px;">null</span>) {<br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 20px;">&nbsp; &nbsp; &nbsp; &nbsp; for</span>&nbsp;(<span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 20px;">int</span>&nbsp;i = interceptors.length -&nbsp;<span class="hljs-default-number" style="color: rgb(209, 154, 102);background: rgba(0, 0, 0, 0);display: inline;width: 6px;">1</span>; i &gt;=&nbsp;<span class="hljs-default-number" style="color: rgb(209, 154, 102);background: rgba(0, 0, 0, 0);display: inline;width: 7px;">0</span>; i--) {<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; HandlerInterceptor interceptor = interceptors[i];<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; interceptor.postHandle(processedRequest, response, mappedHandler.getHandler(), mv);<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; &nbsp; }<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; }<br mpa-from-tpl="t">&nbsp; &nbsp; }<br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 33px;">&nbsp; &nbsp; catch</span>&nbsp;(ModelAndViewDefiningException ex) {<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; logger.debug(<span class="hljs-default-string" style="color: rgb(152, 195, 121);background: rgba(0, 0, 0, 0);display: inline;width: 284px;">"ModelAndViewDefiningException encountered"</span>, ex);<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; mv = ex.getModelAndView();<br mpa-from-tpl="t">&nbsp; &nbsp; }<br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 33px;">&nbsp; &nbsp; catch</span>&nbsp;(Exception ex) {<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; Object handler = (mappedHandler !=&nbsp;<span class="hljs-default-literal" style="color: rgb(86, 182, 194);background: rgba(0, 0, 0, 0);display: inline;width: 27px;">null</span>&nbsp;? mappedHandler.getHandler() :&nbsp;<span class="hljs-default-literal" style="color: rgb(86, 182, 194);background: rgba(0, 0, 0, 0);display: inline;width: 26px;">null</span>);<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; mv = processHandlerException(processedRequest, response, handler, ex);<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; errorView = (mv !=&nbsp;<span class="hljs-default-literal" style="color: rgb(86, 182, 194);background: rgba(0, 0, 0, 0);display: inline;width: 26px;">null</span>);<br mpa-from-tpl="t">&nbsp; &nbsp; }<br mpa-from-tpl="t"><br mpa-from-tpl="t"><br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 13px;">&nbsp; &nbsp; if</span>&nbsp;(mv !=&nbsp;<span class="hljs-default-literal" style="color: rgb(86, 182, 194);background: rgba(0, 0, 0, 0);display: inline;width: 26px;">null</span>&nbsp;&amp;&amp; !mv.wasCleared()) {<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; render(mv, processedRequest, response);<br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 14px;">&nbsp; &nbsp; &nbsp; if</span>&nbsp;(errorView) {<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; &nbsp; WebUtils.clearErrorRequestAttributes(request);<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; }<br mpa-from-tpl="t">&nbsp; &nbsp; }<br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 26px;">&nbsp; &nbsp; else</span>&nbsp;{<br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 14px;">&nbsp; &nbsp; &nbsp; if</span>&nbsp;(logger.isDebugEnabled()) {<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; &nbsp; logger.debug(<span class="hljs-default-string" style="color: rgb(152, 195, 121);background: rgba(0, 0, 0, 0);display: inline;width: 402px;">"Null ModelAndView returned to DispatcherServlet with name '"</span>&nbsp;+ getServletName() +&nbsp;<span class="hljs-default-string" style="color: rgb(152, 195, 121);background: rgba(0, 0, 0, 0);display: inline;width: 362px;">"': assuming HandlerAdapter completed request handling"</span>);<br mpa-from-tpl="t">&nbsp; &nbsp; &nbsp; }<br mpa-from-tpl="t">&nbsp; &nbsp; }<br mpa-from-tpl="t"><br mpa-from-tpl="t"><span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 152px;font-style: italic;">&nbsp; &nbsp; // 请求成功响应之后的方法</span><br mpa-from-tpl="t">&nbsp; &nbsp; triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response,&nbsp;<span class="hljs-default-literal" style="color: rgb(86, 182, 194);background: rgba(0, 0, 0, 0);display: inline;width: 27px;">null</span>);<br mpa-from-tpl="t">&nbsp; }<br>}</code></pre> </section> <p style="white-space: normal;"><span class="cnblogs_code_copy" style="padding-right: 5px;line-height: 18px;"></span><br></p> <p style="white-space: normal;line-height: 2em;">第2步:getHandler(processedRequest)方法实际上就是从HandlerMapping中找到url和controller的对应关系.这也就是第一个步骤:建立Map <url,controller> 的意义. </url,controller></p> <p style="white-space: normal;line-height: 2em;"><br></p> <p style="white-space: normal;line-height: 2em;"> <url,controller> 我们知道,最终处理request的是controller中的方法,我们现在只是知道了controller,还要进一步确认controller中处理request的方法. </url,controller></p> <p style="white-space: normal;line-height: 2em;"><br></p> <p style="white-space: normal;line-height: 2em;"> <url,controller> 由于下面的步骤和第三个步骤关系更加紧密,直接转到第三个步骤. </url,controller></p> <p style="white-space: normal;"><br></p> <p style="white-space: normal;"><br></p> <h3 style="white-space: normal;line-height: 2em;"><span style="color: rgb(57, 137, 31);"><strong>第三步、反射调用处理请求的方法,返回结果视图</strong></span></h3> <p style="white-space: normal;line-height: 2em;">  上面的方法中,第2步其实就是从第一个步骤中的Map <urls,beanname> 中取得controller,然后经过拦截器的预处理方法,到最核心的部分--第5步调用controller的方法处理请求. </urls,beanname></p> <p style="white-space: normal;line-height: 2em;"><br></p> <p style="white-space: normal;line-height: 2em;"> <urls,beanname> 在第2步中我们可以知道处理request的controller,第5步就是要根据url确定controller中处理请求的方法,然后通过反射获取该方法上的注解和参数,解析方法和参数上的注解,最后反射调用方法获取ModelAndView结果视图。 </urls,beanname></p> <p style="white-space: normal;line-height: 2em;"><br></p> <p style="white-space: normal;line-height: 2em;"> <urls,beanname> 因为上面采用注解url形式说明的,所以我们这里继续以注解处理器适配器来说明. </urls,beanname></p> <p style="white-space: normal;line-height: 2em;"><br></p> <p style="white-space: normal;line-height: 2em;"> <urls,beanname> 第5步调用的就是AnnotationMethodHandlerAdapter的handle().handle()中的核心逻辑由invokeHandlerMethod(request, response, handler)实现。 </urls,beanname></p> <p style="white-space: normal;"><span class="cnblogs_code_copy" style="padding-right: 5px;line-height: 18px;"></span></p> <section data-mpa-preserve-tpl-color="t" data-mpa-template="t" class="mpa-template" mpa-preserve="t" mpa-from-tpl="t" style="white-space: normal;"> <pre style="background-image: none;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;"><code class="hljs-default" style="margin-right: 0.15em;margin-left: 0.15em;padding: 6px;border-radius: 4px;font-size: 0.85em;background: rgb(40, 44, 52);color: rgb(171, 178, 191);display: block;overflow-x: auto;white-space: nowrap;"><span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 275px;font-style: italic;">/** 获取处理请求的方法,执行并返回结果视图 **/</span><br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 59px;">protected</span>&nbsp;ModelAndView invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response,&nbsp;<span class="hljs-default-built_in" style="color: rgb(230, 192, 123);background: rgba(0, 0, 0, 0);display: inline;width: 40px;">Object</span>&nbsp;handler)<br mpa-from-tpl="t">&nbsp;throws Exception {<br mpa-from-tpl="t"><span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 117px;font-style: italic;">&nbsp; // 1.获取方法解析器</span><br mpa-from-tpl="t">&nbsp; ServletHandlerMethodResolver methodResolver = getMethodResolver(handler);<br mpa-from-tpl="t"><span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 291px;font-style: italic;">&nbsp; // 2.解析request中的url,获取处理request的方法</span><br mpa-from-tpl="t">&nbsp; Method handlerMethod = methodResolver.resolveHandlerMethod(request);<br mpa-from-tpl="t"><span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 93px;font-style: italic;">&nbsp; // 3.方法调用器</span><br mpa-from-tpl="t">&nbsp; ServletHandlerMethodInvoker methodInvoker =&nbsp;<span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 20px;">new</span>&nbsp;ServletHandlerMethodInvoker(methodResolver);<br mpa-from-tpl="t">&nbsp; ServletWebRequest webRequest =&nbsp;<span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 20px;">new</span>&nbsp;ServletWebRequest(request, response);<br mpa-from-tpl="t">&nbsp; ExtendedModelMap implicitModel =&nbsp;<span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 20px;">new</span>&nbsp;BindingAwareModelMap();<br mpa-from-tpl="t"><span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 81px;font-style: italic;">&nbsp; // 4.执行方法</span><br mpa-from-tpl="t"><span class="hljs-default-built_in" style="color: rgb(230, 192, 123);background: rgba(0, 0, 0, 0);display: inline;width: 39px;">&nbsp; Object</span>&nbsp;result = methodInvoker.invokeHandlerMethod(handlerMethod, handler, webRequest, implicitModel);<br mpa-from-tpl="t"><span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 105px;font-style: italic;">&nbsp; // 5.封装结果视图</span><br mpa-from-tpl="t">&nbsp; ModelAndView mav =<br mpa-from-tpl="t">&nbsp; methodInvoker.getModelAndView(handlerMethod, handler.getClass(), result, implicitModel, webRequest);<br mpa-from-tpl="t">&nbsp; methodInvoker.updateModelAttributes(handler, (mav !=&nbsp;<span class="hljs-default-literal" style="color: rgb(86, 182, 194);background: rgba(0, 0, 0, 0);display: inline;width: 27px;">null</span>&nbsp;? mav.getModel() :&nbsp;<span class="hljs-default-literal" style="color: rgb(86, 182, 194);background: rgba(0, 0, 0, 0);display: inline;width: 26px;">null</span>), implicitModel, webRequest);<br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 39px;">&nbsp; return</span>&nbsp;mav;<br mpa-from-tpl="t">}</code></pre> </section> <p style="white-space: normal;"><span class="cnblogs_code_copy" style="padding-right: 5px;line-height: 18px;"></span><br></p> <p style="white-space: normal;line-height: 2em;"><br></p> <p style="white-space: normal;line-height: 2em;">这一部分的核心就在2和4了.</p> <p style="white-space: normal;line-height: 2em;"><br></p> <p style="white-space: normal;line-height: 2em;">先看第2步,通过request找controller的处理方法.实际上就是拼接controller的url和方法的url,与request的url进行匹配,找到匹配的方法.</p> <p style="white-space: normal;"><br></p> <section data-mpa-preserve-tpl-color="t" data-mpa-template="t" class="mpa-template" mpa-preserve="t" mpa-from-tpl="t" style="white-space: normal;"> <pre style="background-image: none;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;"><code class="hljs-default" style="margin-right: 0.15em;margin-left: 0.15em;padding: 6px;border-radius: 4px;font-size: 0.85em;background: rgb(40, 44, 52);color: rgb(171, 178, 191);display: block;overflow-x: auto;white-space: nowrap;"><span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 204px;font-style: italic;">/** 根据url获取处理请求的方法 **/</span><br mpa-from-tpl="t"><span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 39px;">public</span>&nbsp;Method resolveHandlerMethod(HttpServletRequest request) throws ServletException {<br mpa-from-tpl="t"><span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 778px;font-style: italic;">&nbsp; // 如果请求url为,localhost:8080/springmvc/helloWorldController/say.action, 则lookupPath=helloWorldController/say.action</span><br mpa-from-tpl="t"><span class="hljs-default-built_in" style="color: rgb(230, 192, 123);background: rgba(0, 0, 0, 0);display: inline;width: 40px;">&nbsp; String</span>&nbsp;lookupPath = urlPathHelper.getLookupPathForRequest(request);<br mpa-from-tpl="t">&nbsp; Comparator&lt;<span class="hljs-default-built_in" style="color: rgb(230, 192, 123);background: rgba(0, 0, 0, 0);display: inline;width: 39px;">String</span>&gt; pathComparator = pathMatcher.getPatternComparator(lookupPath);<br mpa-from-tpl="t">&nbsp; Map <requestspecificmappinginfo, method=""> targetHandlerMethods =&nbsp; <span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 19px;">new</span>&nbsp;LinkedHashMap <requestspecificmappinginfo, method=""> (); <br mpa-from-tpl="t">&nbsp; Set&lt; <span class="hljs-default-built_in" style="color: rgb(230, 192, 123);background: rgba(0, 0, 0, 0);display: inline;width: 40px;">String</span>&gt; allowedMethods =&nbsp; <span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 20px;">new</span>&nbsp;LinkedHashSet&lt; <span class="hljs-default-built_in" style="color: rgb(230, 192, 123);background: rgba(0, 0, 0, 0);display: inline;width: 40px;">String</span>&gt;( <span class="hljs-default-number" style="color: rgb(209, 154, 102);background: rgba(0, 0, 0, 0);display: inline;width: 6px;">7</span>); <br mpa-from-tpl="t"> <span class="hljs-default-built_in" style="color: rgb(230, 192, 123);background: rgba(0, 0, 0, 0);display: inline;width: 40px;">&nbsp; String</span>&nbsp;resolvedMethodName =&nbsp; <span class="hljs-default-literal" style="color: rgb(86, 182, 194);background: rgba(0, 0, 0, 0);display: inline;width: 26px;">null</span>; <br mpa-from-tpl="t"> <span class="hljs-default-comment" style="color: rgb(92, 99, 112);background: rgba(0, 0, 0, 0);display: inline;width: 293px;font-style: italic;">&nbsp; // 遍历controller上的所有方法,获取url匹配的方法</span> <br mpa-from-tpl="t"> <span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 20px;">&nbsp; for</span>&nbsp;(Method handlerMethod : getHandlerMethods()) { <br mpa-from-tpl="t">&nbsp; &nbsp; RequestSpecificMappingInfo mappingInfo =&nbsp; <span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 20px;">new</span>&nbsp;RequestSpecificMappingInfo( <span class="hljs-default-keyword" style="color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 27px;">this</span>.mappings.get(handlerMethod)); <br mpa-from-tpl="t"> <span class="hljs-default-built_in" style="color: rgb(230, 192, 123);background: rgba(0, 0, 0, 0);display: inline;width: 47px;">&nbsp; &nbsp; boolean</span>&nbsp;match =&nbsp; <span class="hljs-default-literal" style="color: rgb(86