From 41d3f0e30b222b1ded93fce5548abdf020c848c1 Mon Sep 17 00:00:00 2001 From: skywalker Date: Fri, 25 Aug 2017 14:12:52 +0800 Subject: [PATCH 01/20] =?UTF-8?q?Spring=20AOP:=20aop=E5=88=87=E9=9D=A2?= =?UTF-8?q?=E6=8B=A6=E6=88=AA=E7=9A=84=E5=9D=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- note/images/cglib_invocation.png | Bin 0 -> 3062 bytes note/spring-aop.md | 58 +++++++++++++++++- pom.xml | 8 +++ src/main/java/aop/Bootstrap.java | 19 ++++++ src/main/java/aop/SimpleAopBean.java | 24 ++++++++ src/main/java/aop/SimpleChildAopBean.java | 12 ++++ .../java/aop/SimpleMethodInterceptor.java | 17 +++++ src/main/resources/config.xml | 21 ++----- 8 files changed, 142 insertions(+), 17 deletions(-) create mode 100644 note/images/cglib_invocation.png create mode 100644 src/main/java/aop/Bootstrap.java create mode 100644 src/main/java/aop/SimpleAopBean.java create mode 100644 src/main/java/aop/SimpleChildAopBean.java create mode 100644 src/main/java/aop/SimpleMethodInterceptor.java diff --git a/note/images/cglib_invocation.png b/note/images/cglib_invocation.png new file mode 100644 index 0000000000000000000000000000000000000000..6091a9886ed128561e3948e73b45c15b716f1acf GIT binary patch literal 3062 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 clazz) { ## 总结 -Spring对于AspectJ风格AOP的支持停留在外表(注解)上面,内部的实现仍然是自己的东西。 \ No newline at end of file +Spring对于AspectJ风格AOP的支持停留在外表(注解)上面,内部的实现仍然是自己的东西。 + +# 拾遗 + +## AOP切面的坑 + +1. 定义在private方法上的切面不会被执行,这个很容易理解,毕竟子类不能覆盖父类的私有方法。 +2. 同一个代理子类内部的方法相互调用不会再次执行切面。 + +这里以Cglib为例对第二点进行说明,cglib的相关核心组件可以参考前面CallbackFilter & Callback部分。对于配置了一个切面的典型场景,Spring内部的执行流程可总结如下图: + +![Cglib调用流程](images/cglib_invocation.png) + +核心便是对目标方法的调用上,这里由CglibMethodInvocation的invokeJoinpoint实现: + +```java +@Override +protected Object invokeJoinpoint() throws Throwable { + if (this.publicMethod) { + return this.methodProxy.invoke(this.target, this.arguments); + } else { + return super.invokeJoinpoint(); + } +} +``` + +如果是非public方法,那么Spring将使用反射的方法对其进行调用,因为反射将其可访问性设为true。MethodProxy是Cglib对方法代理的抽象,这里的关键是**方法调用的对象(目标)是我们的原生类对象,而不是Cglib代理子类的对象,这就从根本上决定了对同类方法的调用不会再次经过切面**。 + +### 总结 + +前面aop:aspectj-autoproxy-属性-expose-proxy一节提到了,Spring允许我们将代理子类暴露出来,可以进行如下配置: + +```xml + + + +``` + +当我们需要在一个被代理方法中调用同类的方法时(此方法也需要经过切面),可以这样调用: + +```java +public void testB() { + System.out.println("testB执行"); + ((SimpleAopBean) AopContext.currentProxy()).testC(); +} +``` + +这里其实是一个ThreadLocal,当Cglib代理子类创建调用链之间便会将代理类设置到其中,DynamicAdvisedInterceptor.intercept相关源码: + +```java +if (this.advised.exposeProxy) { + // Make invocation available if necessary. + oldProxy = AopContext.setCurrentProxy(proxy); + setProxyContext = true; +} +``` + diff --git a/pom.xml b/pom.xml index 26cdbbf..0cd09c9 100644 --- a/pom.xml +++ b/pom.xml @@ -87,6 +87,13 @@ mysql-connector-java 5.1.20 + + + cglib + cglib + 3.2.5 + + @@ -95,6 +102,7 @@ org.apache.maven.plugins maven-compiler-plugin + false 1.8 1.8 diff --git a/src/main/java/aop/Bootstrap.java b/src/main/java/aop/Bootstrap.java new file mode 100644 index 0000000..9bf64b0 --- /dev/null +++ b/src/main/java/aop/Bootstrap.java @@ -0,0 +1,19 @@ +package aop; + +import org.springframework.context.support.ClassPathXmlApplicationContext; + +/** + * AOP测试启动类. + * + * @author skywalker + */ +public class Bootstrap { + + public static void main(String[] args) { + ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("config.xml"); + SimpleAopBean bean = context.getBean(SimpleAopBean.class); + bean.testB(); + System.out.println(bean.getClass().getSimpleName()); + } + +} diff --git a/src/main/java/aop/SimpleAopBean.java b/src/main/java/aop/SimpleAopBean.java new file mode 100644 index 0000000..7c002a9 --- /dev/null +++ b/src/main/java/aop/SimpleAopBean.java @@ -0,0 +1,24 @@ +package aop; + +import org.springframework.aop.framework.AopContext; + +/** + * @author skywalker + */ +public class SimpleAopBean { + + public void boo() { + System.out.println("testA执行"); + testB(); + } + + public void testB() { + System.out.println("testB执行"); + ((SimpleAopBean) AopContext.currentProxy()).testC(); + } + + public void testC() { + System.out.println("testC执行"); + } + +} diff --git a/src/main/java/aop/SimpleChildAopBean.java b/src/main/java/aop/SimpleChildAopBean.java new file mode 100644 index 0000000..8b5edc9 --- /dev/null +++ b/src/main/java/aop/SimpleChildAopBean.java @@ -0,0 +1,12 @@ +package aop; + +/** + * @author skywalker + */ +public class SimpleChildAopBean extends SimpleAopBean { + + @Override + public void testC() { + System.out.println("child testC"); + } +} diff --git a/src/main/java/aop/SimpleMethodInterceptor.java b/src/main/java/aop/SimpleMethodInterceptor.java new file mode 100644 index 0000000..7c161a5 --- /dev/null +++ b/src/main/java/aop/SimpleMethodInterceptor.java @@ -0,0 +1,17 @@ +package aop; + +import org.aopalliance.intercept.MethodInterceptor; +import org.aopalliance.intercept.MethodInvocation; + +/** + * @author skywalker + */ +public class SimpleMethodInterceptor implements MethodInterceptor { + + @Override + public Object invoke(MethodInvocation invocation) throws Throwable { + System.out.println("SimpleMethodInterceptor被调用: " + invocation.getMethod().getName()); + return invocation.proceed(); + } + +} diff --git a/src/main/resources/config.xml b/src/main/resources/config.xml index edd0225..795107b 100644 --- a/src/main/resources/config.xml +++ b/src/main/resources/config.xml @@ -14,23 +14,12 @@ http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd"> - - - - - - - + - - - + - - - - - - + + + From 0bb13dfb927153a3e0d9ed197f4cde3a3a728a3a Mon Sep 17 00:00:00 2001 From: skywalker Date: Fri, 8 Sep 2017 22:03:56 +0800 Subject: [PATCH 02/20] =?UTF-8?q?pure=20parameter=20object=C2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- note/spring-mvc.md | 16 +++++++++- .../java/controller/SimpleController.java | 7 +++++ src/main/java/model/SimpleModel.java | 29 +++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 src/main/java/model/SimpleModel.java diff --git a/note/spring-mvc.md b/note/spring-mvc.md index eba87cc..f5ecb9d 100644 --- a/note/spring-mvc.md +++ b/note/spring-mvc.md @@ -1187,4 +1187,18 @@ HandlerMethodReturnValueHandler接口以及主要实现类如下: 从中也可以推测出我们可以把哪些类型的值(对象)直接"丢给"Spring。 -对于HandlerMethodArgumentResolver和HandlerMethodReturnValueHandler来说,HttpMessageConverter像是两者手中用来实现功能的武器。 \ No newline at end of file +对于HandlerMethodArgumentResolver和HandlerMethodReturnValueHandler来说,HttpMessageConverter像是两者手中用来实现功能的武器。 + +## "纯"对象参数接收 + +假设有如下这样的Controller: + +```java +@RequestMapping("/echoAgain") +public String echo(SimpleModel simpleModel, Model model) { + model.addAttribute("echo", "hello " + simpleModel.getName() + ", your age is " + simpleModel.getAge() + "."); + return "echo"; +} +``` + +经过测试可以发现,SimpleModel参数既可以接收get请求,也可以接收post请求。那么在这种情况下请求参数是被哪个参数解析器解析的呢,debug发现: ServletModelAttributeMethodProcessor \ No newline at end of file diff --git a/src/main/java/controller/SimpleController.java b/src/main/java/controller/SimpleController.java index b7cd6c3..cbf1cb6 100644 --- a/src/main/java/controller/SimpleController.java +++ b/src/main/java/controller/SimpleController.java @@ -1,5 +1,6 @@ package controller; +import model.SimpleModel; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; @@ -18,4 +19,10 @@ public String echo(String name, Model model) { return "echo"; } + @RequestMapping("/echoAgain") + public String echo(SimpleModel simpleModel, Model model) { + model.addAttribute("echo", "hello " + simpleModel.getName() + ", your age is " + simpleModel.getAge() + "."); + return "echo"; + } + } diff --git a/src/main/java/model/SimpleModel.java b/src/main/java/model/SimpleModel.java new file mode 100644 index 0000000..7e79b9b --- /dev/null +++ b/src/main/java/model/SimpleModel.java @@ -0,0 +1,29 @@ +package model; + +/** + * 简单的model. + * + * @author skywalker + */ +public class SimpleModel { + + private String name; + private Integer age; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getAge() { + return age; + } + + public void setAge(Integer age) { + this.age = age; + } + +} From bd56e4c5c10d0e7b43d4513ee382f91580254dac Mon Sep 17 00:00:00 2001 From: skywalker Date: Sat, 9 Sep 2017 09:36:14 +0800 Subject: [PATCH 03/20] @ModelAttribute --- .../ServletModelAttributeMethodProcessor.jpg | Bin 0 -> 40858 bytes note/spring-mvc.md | 51 +++- note/spring-mvc.uml | 281 +++++++++++++++++- .../java/controller/SimpleController.java | 4 +- src/main/java/model/SimpleModel.java | 8 + 5 files changed, 336 insertions(+), 8 deletions(-) create mode 100644 note/images/ServletModelAttributeMethodProcessor.jpg diff --git a/note/images/ServletModelAttributeMethodProcessor.jpg b/note/images/ServletModelAttributeMethodProcessor.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4b5f83ea6760e263e505707f5c019577679e829d GIT binary patch literal 40858 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 literal 0 HcmV?d00001 diff --git a/note/spring-mvc.md b/note/spring-mvc.md index f5ecb9d..bb56bab 100644 --- a/note/spring-mvc.md +++ b/note/spring-mvc.md @@ -1201,4 +1201,53 @@ public String echo(SimpleModel simpleModel, Model model) { } ``` -经过测试可以发现,SimpleModel参数既可以接收get请求,也可以接收post请求。那么在这种情况下请求参数是被哪个参数解析器解析的呢,debug发现: ServletModelAttributeMethodProcessor \ No newline at end of file +经过测试可以发现,SimpleModel参数既可以接收get请求,也可以接收post请求。那么在这种情况下请求参数是被哪个参数解析器解析的呢,debug发现: ServletModelAttributeMethodProcessor: + +![ServletModelAttributeMethodProcessor](images/ServletModelAttributeMethodProcessor.jpg) + +核心的supportsParameter方法由父类ModelAttributeMethodProcessor实现: + +```java +@Override +public boolean supportsParameter(MethodParameter parameter) { + return (parameter.hasParameterAnnotation(ModelAttribute.class) || + (this.annotationNotRequired && !BeanUtils.isSimpleProperty(parameter.getParameterType()))); +} +``` + +可以看出,这里支持带有ModelAttribute注解或者是非基本类型的参数解析,同时annotationNotRequired必须设为false,即ModelAttribute注解不必存在,这里是在ServletModelAttributeMethodProcessor的构造器中进行控制的, +RequestMappingHandlerAdapter.getDefaultArgumentResolvers部分源码: + +```java +resolvers.add(new ServletModelAttributeMethodProcessor(false)); +``` + +此类的作用是对@ModelAttribute注解标注的参数进行解析,假设我们将Controller方法改写成: + +```java +@RequestMapping("/echoAgain") +public String echo(@ModelAttribute SimpleModel simpleModel, Model model) { + model.addAttribute("echo", "hello " + simpleModel.getName() + ", your age is " + simpleModel.getAge() + "."); + System.out.println(model.asMap().get("simpleModel")); + return "echo"; +} +``` + +首先,Spring会首先反射生成一个SimpleModel对象,之后将从request中获取的参数尝试设置到SimpleModel对象中去,最后将此对象放置到Model中(本质上就是一个Map),key就是simpleModel.下面我们来看一下具体的解析过程,整个过程可以分为 +以下三部分: + +### 参数对象构造 + +因为SimpleModel是一个对象类型,所以要想将参数注入到其中,第一步必然是先创建一个对象,创建的入口位于ModelAttributeMethodProcessor的resolveArgument方法,相关源码: + +```java +//name在这里便是simpleModel +String name = ModelFactory.getNameForParameter(parameter); +Object attribute = (mavContainer.containsAttribute(name) ? mavContainer.getModel().get(name) : + createAttribute(name, parameter, binderFactory, webRequest));//反射实例化 +``` + +ModelAndViewContainer是个什么东西呢,从名字就可以看出就,它是Spring MVC里两个重要概念Model和View的组合体,用来记录在请求响应过程中Model和View的变化,在这里可以简单理解为去Model中检查有没有叫simpleModel的属性已经存在。 + +### 参数绑定 + diff --git a/note/spring-mvc.uml b/note/spring-mvc.uml index 9fead32..1a2c8dc 100644 --- a/note/spring-mvc.uml +++ b/note/spring-mvc.uml @@ -13,7 +13,7 @@ classes OAE4p02Jq0OpklAf3brB/QAA -22 +23 DispatcherServlet f0Rg6JdVd0OMg3954zePZwAA @@ -4409,7 +4409,213 @@ -144 + +ServletModelAttributeMethodProcessor +f0Rg6JdVd0OMg3954zePZwAA + +UDJQm4b87ECfAwXFsnru6AAA +7 + +clMaroon +$00B9FFFF +264 +180 +298 +72 +sdkNone +peTc97n8EUu3mxXpQmi/OQAA + + +1 +HandlerMethodArgumentResolver + + +<<interface>> + + +False + + + +False +peTc97n8EUu3mxXpQmi/OQAA + + +peTc97n8EUu3mxXpQmi/OQAA + + + +clMaroon +$00B9FFFF +676 +180 +309 +72 +sdkNone +AxM/7rK/g0GLar9wkB2XXQAA + + +1 +HandlerMethodReturnValueHandler + + +<<interface>> + + +False + + + +False +AxM/7rK/g0GLar9wkB2XXQAA + + +AxM/7rK/g0GLar9wkB2XXQAA + + + +clMaroon +$00B9FFFF +526 +320 +195 +43 +ibXQqLx7ckSWOfZXsxBLjwAA + + +1 +ModelAttributeMethodProcessor + + +False + + +False + + + +ibXQqLx7ckSWOfZXsxBLjwAA + + +ibXQqLx7ckSWOfZXsxBLjwAA + + +False +ibXQqLx7ckSWOfZXsxBLjwAA + + + +clMaroon +$00B9FFFF +505 +428 +236 +43 +gjLsOeXqqkKj8QMxdihosQAA + + +1 +ServletModelAttributeMethodProcessor + + +False + + +False + + + +gjLsOeXqqkKj8QMxdihosQAA + + +gjLsOeXqqkKj8QMxdihosQAA + + +False +gjLsOeXqqkKj8QMxdihosQAA + + + +clMaroon +$00B9FFFF +588,320;472,251 +HhI8sYeMF0ys3M/9T2oTKwAA +rv9PEXadqEGCBS48x/re7gAA +fHdcTifBwkC3y1PUyVq6QAAA + +False +1.5707963267949 +15 +HhI8sYeMF0ys3M/9T2oTKwAA + + +False +1.5707963267949 +30 +HhI8sYeMF0ys3M/9T2oTKwAA + + +False +-1.5707963267949 +15 +HhI8sYeMF0ys3M/9T2oTKwAA + + + +clMaroon +$00B9FFFF +657,320;771,251 +pn6vT5w+mkOaR1MQs1QN/AAA +5aum4bXNxkeh3XjMFIYN2AAA +fHdcTifBwkC3y1PUyVq6QAAA + +False +1.5707963267949 +15 +pn6vT5w+mkOaR1MQs1QN/AAA + + +False +1.5707963267949 +30 +pn6vT5w+mkOaR1MQs1QN/AAA + + +False +-1.5707963267949 +15 +pn6vT5w+mkOaR1MQs1QN/AAA + + + +clMaroon +$00B9FFFF +622,428;623,362 +xIbzWrL0vUa1uG6adJVk5AAA +fHdcTifBwkC3y1PUyVq6QAAA +6TKNtNrhH06VHVI44sCUewAA + +False +1.5707963267949 +15 +xIbzWrL0vUa1uG6adJVk5AAA + + +False +1.5707963267949 +30 +xIbzWrL0vUa1uG6adJVk5AAA + + +False +-1.5707963267949 +15 +xIbzWrL0vUa1uG6adJVk5AAA + + + + +149 Servlet f0Rg6JdVd0OMg3954zePZwAA @@ -5708,17 +5914,21 @@ HandlerMethodArgumentResolver f0Rg6JdVd0OMg3954zePZwAA -6 +9 vWfojbrAMUmYsvomk6kLvQAA bI+cXd6Kc0yBYNCAY5fPpgAA Edr2pVCtqk6UsuvdLkTqEQAA LLn27gmaHEKAiZZT+MLONwAA 8N5RHGxfE0CjfGJ2yn9G+QAA cpvr6q+p8EexEbvLlFbXYgAA -3 +rv9PEXadqEGCBS48x/re7gAA +YIXUuCCHyEqo+uZGf/4WPQAA +ngAwPD+33UKpwqHhnEEK/wAA +4 sQQIFHG3aE2xOYT+cKjRdwAA 5SVpxR1180CZSECIlxOBIAAA NaM3heUPo0q20AUHwMJ3CwAA +HhI8sYeMF0ys3M/9T2oTKwAA 2 boolean supportsParameter @@ -5742,17 +5952,21 @@ HandlerMethodReturnValueHandler f0Rg6JdVd0OMg3954zePZwAA -6 +9 koFyJoNyJUaSI1YEJQYVjQAA pssrew/SVkeC8yF9kdNfHwAA E+BRXJh8HUeWzAoIR0H+XwAA Xk8eOEILgU6VT93LOCT5kQAA nqLfmK28q0mqqD9Umo+gPAAA AMAv97kycUK0nGzgCQ3kQgAA -3 +5aum4bXNxkeh3XjMFIYN2AAA +Aj0bbg4KYE6Jtpw6W0leswAA +bDHFjw0JXEG3VVmRirexnQAA +4 mEb/Cv39rEi2aR36ilmqjQAA K+7PNUoTiUabFxJ2oKgHVQAA 3BIm9nAI6UC51JF8+fP6XAAA +pn6vT5w+mkOaR1MQs1QN/AAA 2 boolean supportsReturnType @@ -6743,6 +6957,61 @@ +0Nw5xsKokqDkrsMbESbRgAA xuTQv6cGO02PQeK9RkRpDwAA + +ModelAttributeMethodProcessor +f0Rg6JdVd0OMg3954zePZwAA +4 +fHdcTifBwkC3y1PUyVq6QAAA +Bzyy0AttQ0ejvr94QbZ9OAAA +3SEBCl7JyU6hZJua7KMhgQAA +JLPdPSuraUOowDy6WUdGtgAA +2 +HhI8sYeMF0ys3M/9T2oTKwAA +pn6vT5w+mkOaR1MQs1QN/AAA +1 +xIbzWrL0vUa1uG6adJVk5AAA + + +ServletModelAttributeMethodProcessor +f0Rg6JdVd0OMg3954zePZwAA +4 +6TKNtNrhH06VHVI44sCUewAA +7RpMlA7t6UyWY2IsslzXOQAA +yMn4xSD1qEmjzQvI+iPkwAAA +6X889fII70WGx2Ah9hgiswAA +1 +xIbzWrL0vUa1uG6adJVk5AAA + + +f0Rg6JdVd0OMg3954zePZwAA +ibXQqLx7ckSWOfZXsxBLjwAA +peTc97n8EUu3mxXpQmi/OQAA +4 +fn2T6Y7SXEuqh7G8Lr2x0QAA +WX2dmI75IkmcteUji6UVjwAA +q6NhrPu8q0y2y389l10nDQAA +PeFoagF5IkSp9Zawyno52wAA + + +f0Rg6JdVd0OMg3954zePZwAA +ibXQqLx7ckSWOfZXsxBLjwAA +AxM/7rK/g0GLar9wkB2XXQAA +4 ++140xJ7iT0CXzJ2NXqrV0AAA +35jyvaS4CUCwi4QnNWurIwAA +FPnOefJKG0uZUOwJdwe9sAAA +tnpPbeksYEqsQP9BFdWRsQAA + + +f0Rg6JdVd0OMg3954zePZwAA +gjLsOeXqqkKj8QMxdihosQAA +ibXQqLx7ckSWOfZXsxBLjwAA +4 +SPO5vrS66U+/OiwocIcGPgAA +Y9NHEXK2NkCj6nnMGPdk3QAA +nDMxMrRsj0atX22tptcvuQAA +nOXi52n3D0Sx0OqmVZEclAAA + diff --git a/src/main/java/controller/SimpleController.java b/src/main/java/controller/SimpleController.java index cbf1cb6..4e0211d 100644 --- a/src/main/java/controller/SimpleController.java +++ b/src/main/java/controller/SimpleController.java @@ -3,6 +3,7 @@ import model.SimpleModel; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; /** @@ -20,8 +21,9 @@ public String echo(String name, Model model) { } @RequestMapping("/echoAgain") - public String echo(SimpleModel simpleModel, Model model) { + public String echo(@ModelAttribute SimpleModel simpleModel, Model model) { model.addAttribute("echo", "hello " + simpleModel.getName() + ", your age is " + simpleModel.getAge() + "."); + System.out.println(model.asMap().get("simpleModel")); return "echo"; } diff --git a/src/main/java/model/SimpleModel.java b/src/main/java/model/SimpleModel.java index 7e79b9b..6994a8a 100644 --- a/src/main/java/model/SimpleModel.java +++ b/src/main/java/model/SimpleModel.java @@ -26,4 +26,12 @@ public void setAge(Integer age) { this.age = age; } + @Override + public String toString() { + return "SimpleModel{" + + "name='" + name + '\'' + + ", age=" + age + + '}'; + } + } From 435523732d0925d0817262c4ca835f09e853d1ef Mon Sep 17 00:00:00 2001 From: skywalker Date: Sat, 9 Sep 2017 21:06:27 +0800 Subject: [PATCH 04/20] =?UTF-8?q?DataBinder=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- note/images/DataBinder.jpg | Bin 0 -> 70766 bytes note/images/WebDataBinderFactory.jpg | Bin 0 -> 31819 bytes note/spring-mvc.md | 16 + note/spring-mvc.uml | 840 ++++++++++++++++++++++++++- 4 files changed, 854 insertions(+), 2 deletions(-) create mode 100644 note/images/DataBinder.jpg create mode 100644 note/images/WebDataBinderFactory.jpg diff --git a/note/images/DataBinder.jpg b/note/images/DataBinder.jpg new file mode 100644 index 0000000000000000000000000000000000000000..af2236cf465f4ef5e909ff0fffa4677d4367fb78 GIT binary patch literal 70766 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

    Z{ ziDE(GxCFITvuKQ>>E^Q`V0@`Y;`2`Intr&5!Zwt9#=|a8f)&`){;Ms+9b|Qeu~#nJ z^>~bTrJXz!@_Yx6UhZ3@JE;4bPDm!ql?VAR3!Y80^ucLVs39~yh4kTWfKQ0bx($cM z?0o`6=zqxu-Nyyfbm=Kevejb|+5g>a2OK7bX@7oL;0GgDp0MOKj&XQAj{8M2L-MeBesE~O4 z2BLT@xhcbRA;qmIqm<6|0G<=Gr>TG{-5v*2Y3EbE1OWh`ZKM?dqz3>{{a5H1fL-*u zc@cUf-wQjS@(prN?}$n)z&Ktj80SPTz&K{z0OORym}wY*&y)c^6Dh&+d~pB%%Z-LI z3!pgsCW-&!*q40GHHQGV?Am?30B8&*{!xmH9Zuo@4SW~yA3WbL{8xBThkw-<^j4Y+ z7Yy=H{JR)n4!`Q$)?WJ3->{&fzUu!k^ItNWYhHkCNNa|KNZW*#Wh>p(-lq)};;PhC z?xZEl`OMp&Oj@5ul2EP_s=t|}U_Ge&CakCYMVbDKj;A*7IMb5E classes OAE4p02Jq0OpklAf3brB/QAA -23 +25 DispatcherServlet f0Rg6JdVd0OMg3954zePZwAA @@ -4615,7 +4615,535 @@ -149 + +DataBinder +f0Rg6JdVd0OMg3954zePZwAA + +esr4oSt9H0qUyMpIsMdqUgAA +11 + +clMaroon +$00B9FFFF +148 +76 +515 +85 +sdkNone +piQAW2SEpUe/rCvfoN3cQAAA + + +1 +PropertyEditorRegistry + + +<<interface>> + + +False + + + +False +piQAW2SEpUe/rCvfoN3cQAAA + + +piQAW2SEpUe/rCvfoN3cQAAA + + + +clMaroon +$00B9FFFF +700 +76 +474 +85 +sdkNone +BG8MYkfwdk2lyYL04Q1hSgAA + + +1 +TypeConverter + + +<<interface>> + + +False + + + +False +BG8MYkfwdk2lyYL04Q1hSgAA + + +BG8MYkfwdk2lyYL04Q1hSgAA + + + +clMaroon +$00B9FFFF +631 +228 +86 +43 +pNvR01Bc6kuV6Ut9BnX1bwAA + + +1 +DataBinder + + +False + + +False + + + +pNvR01Bc6kuV6Ut9BnX1bwAA + + +pNvR01Bc6kuV6Ut9BnX1bwAA + + +False +pNvR01Bc6kuV6Ut9BnX1bwAA + + + +clMaroon +$00B9FFFF +625 +308 +98 +43 +w2K7xvxiIUS65fEDoLk1mgAA + + +1 +WebDataBinder + + +False + + +False + + + +w2K7xvxiIUS65fEDoLk1mgAA + + +w2K7xvxiIUS65fEDoLk1mgAA + + +False +w2K7xvxiIUS65fEDoLk1mgAA + + + +clMaroon +$00B9FFFF +631,228;491,160 +2k6DnZODdEC7//zai45RMQAA +Z2csDvZeFUaOqeDewRMYygAA +eAOprjhxhkCW41wVvMB+eQAA + +False +1.5707963267949 +15 +2k6DnZODdEC7//zai45RMQAA + + +False +1.5707963267949 +30 +2k6DnZODdEC7//zai45RMQAA + + +False +-1.5707963267949 +15 +2k6DnZODdEC7//zai45RMQAA + + + +clMaroon +$00B9FFFF +716,228;852,160 +Zz0GMpvSaEuQxvqqCKvZvQAA +WShetbG+V0ycUL0v9FUi7AAA +eAOprjhxhkCW41wVvMB+eQAA + +False +1.5707963267949 +15 +Zz0GMpvSaEuQxvqqCKvZvQAA + + +False +1.5707963267949 +30 +Zz0GMpvSaEuQxvqqCKvZvQAA + + +False +-1.5707963267949 +15 +Zz0GMpvSaEuQxvqqCKvZvQAA + + + +clMaroon +$00B9FFFF +673,308;673,270 +5l972v0y/Ui0VCwW+tvW2wAA +eAOprjhxhkCW41wVvMB+eQAA +/kUDuaB74EeyUClxItcxlwAA + +False +1.5707963267949 +15 +5l972v0y/Ui0VCwW+tvW2wAA + + +False +1.5707963267949 +30 +5l972v0y/Ui0VCwW+tvW2wAA + + +False +-1.5707963267949 +15 +5l972v0y/Ui0VCwW+tvW2wAA + + + +clMaroon +$00B9FFFF +594 +388 +161 +43 +FLWL5G8Fy0eOR9NvFZcwTAAA + + +1 +ServletRequestDataBinder + + +False + + +False + + + +FLWL5G8Fy0eOR9NvFZcwTAAA + + +FLWL5G8Fy0eOR9NvFZcwTAAA + + +False +FLWL5G8Fy0eOR9NvFZcwTAAA + + + +clMaroon +$00B9FFFF +567 +468 +214 +43 +oh1ObkvL10yOHzlD5I/pmQAA + + +1 +ExtendedServletRequestDataBinder + + +False + + +False + + + +oh1ObkvL10yOHzlD5I/pmQAA + + +oh1ObkvL10yOHzlD5I/pmQAA + + +False +oh1ObkvL10yOHzlD5I/pmQAA + + + +clMaroon +$00B9FFFF +674,388;673,350 +6ZPEreowskq8Ll4G5xoiKwAA +/kUDuaB74EeyUClxItcxlwAA +d7VoCDk8hkSRLCj9PxUMAQAA + +False +1.5707963267949 +15 +6ZPEreowskq8Ll4G5xoiKwAA + + +False +1.5707963267949 +30 +6ZPEreowskq8Ll4G5xoiKwAA + + +False +-1.5707963267949 +15 +6ZPEreowskq8Ll4G5xoiKwAA + + + +clMaroon +$00B9FFFF +673,468;674,430 +FGAaCyp+t0aXHPA3PhpYRAAA +d7VoCDk8hkSRLCj9PxUMAQAA +q2B/MVi5VkuAa4yHdTEIkwAA + +False +1.5707963267949 +15 +FGAaCyp+t0aXHPA3PhpYRAAA + + +False +1.5707963267949 +30 +FGAaCyp+t0aXHPA3PhpYRAAA + + +False +-1.5707963267949 +15 +FGAaCyp+t0aXHPA3PhpYRAAA + + + + + +WebDataBinderFactory +f0Rg6JdVd0OMg3954zePZwAA + +Ua0UiXFEkkO5TOAMBHWKMAAA +7 + +clMaroon +$00B9FFFF +499 +64 +488 +59 +sdkNone +wKUl0IUMW0W9gNwI6CxlZAAA + + +1 +WebDataBinderFactory + + +<<interface>> + + +False + + + +False +wKUl0IUMW0W9gNwI6CxlZAAA + + +wKUl0IUMW0W9gNwI6CxlZAAA + + + +clMaroon +$00B9FFFF +665 +169 +157 +43 +9yrYPcKy+0uGnWPtCK2PsAAA + + +1 +DefaultDataBinderFactory + + +False + + +False + + + +9yrYPcKy+0uGnWPtCK2PsAAA + + +9yrYPcKy+0uGnWPtCK2PsAAA + + +False +9yrYPcKy+0uGnWPtCK2PsAAA + + + +clMaroon +$00B9FFFF +657 +258 +172 +43 +yhK7vbyjL06s/ziF6GC88gAA + + +1 +InitBinderDataBinderFactory + + +False + + +False + + + +yhK7vbyjL06s/ziF6GC88gAA + + +yhK7vbyjL06s/ziF6GC88gAA + + +False +yhK7vbyjL06s/ziF6GC88gAA + + + +clMaroon +$00B9FFFF +641 +347 +204 +43 +UyKFirHXNU2r9RKRIB0gCwAA + + +1 +ServletRequestDataBinderFactory + + +False + + +False + + + +UyKFirHXNU2r9RKRIB0gCwAA + + +UyKFirHXNU2r9RKRIB0gCwAA + + +False +UyKFirHXNU2r9RKRIB0gCwAA + + + +clMaroon +$00B9FFFF +743,169;742,122 +S9JMEFMFmkO9hRPIOTyLkQAA +Tbj+QFoOYEiOy3zrbRgqcQAA +FcxNSNGHoESYUN+VRFn/KgAA + +False +1.5707963267949 +15 +S9JMEFMFmkO9hRPIOTyLkQAA + + +False +1.5707963267949 +30 +S9JMEFMFmkO9hRPIOTyLkQAA + + +False +-1.5707963267949 +15 +S9JMEFMFmkO9hRPIOTyLkQAA + + + +clMaroon +$00B9FFFF +742,258;743,211 +V/WkItcHYkSPJfLrj/d9zwAA +FcxNSNGHoESYUN+VRFn/KgAA +meF/RUQ8a0mjB1ESPqnnUAAA + +False +1.5707963267949 +15 +V/WkItcHYkSPJfLrj/d9zwAA + + +False +1.5707963267949 +30 +V/WkItcHYkSPJfLrj/d9zwAA + + +False +-1.5707963267949 +15 +V/WkItcHYkSPJfLrj/d9zwAA + + + +clMaroon +$00B9FFFF +742,347;742,300 +cqQ8qAvBDEeKhtLtVdPI0AAA +meF/RUQ8a0mjB1ESPqnnUAAA +ffq1tTCxjkay45CSLHGA3wAA + +False +1.5707963267949 +15 +cqQ8qAvBDEeKhtLtVdPI0AAA + + +False +1.5707963267949 +30 +cqQ8qAvBDEeKhtLtVdPI0AAA + + +False +-1.5707963267949 +15 +cqQ8qAvBDEeKhtLtVdPI0AAA + + + + +167 Servlet f0Rg6JdVd0OMg3954zePZwAA @@ -7012,6 +7540,314 @@ nDMxMrRsj0atX22tptcvuQAA nOXi52n3D0Sx0OqmVZEclAAA + +PropertyEditorRegistry +f0Rg6JdVd0OMg3954zePZwAA +3 +Z2csDvZeFUaOqeDewRMYygAA +uSYe0x2/pkCJGN2pu/tTBgAA +bJQyy44NFUi8br7SG9rY1QAA +1 +2k6DnZODdEC7//zai45RMQAA +3 + +void registerCustomEditor +piQAW2SEpUe/rCvfoN3cQAAA +2 + +Class<?> requiredType +GezSC47ndUOhtqnFK4z8bQAA + + +PropertyEditor propertyEditor +GezSC47ndUOhtqnFK4z8bQAA + + + +void registerCustomEditor +piQAW2SEpUe/rCvfoN3cQAAA +3 + +Class<?> requiredType +/tNjM7s7jUORx0Z8Z4s23wAA + + +String propertyPath +/tNjM7s7jUORx0Z8Z4s23wAA + + +PropertyEditor propertyEditor +/tNjM7s7jUORx0Z8Z4s23wAA + + + +PropertyEditor findCustomEditor +piQAW2SEpUe/rCvfoN3cQAAA +2 + +Class<?> requiredType +bh02mP0a+EysXtTc0veqMQAA + + +String propertyPath +bh02mP0a+EysXtTc0veqMQAA + + + + +TypeConverter +f0Rg6JdVd0OMg3954zePZwAA +3 +WShetbG+V0ycUL0v9FUi7AAA +aY944ttpX0qD1WGxoerjLQAA +aMMdGgg/FECgTYtxEtJVTgAA +1 +Zz0GMpvSaEuQxvqqCKvZvQAA +3 + +T convertIfNecessary +BG8MYkfwdk2lyYL04Q1hSgAA +2 + +Object value +svKU7cw/zECUH3cCN+U2PwAA + + +Class<T> requiredType +svKU7cw/zECUH3cCN+U2PwAA + + + +T convertIfNecessary +BG8MYkfwdk2lyYL04Q1hSgAA +3 + +Object value +kG1lMLPdUEaLoSQVSdf+RgAA + + +Class<T> requiredType +kG1lMLPdUEaLoSQVSdf+RgAA + + +MethodParameter methodParam +kG1lMLPdUEaLoSQVSdf+RgAA + + + +T convertIfNecessary +BG8MYkfwdk2lyYL04Q1hSgAA +3 + +Object value +PZt6FSgC/kKN+uGVCtiplQAA + + +Class<T> requiredType +PZt6FSgC/kKN+uGVCtiplQAA + + +Field field +PZt6FSgC/kKN+uGVCtiplQAA + + + + +DataBinder +f0Rg6JdVd0OMg3954zePZwAA +4 +eAOprjhxhkCW41wVvMB+eQAA +GqSR/b0XnU6RNV1cOY/HsgAA +K4NKmVLEQU+1BmmPCljhZgAA +g9PsZnK2ZkmjMsqNkeqz3wAA +2 +2k6DnZODdEC7//zai45RMQAA +Zz0GMpvSaEuQxvqqCKvZvQAA +1 +5l972v0y/Ui0VCwW+tvW2wAA + + +WebDataBinder +f0Rg6JdVd0OMg3954zePZwAA +4 +/kUDuaB74EeyUClxItcxlwAA +v2qpV03TrEu1AoWAxMeeowAA +g+whx8rtW0OyuHUD9EX5GwAA +PhwqhkdCJkygUcfLlkQFdwAA +1 +5l972v0y/Ui0VCwW+tvW2wAA +1 +6ZPEreowskq8Ll4G5xoiKwAA + + +f0Rg6JdVd0OMg3954zePZwAA +pNvR01Bc6kuV6Ut9BnX1bwAA +piQAW2SEpUe/rCvfoN3cQAAA +4 +/2zoSbgWpkWDgccWDiheHwAA +YgMXBNJJlkGYzz+yFOUwEwAA +avCAiHj3d0aJHKmUO87z+wAA +ODFHxfo+PU+CeP8OXghSSAAA + + +f0Rg6JdVd0OMg3954zePZwAA +pNvR01Bc6kuV6Ut9BnX1bwAA +BG8MYkfwdk2lyYL04Q1hSgAA +4 +MwlCdWYFi0ePKP3HTrKhlQAA +Tp9JHWeMDUyZxTxQWBdFHwAA +esjh4TFqakisvvFn2deZogAA +CHh/cRqOgkChybpBtDl6fwAA + + +f0Rg6JdVd0OMg3954zePZwAA +w2K7xvxiIUS65fEDoLk1mgAA +pNvR01Bc6kuV6Ut9BnX1bwAA +4 +7U1tY2J5/0ulGCFXJIT1YQAA +OaOBCTeOQkyVsvAiBl9hRgAA +kOa9VXrUdUmHNfsa2j+OPAAA +xK2Bqmyjpku14kGawAllXQAA + + +WebDataBinderFactory +f0Rg6JdVd0OMg3954zePZwAA +3 +Tbj+QFoOYEiOy3zrbRgqcQAA +WH9H5W0q4kqq+krzj+YVkgAA +5rudIgzHZ0qmUU1u93nykwAA +1 +S9JMEFMFmkO9hRPIOTyLkQAA +1 + +WebDataBinder createBinder +wKUl0IUMW0W9gNwI6CxlZAAA +3 + +NativeWebRequest webRequest +AYBnIu51aU26lFRBaIBUtgAA + + +Object target +AYBnIu51aU26lFRBaIBUtgAA + + +String objectName +AYBnIu51aU26lFRBaIBUtgAA + + + + +DefaultDataBinderFactory +f0Rg6JdVd0OMg3954zePZwAA +4 +FcxNSNGHoESYUN+VRFn/KgAA +DeuCpSWPEU2bb3Kx0eaOQgAA +kijz2GvMAEe2mXKRzwyzBwAA +4sZC5XdsxUOCClK1juidqgAA +1 +S9JMEFMFmkO9hRPIOTyLkQAA +1 +V/WkItcHYkSPJfLrj/d9zwAA + + +InitBinderDataBinderFactory +f0Rg6JdVd0OMg3954zePZwAA +4 +meF/RUQ8a0mjB1ESPqnnUAAA +l0BvVXUc/Ee6mFIrlSiGwgAA +eXH8QAYJDUCrHbjPpSxUOQAA +riW28AFawEy0CCyGSSkEgwAA +1 +V/WkItcHYkSPJfLrj/d9zwAA +1 +cqQ8qAvBDEeKhtLtVdPI0AAA + + +ServletRequestDataBinderFactory +f0Rg6JdVd0OMg3954zePZwAA +4 +ffq1tTCxjkay45CSLHGA3wAA +p+0tX/sdJkm93S80oDOUWgAA +9OvDeRC3RE6u5KpmPpgwTwAA +Y2swPHjQe0+fanxGnemcMgAA +1 +cqQ8qAvBDEeKhtLtVdPI0AAA + + +f0Rg6JdVd0OMg3954zePZwAA +9yrYPcKy+0uGnWPtCK2PsAAA +wKUl0IUMW0W9gNwI6CxlZAAA +4 +Xir3C8L9gkCy1dd0PnuAxQAA +K3piFQpQvUa2kdlGDEUG9wAA +TFKLU0/pxU28OaQGhsm0SQAA +p6H9W9mVn0WPhf8zPQ0BiwAA + + +f0Rg6JdVd0OMg3954zePZwAA +yhK7vbyjL06s/ziF6GC88gAA +9yrYPcKy+0uGnWPtCK2PsAAA +4 +ZOppfJGxpUSZ60kZeq8oJwAA +xz+GA41cjk2cZIqIBNzfkQAA +ogU9acFPwky4Hn1MA8r73gAA +zd6Y6eqOWEyEVLZJwXRHWgAA + + +f0Rg6JdVd0OMg3954zePZwAA +UyKFirHXNU2r9RKRIB0gCwAA +yhK7vbyjL06s/ziF6GC88gAA +4 +BIgZlgdMCkOLHle53lJ3HgAA +hqvRHCyNxkSGca0vgtnDmwAA +a2+r8o0ZYkydMtHAbwSN1QAA +fAc10pz5xkqa6ezaInKUsAAA + + +ServletRequestDataBinder +f0Rg6JdVd0OMg3954zePZwAA +4 +d7VoCDk8hkSRLCj9PxUMAQAA +sb0HToHNi0euYFE/Wre4hgAA +wCmdWLGPdkGa7eBPbqxyfQAA +OWOxudkHeEmvxVzWM0VSTgAA +1 +6ZPEreowskq8Ll4G5xoiKwAA +1 +FGAaCyp+t0aXHPA3PhpYRAAA + + +ExtendedServletRequestDataBinder +f0Rg6JdVd0OMg3954zePZwAA +4 +q2B/MVi5VkuAa4yHdTEIkwAA +RvaR3Tvan02R52PQQ4G+0gAA +I9JQBM42GU+94UnDDDlTGwAA +9O2N0C0kuUOIpZfK7/jY4QAA +1 +FGAaCyp+t0aXHPA3PhpYRAAA + + +f0Rg6JdVd0OMg3954zePZwAA +FLWL5G8Fy0eOR9NvFZcwTAAA +w2K7xvxiIUS65fEDoLk1mgAA +4 +Uu74J7mX0EykJEYw29gZ8AAA +1EqmNZS72UqwAWcJDXdLQAAA +rXgkNx3FIEG0WuD1t60gdwAA +RBnWgG/asEqwYjyqDXQMbQAA + + +f0Rg6JdVd0OMg3954zePZwAA +oh1ObkvL10yOHzlD5I/pmQAA +FLWL5G8Fy0eOR9NvFZcwTAAA +4 +D+hWN0fL9UmCSYMnAbizbwAA +x6kM1IaD1UKuEeu7UX8KaAAA +cpqJUJuOCU2skrsbzSyyXwAA +BdegGiyk8EG9WkTaCN/HzAAA + From efdb8fbf8e3c5bb3616eaa8b2f0ab01123aa4310 Mon Sep 17 00:00:00 2001 From: skywalker Date: Sun, 10 Sep 2017 20:09:40 +0800 Subject: [PATCH 05/20] =?UTF-8?q?JSR=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- note/images/Validator.png | Bin 0 -> 18993 bytes note/spring-mvc.md | 128 +++++++++++++++++- pom.xml | 6 + .../java/controller/SimpleController.java | 4 +- src/main/java/model/SimpleModel.java | 3 + .../java/validator/SimpleModelValidator.java | 7 + 6 files changed, 145 insertions(+), 3 deletions(-) create mode 100644 note/images/Validator.png create mode 100644 src/main/java/validator/SimpleModelValidator.java diff --git a/note/images/Validator.png b/note/images/Validator.png new file mode 100644 index 0000000000000000000000000000000000000000..85aa28f736ea405eb25002f32b143655d7ae4e20 GIT binary patch literal 18993 zcmb8X2{_bk7e7vl%2o*>w4vp-0dEVdi{@>sAzpk!n=KH zh}sDV2!qa_0iN8&Ng5Ck$R5Z(eXQyRUz=J{pD?fA*m8VU$ctx_b71Qitd>Db3+jl5`qVO*kN0tu)lK7$Yuz{Ui$={x zuKaYrbC|eWW|w`UPY8VX7X&^Y6%+sY zJP!lD5;W2SAHO>OtNX8x|LT6)QM#-Fb(e>j4Bx-uzJ?OwMcU=FU_6sYbq3-O;-20< z55r6H#-q{0P{8l`rThzcerSJm!4qcs$HlC8S%*nsbE9+SXB(67;=bh3KwN+S4>I0H zA|e0is3Czg_F|Q&ORg?Uyx$&CTBaCF^ZXB?bg9eQ(MnW{GS)&BF;2P8au=%(C1ZXn zbL%AN9>y#C2s1!v+>}-K)E6CQhiZuZ1@V%9(JSVb(JHt(aM&B{#7L!tvEmT2*$VyY zl_<2u=gNxgA3m+2`;99^V=u2yM*r}E#Ud^(7HoE{xH zPPrl_dmr2~GF^fodLm>=3BLRZ@iL~sjOa10ZPqWcvPRCnehRX=*`V`EbCk603CQ~5 z!)ax?P}e-^yc~&b)aPxq{bqk&Zh(OTezv~R<_DAb(?s)JsT5WY;+XQil2T&30A0i> zcPrcP@*GEM*PU{S4C(VxjwvD~#I+smI%tk-$T&^V^zMTjtM$1aCO{sz`8+0t;Ru6~ z&3TzPM@Gs&I$y$ia&@nax5LJ<^>AEVNK`f#gR_i;PjTkm)FpN{U5ueQsNDvMX+$pelwJTL0Hx!Eg?dqr(6@g0tu zEX)N^jNhApdU?2Wz%Q@VT}jdg#ZYPyUVv?ke8`Ds@xGnTIuo(8Hro(uH?!^Cv7BjE z22ZohBk_#tikjHKUE0=%am0c6v|2de!piKUH%u~)yk<(T=GAHanf+dqGc^3Dd!*tT zqw7TlpSnmcLJzsDLM$-1G&_d$nGQ)Gh{_Bwp$HM(t5%RTywFL~9kt zeUR3cb63eI*XdHfJ!+F3Us}n2U)fZ4u1Hk_3B4+A_!iz%hz%U@l)-4 zvm!_KXP*=-$(JRfGXl?|!szo0uwYb3ldbqI$+bR2j@1MW)%e?@O$Y5mCnbks<>UcZ zx%O$5n5mItw{PNnwRi7hN|Ky5tXCK;&yET)S<6LzRy<&@m~TrlLA2}(@Blz-b7-3q1{Y~9_ygzGoSM7<1~LZl6-!-n%lJ`jQDGLp9R&tz{`JW+8N+t z{H33NPk`^x6BuJmigRu`?;lktwu%m%|NGZdvHrh*t%vGJ{e6;(GTBJ~;}=c!KaNLd zfw7>!4@>9IAS0eXG#5t>LJ6htr^$DjTSkxR2~SVvth1$l1LzDMxRlDNxv=vJkS{6u zV7&PHZPuw>m^p~ZV^Jez(h9&I&;6@&mW-4IkMU&8k@kYWzltQbjXW$T#-FA$XPH1d z{q(2Aquq6Sq`;@PLviN+)%dydfw%4~6aR&wIB`aC3HpntB+?@d6mFkN2AC~8ec=14 z6>FqFHC31LPi48GaVp;5ZBCh0O-ONJ+1%}TGDpdLQ^LG3R9~8q_ z?dmgVA70C^d$9L#Y}8Jw*fh~Ob}>NE+D!=0(!Qw&Fy_7SW&wiUF zKH}m3TOcYMoA4iY^$!{HSHLq?{}vZBG|SNZ>VJ!yY{wrL0jE!Wuf&tRZe>cgoxbYC z9$~a&Ra`j4S|ECK9wriRu+~_$Xxc*p7TvWsVu zu&=AO_nf3%jR#zW2X3=dpSRnh?V{OY^)?NPUFbav1df)$-|uL6+7&W-sNC%?Jd(c$ z{ZydYka{(?F1Bi@3cQ>|38VcgrTr!60!-xj_X{+}{mgfUHhw!7mSD!__Am4=VtIDh z90bRV^hDGhh^I?vafw94Z_lJqvw>wTHf}woS66D(t5~9l0w+tGyEdMqvAre@4!bBtPRKXqGtg)UibMuk7+w#qbid@U`Wv+GY1;Jh~GxU?yz z$+Qaoep4fLR42OSrLwcLW^aD1Wb&}3RXxv-Md7O^T_UAN$hAV{WLwwjJ4W8&frapC zxtPJ9y1^)`O&?YLokmQp=rH*Al4c(edw5CUlUL;Tx=22qmE-8;u-|4XE+pM|D`FB! zUHbYkHo69!xox@k_|@U=Qm<&sHm(^NFdO)2iqCQTakYpm3-v~~$&u9fqgxINh$6++ z<3|DUPInw$bGXpD3`fiHxbbR?hKsvWK%*B<_YB&-rvh-Is%ix;qq_I^>ASXNxuC7y zH>p!`8LK=kNZHsAfln)kdYUv+Nrr@MZ$iIhiU*&ojl>S50SjPhBux*D-)l@Z7!Q*= ze*V5kMn0w+Sj&BF_Ri#Tt6||7MxPpOtq%Ql-}0Q8xOHP9Wbev?xCtu90xSDmp*z;r zb(LGbBrV?};+4jt+2PVwdqq-NxAi?#ET0Q?OG-r)+B_@D6Wkmtl{2a`erWQTN2pdu zxt?>Cws5^tGROWdX$5}UVy%*XdIckf`a-6qJ&M#kRD$9pHdl!ocxqw^Uy6xX*GvR> zlMA0k?IeNuZin#2`fO{v_`H&Xa;mb%bh9R!e8{hCb;53JFCt#-2PUfa1#mq(dXW3WQ3(Uv3wbD;`HT7u`qk);&+0>ciFuT z1MvnM2cPJa%EaWj5I(jAXrKwy>e{@t{C%l)w)ai)Mt%^T=jzjI71|QcOT%4J+sE(s z+Q-Kz_U^DiZKkj{=b_0%4leF2R1`Xw;i;KInPDE~gFl@H&BW!OvqC&BwS}ngxW-cM zz!e|V>pi2vfdYlbsV-!Ux{TC3;f_9880yj<2$$K2?Vqgv>eU~f7*DD)jEryg>nf>2 z-lt3+_V@VOCqDU98n%u25I+@rJP+`JN_pQGAGvd>bibAp*16k&dW~x2-^9C+1Zx5&h1aW zy6RA`uPN<&A|vQ3kI;b)3g)GWikjvHtb;w^y;8&v^y8LiGGP!|U>jT)8&<(@gMnrR zoyBHCyqoIn09&tARb3zoL>$owwFpFk(jbqWp^{9!wSzvHYraC!$dY6e-U5Zyazu%tmiEus!HJH}Ot}tUX0Nq^ z1+@N$qIFeC?jiK#u_MfLUv3VDLHmdhvAkw} z<}OKuVpodM5_-9!n&^x5jgi~*D>lFEN}qipn$7dhg%8}ec~nb7I?kHYKH~736FFn~ z5N`!UoKjV*vRAtk{}kwIg;@t70Ow+D*O-a^ z!yR7p+C1#xdJrpewf5>wRE?ap)4809UTlbjhoD2XOE`VXEVdr^&`t zqsZR`#}f9-xUvC;D#E~9&#^#s&I5C6^h~{MqU#8?GLHY1^LvTn0`8^{FNBA@9~)EE zH+5Mr42fSble5oKZaoH;)A;w6>$PIvB-g)1SRi#HRhIQ zSrZd8b)6KFX_yjSM4^+gy;Z2^ zV0q#XY(j@`a2T)&4T}ru@SAWRbepHLE0fU#{G9O>Po-;@SY~{O9Ca|^mxvcecCd}V z7MXS7lt&3j_vX-+m`4!IRL-OTGG${`&3N$YZ1CqbcCpOCJ-FNG@rz3Ql2W%7#*(7V ztQR|9kGfEsEUh?gZ+6+$77XirdiI~z=OJtAk(cRTQObS!XH)H@i612bj?A@JU%z?< z$trzs)13S?rGV~mWHZzncheAvQxsdCR<3qSjvj|;_(-HIQ;=kZVoyke&{#hX%>AJ) z#gmkMY~PK_EMqeunknpPFX z^mq&=NsWYf^5M;tFd1~LU0L=ObUNLJ*4Ps}BBPBXydivHu07brHQC_94sa?7j=uGJ zBpA0)P=f%0+I^=I7w^ln=#3^bSEvCCu9NuT>@#@2S~Z(;+l< z^*}>xLxp-~-;}H5`7EW6|5Il?FSGhP06OA(HqwFvbc8@q3Lt*uVu0(?2 zjz8qLUe-WSVz|nZ{*gzcnbS5EkFtt5u7AIEE<+<@Kjg?<;@$P}qS)0?ogr6x68qd` zP^ykzR2hTXaMW>^UqD+VY5>*RjHP8|Xg!v({j`#R7Mxdm+QSR{}&M?L66Kl`2J{{H@yqGp#Z5S@} zy>4`yapNK#|0q6|yS;zAD^m+^rb?v5M~2UWuRoalaZ7?OrQ#x`lnRv1s-ws%Pe&(5 zqwP@dQFnAB++ww2Z!`3AzCBYTJixK12RM10md6DE7)hE!c%T?FFa&#)X0~c!yuA-B zkh@|jopWQS&NC{kj)uwSmsbRMj#ZjFjY$;ZpYU5!WR{f<_2Y2csyM62uj~Shv#fB? zt2m3iFYA}peE+tZYJlQ@`@UgzLnE|RL3k&-!(i%}K9L#Kznpohi!LqAYa;rCq)cS6 z>Fb`qgemK;mIGuFdUz_!wb?9wAfWtBNA|zdA#-{jVEw=8w9m4pgeWO=7*QQw_*@BpUj+t`UXNy-5sBUj%`~%Y}Z{%U_Xfq}TI$^QTL^{?txC{L22+$Ab&7 z&1E7oCZk`xYLAdn!LYdR8$mymii4z?4K{z%np*$~Kh>D{?z@iXvLVqhbD#KhoNZl2 zOH8k==Z>q`eEbD#u>=8a*9^J|x^=GeKtJ2QEuh-(6W*fApIsrj_OO+}h}dB9r`sX= z`faO}@4oeTT1t}tL5un|X;`R?fySzk=34{&Z znX+}4_AkH;bP0elM1UF%Wr~S4Xd4m;2|jC3FES_3EVqjKi^PI0KDUo z&~uh5Yfm!G5>^esT0HU>d?a%Q=zVbZ84%jb0!(J!3-&a*<`bIU09Yhc36KKgP$0y! zi#MHRyqr%Mr*%5xc-;1l;JGk5K+8#ie-BEt_Y9s}(iwnT(L7gD3xK!WxI+lEn@K+d z01tQk?i0O{E}OQYsW+IYJE;KwUGjwa?1j&NkA&y#ur(@KObUh_`p}$}@*e{A(=4{=aB#h66n1x&ARQ z*j1npucHOcAC<p%Q~ZP67>^=~62%zguTi7!-fL zrqHmEq|a<2B}#8_Fp%bScM>4RtASwOZTxS~BlIJh|J!o__Wv*KH}%g|-M=3AZ^koF zBk{NhQM!M|`}r#8veN+J^|I1e%z2NN`=gQlkt+-P1t&RW#-6(Mdohxq--7r0PJsY3R~85`Lfx@0 zm%5i0*4czFe_bN<)`%@HJ6QY6M~t-XxS78z{GkBcc%dLoEj3hfNCe_cTXO_*+)?yPH6sajkdZQDVbSTHYi)w=i9 zRkCCU@o7z15QMeozS0tHd=8;#Qb9GwZJ0ZHYIz*JlNK>16L9)yilpfERb!X>nkej0 z-?Q8}%O>9gou&yFxPy#{ejfC*L>eAgZ!hB%jysMJEtM1(d#_n6Nd>m;VUxh=`s7*K znTTZWeBP4*HyViF3Yhyc(9ymcyqlJhQ1R1pV{C))CPPJV#WkjDn)mLtRB=R3Lo~jL zqh|s{eVItmh}I_{O7W%(gFLMwH5Mnp^#_0>IOU2!Gh^b1wrPIO?y;p_UD%nl(9zpL z&AFo;tbC+iLBfb*TzqQst}ab5dc1~KSd%nt&T(ayyN#xa&CfvB$DIrV0$z@~wWNQ} zs}QRm4nLn9UTY8^;kI7OXzlJ%* zwOpvVKU!gz;BX~Rf4wu*WnyA)Vp$ zS~zS!1bO91jNtAriE#Jc$?xQ_a=5dp-?&GcO>F*`_G9_6*{U+~q%2Smn zT6{I?{$ccQ4PA?DGSJ%y8{zdtfNBuRuUNxO(!~mIoc+bVH_1N+D1p8 z-mlcuWOhufeeiXh1|n8;l>=7_F}Y_kaD;KwtK$sq4d6n%zgWn?BNx?*;N=2qCW6H{ zRk4!Y)o@)lre)mJg4p<*H8QwL$|pF^((826ZWztO4JBL4+%bXln0%cKmj*d)HR;GTe^aI<2xw3a73O{qvY}%w zBHkeq5ltL-drn>XLDSNMIglbp)xc`Vp0*K8f07~ifw+FB-btT1>vzmR?NGnY!;ka1 zUWXmFny)EzUvy7-WGLDn7Ia#em><E$F6kMiF@0F{@ zT)2J0#fdd(z99+w{A7Oj#m>;NEjGG}+FHp5X(H=>awpwpm7RH!2-M`qar49^J?`sz z?R5&B@Lub?ompDS+V{IS5{uO}uw}hjLzjIHcemBcZx4F12vl+h59Tt9Samy%apB~K z=i>FK;qxMqk36g^9TrL@)+v{_2lMy7bU})n-4_l*l#|tXc%a|&R*(2hhID$0B9=zF zZau914zlR3^|Hepd}*$t%`LDdBPh_8?5zY(c^uXYsIQD$wbtJc5SLx~QQ#>lBP|wA zq9P4$8D{>#6w|-x^xC0(YQ)DmTfe|9%<o70jSqlI9r#S{-*X3I)Ok!hxA(_>5GAZJFIr-kC|>_{1` zY~R+}BD-RbhQ_qI#B}TjKj}|ElsWw=*-G*_!zX2?|6I?CoR-yr#Vf(0{dk2X_29S7 zA{OQk27^;YaT^6)PXy?{8!}l4u?ceN-}FT)RF!(^E(5bF>N_+taX4c(p~{uC`cjh@ z{pIk^oUmCCCiJ}thB-%N(kstF&mh81FPr$G(@1VzLNucV*Flm0JRf0bB046p{wnOB zH<>2$L|2Lo{}c#8kBj5JAeonzwp+l43%>i)V6J65}l(6^CSA;>$dR;CCW_-Y(r`vA;(Ql zXYAwCwvy#2$@xvxMaNBWAI5_Q&{y?t^H9Lbs)mysSi9Asxl7Y%4%I^T-Zs+Axw?E2W+h1#Xct* zJ>tjao0cLU)g{&CL_RO)3}XheK`Tm&8PJ6rL`Y`o&kAha*vib>p3AIy>lTy^KhyTw zH^2JaYHQ9~w_Z6{K1YeYhoiN!ERTbX+H#egH|Gp)u0(&R zVD{d=%r&o65HsB5!L=}_TL&8kA3o+ttgT^bUUpVQq>k`m%GWN>Kh10@G0KxC$a z`<#)xne+D^NE)||GK~ooE~%*#Ew7{%rNX+?sgd?6vWsC)DwirPo;RNjpHoR z`omk}7|Cjnmee!%ji4V56$;oY^;XqrgPo4Tk4;fLtk~1pL!NH6`5l<;BkW@hM;@{9 zNSHsOWF4fv_9m^QVHf)&Eknav_x|=1)6l*fl5mQg)v3+l$fr4X89fo{3 zWb!ThIf)n7DnhgwT7w}ZenPl6vkgx6C%%NmK9Y9N5VoFYy_Ep)FSUK8c>Kpy4>I;` zFm2b!9PJW233R{lNXfnk#bQk=mJA9%=>q^|OTSLYvr{j(l$)lzJ)0g)nm@8Y7;s>{h+P%p}>w~nF^@|nu8l- zE@6)Eooc~0DmaSCr}@pNlO`Fn4;746tI2xeovqE^%a8gtE4G# z8bsb7Wfgk{fQ_%@g#eEQe!S6x<&wSx0F!#0Og6$P%VI{p8I?V%xEkCXmWQM~Pmsc- zHt^#~>16B&R3+D{(=^=G8t*uU*KsOGfvW4}TSdFYP?bR?H(v`FmuKW;Sfe$TbM;Es z-41&B&U1mlp2j&$Yt}=lH0_$&oOLoHg2OFq%Xoxz+3z@(*<|p6!k8#kl?&Oh z&~aLwuK}D1Cb(!_W#!Iu9KgRXLsCK!7Jz!Q*SDuXBH!s2w{KGTb2zN^j+{m43wZfd zd(+SITNQ(%bHiyB-Tc|+&ULyC44E$0g`SmJHwfn>6) z9<86Bv-)oE|H|SUiVH(aB3_*^COg&!m5l*KFA7N<-Bm!w=Nl}fG+$QDm@Wt`qG1n>Iec&d_qT}FcF{Jl;RgXTW?r43T z-RNY-;;3{{MFQ!eC=|6)dzDguM@w2vL4#7!7)Dq0p15ew$!BzGtDxKaf}PVhhV|p6 ziF;ghsRy9P`TT5`*WUbB2x5x1iZ~wZ_TKHBNUKJG%fx=3Iba z5$V>~_!V=}B--W(TE@=2mgib|=TI;J8uc1rf~PI~Mo_1bjR0<1sP1-~(MO*bAs;Ms z*9}GfVJ6VjBGQ*S15L)=!bf?#T&m00i(Xf0`@+RAx{Z&#T6hq(TJX%%V`qJ^myC$D zIFVyj(Mb`9&|C^yK4O1WAEnVs=ePB==A@b| zY^vIX(c4K@O+BI3t?hgUzc9tsGi`Ngf5l(9ux+y|__Z!LU&fHMOWSy{R!IJY)OZz=S}&{h~|toyUXc^~?bXk(7o&-MT;E#^XUiLvJFK zZp8U%_Icg}esT_+1=Da|iUOd^^vJWaWtXPU!#Fj*#5YRYxK)#AHlBwGgn}>UYZfn? z5OjM?lU|52osH&iOgcxp%jY(I0iRyw)s|$SfS9@Nso5u6aneV+>U!d%R6rKyM>W}Z zaj_8>bwk_X*)0G?USS}h6`Lu&MR=zjmXLHj-lc>j z#qbp36V(9a%Hp%yK5IDYtv3=Vsks{hX}=Al7Y_^h5hcVLWQoIGZS(~DSI%$)NcR0Z z8bc6(;aPC+>BvucH74yiP!gZ_JssmZ%UK;@c!up6_zde4_IJWSvJ?4t_aMko#v%YY z6O>Z`uQTxZbV~UTc=iq6WamBv#!WPnXX`bZ2w?S`LBR9?|Ig?>X<)(sJf(XHXpGOh z`zQPV!g2HZvDzgb0q6N?P>|>hoDRMno#ab>w&7V6b5(sq=;%tVvD5vQ8TJ7;|Mwm8 zdi<5Pz%(Yy757rMX4z)FiDsD#F(9WUMll#Y$jWY`-u4Ctn@yb`e44X1W8CrmmPYf3 z#_Eqo9v+kJFOv<(XUhH22126ulL!>!!Z`c|b*|-0lj8e+m^Z}ty_RoFjd>IOtT+f9 zAUHHM7etc&izEqOBNe@CBh8~)>;U5Ib}>ViE@Mf=?)u(8_C`_0OV zy%g@Xzu+4cGMLffw}StGoU>Kj8y?{qJEz!peO)?N#o0*TkaG_8EAMOsT5MillVI|> zuDrmZ{;zCxuUf6Y0BIO9knNd?t;zbk;6VJ)Ca(dR;K{^mf!e#hR4?l2^1pwszNj*Qla`+0krrKv_BnZ zjD`wd%T)o-?{yZI?yN&9y5CJckducve{!EYDXdTCUfq?!CO3|o=v>a9?KGIO6*KHJ z7~qE`7s;7WXsPFxB_7-8G4+}H(YFK3I9aP$k%{@YiTzz5r$D3{F1F|S zs6A)_R1rk-TwShnw5?G}UdY_dpzvG1B*Xbud_I`GP#9I+lv>En8XDZ;!s#@U)o_aM zy53mc<@T8pgV*#U-0auoGAb2LQQj`tQJk`#Vwd~eUwE;svtQz0Qy+u{2cyP0Jun`( z+_&Ze!p%2x+aFFIjZQ?C=@9DFKm6QtW+e3@a84wv7b~)O0Gais9hsm==#eh14;HQL zJNv2d%YlmRZPu3G}nH(vQS!D@^QIP zUmgM^gT<%l_pe{a5oWuVc>HipgKqJV`g!>l6>f#(u?-kHAmG{zaXY40ri{8K91x;8 z+`Q5Dz}gf8vgho?^PbtRhko_>rr09pNO$s5=;J#bvBANCql+`!3tLt+->gdGfdxP8 z@2p=Gx#_gX(2=={J_$4R&tvWpBaaJl0GC(|-;ZI`lStsHNI`zc-j;r3g0c{LS>tQV zRkWU{H=VaWKzYjq662h6OZW|mHqw!zZhfsHs#H+-LAWE=8Yq@ONhw=Tc4eH=`=k*` zQt0BU**T^MtsT;LSxCu+Mj4hR*7h(IRq=M2tk%1G3_Idn4@W6$Vzpy1998Emsh5N} z#PA^OPiCw6Sy8UNXZL==uxa7HcIFPQq8S}VBc2$rklJ>8G#}d&8exI$)#^x?QQ{*n z6oT*Se0!nooTw$jtEPK8S+TPCj9oGW(b(C)OD9fW5OT(RsO+frMri9~wP@RZHj-qYC&H}k zk;xVOIYpa4S8B?5>3D5}7|rB}$D#P;pQ%Z_Jm|4~t-?ul?FG0IGjME6!rY;2w(|U& zHSZejmfd2k`lBiRV|UJep^wP>%&)zivoV`Sxc6GmYDh9hi1wb9Iy8T*CZckX)bO>+ zT~-C#Dc3k=poh4o&gaIbF(HqGCLaJG9>vH$B5)23HVN55qDgUWK>i7dr%(SlbJe0Q z^PEn{vem0`cd?xMp0A}_M&&BVPVc_2oY{h7Bi*q{Zez zIb#iS7TV$Z6Hvaw^DsLzAUChjtb93VXm7l`(fP$M)xe)dgE|uQKNJuwt~|)I)*q@2 zl{3k$c6WdH=^Xo%bTP4=Wuxe2%4Lp}o2PJ({xeTJ+(Rt?On0`DDKd3$X+sra9ZLQ? z4Q$U>Y*U72*lg%R>ame8UnM8_=TjwT-+iBs_wk zRRvzvY+xX()gmL#C1OB`LN5q27w*C1^sWAc`+AW+&rZMV%!iZZA=^7diqeJNqiqjB zeVd_cb;4CE!Yn3^%AsfY<;7Tw7}juz8^oCSvrp^b{G0mkQUAL{C`NZS!=`f;DZ!7yz_vv}}bsZzdF=1F*T>mhE2OI5LX&md7 zGUTh8s@DD_d3OaXDY**k%CGA{pWKE1$=`Chx`2CCKu)TC1IuzNV3I~g`vM}UKLUuL|@+rQpO!G_B7878vhc3dl z5}^9JVSAah{VG`Z5382pgliQl~8#1)lp`df?ywLNI^<$ zML#EFtGV|6phkex10qJH>14Tl|J?I6yQl3mqm0T9EQgRhGOTeqr*WW>GQ-TeYe=3C z>jAzRX#)DQjrLQj7Qc5>D#W}W~`okKm|ra?4x}=$QL=yv7N4` zEcCU`x>V)I6Of70!{I{O(BKJlHHPp*K=wQ_46Vxtdo5vv(`pTRJMi(u;R{OHc7NYH zD+)5Q;ISL!T!`>`T_GvTSha`W_)kuH4He4tqxSDsx*I_~9?j`W7YYsIRF6g|0aZo|o_M z{&J->ez1|M7aZWE8}&~t<$X-F&vD1pAJ%5n`d+dUo7-sxXoG>&{c;=aUF8xA_2Qv^ z+7-OdRA9hJo~OiP#ZpN5oJMc=7^6>o_{v2zHhAJ8XRa^XR5DJ8P7I~egJMqMe%0z4BX|6=jk@8dxDYET4>tmh|^lJ5AmC?JK4< zCIOD(z)KQ9=#_J*!uoc>-)~|YMH_c_G03ZT0HG=j7*7+m8akrzP625E`jM|c&@pmG z5WiwcVJRj3YX2mO9?7XpIrV{^dHdQAEh73vUWI@F=+OUT4k>vIYLNo!XMh$-UOEMHX@aLk zs6FC^i@(3JZGTS+28uv|Xear{oF$VM5x%e8t%y8#b8>w7O@r*i|3~BgFX4~!`IGpg zd9BAC3)r4W5uTC|xRP&i_LMb15KsSCWOZ8C`uhpKpa!sxc=7(T4gLwfPzUJs?>6`+ z_&TD0w*iRYdjX98-3HGH-|N4&`L}q#>HK%`e$)By;{6`xZ}Hx!T&dcReNKQEDxxz& zM}MZJ%bSNT@r4qeG%csb5{c1}u*w_H_5@(H0ffK1HF}ue5PA@Ic2cVK4lqVwL9~#< z0>+nrn4htuq>Bc+;d}Do6M6{Ofody2RJ)tNvc%W*P<#&#lLfQ}EKO26e8@zw575Mu z{n%J7$yk5?`nkW!2LAW(Xyz#(EAUUJ-5^CFP&)Wl1%{TUClb!Nvzlog%dh@d>8^yI z)WYJ)%Mkgh%`M9Zy0Wvfug0|#y8@^Bb!gxHB}M49{D5=sgGglmWUu5EIFsG3WQk%w zf$4=Pd$@`@WmMO6_D1H4Fj?Bwf3xDG2%>@B?TmNdDO#`Nk`<}PheTZ~a?kH*#K&2o znD#|UH}=?jG9d}gfhkNDsr(`}f0)tc551px_f#r+^65~K`bFyR?{xvED#L?;Sr8vDNEMb!e%5G*A*7Urp><_? zogKK5#Z)90KJ^aBY^fn?d_FC2H2R=aSvkZJbgRy~x|M?otpi!C1ga6VdKoAyB@Z)z zN?pYa9GCG6AhN-$v(_L*ZkK}cY|sB!#>Rd5mI3I2v<>W)(fUf7}2-Lo60No5g*qBPoS844QN;Gd`2;9iUMcqI;4;y*l*QLHOS~JA zpVq_IGzY^5eM}r#kS#Hvrv~n!T{$2S-VW?{FmOp8>FnNq|$s!Oy3dKtxKWwfhdeL z{jUxMG@02Mxy*cun;%jXK_LKl|(lQcQ8?Wx+Aa*fD3=hy*nl+usY@^ z$6ZxGsq;b|z;Rd=q}TD52=sQ(Ib6XT`qns8ghNc~utoR%stPjF_fO(QhQy7Nmq40~ zT;WZ8`b5rWpz1_IV)KnewInbs#xFVzzWZ^k(ku8(Yi1y>0tlrOqy?NBarqYk3I z@;I2LY)@uw?BjjFKH^Ua!T@I-{{g~T#IeoG05mSO$FrN0TJ7-BtS~fCq2z_ZX5?9v z8GjDbPOsl^KfXLU!-`mmET#Z!Qf}5~#0M@z$#;WV%`KY`z>bQ7@yuU9QTU@Nuq4Qb;#VrGN;e ztXF+mwdg56*T6lZa!8R)u#UE^@=K-E#G_p4Wl5VUoW$5pz^`0`hcqw2YFgOkCAsG# zP$qNl`yf>zpRioS7*O%=5&3aPZo3yqd5Gb{IpH%Qu0T~n$M@eQ{^MAn+IquOOa=_x zv>$qLutr&6LqOwSWhhFx-j-&Y9YwCZ98GnFF`!l(xGg_EHdf?AEJ=^xB8H7D8~5w9 z4kCZl0fC6)>{=z2IQ$-D)aI~!NcNfa(vL3jH4B@E!%TE~`PYG*D4TDiA2+G>Y&cTa zW$&tn@W%iM%Xol?V^MjT5a!dT@{ZleMQTr=@z9?1Um zd=?@mrbm_wh8-#LuceDx`<(|6GaLdZ4EDaV%R|~R>8#xizg=N;`;Q@T?uMog3T$O} zrMdbJokMswYTvB>+ib_;QKULh>KWfQ#P3iEBI7=IKP9B){@DWVhH@2>hNEkoK#rm!0G>*kC^}KU@ z>xFe4jB`4-L`zkN zsXd2v<*XukpIC)&H;aH84zI|W$6pkRVtwliyc_oqhYuVDds(YZ%tUx~Cnb9^xCZLA z8?M5!_&N;`8_?p#9;ZSVrFxUlvEyNY@xXqzG_s zI?hq!tqBNrX1p>RDVaNz1eff^E++@gc z%dVFk68=Vvs)9V)X94~s!!1AU6E#jJ!G34pO4f6H&(#~mg`lR;8Mx?c%WZX)*S1Y+ z&7;HZ`_z~P_r3U=lB`CIi}D5fU1J}4*=?Ufn8gV9p*63+GQLX z`m0{p*FUP{cu5Q?>Fi3p|v?QyGHQ$jsaFAFhzRgF{*&7*V~`^ss64P*-Uw z)9nC0o(h2MzZEF+P3-a-!QZaWGcuU2cO>{f+%D0pt0BP?g!_Mv%gX`IW}Hsc|8Tl^ zG)Rb21`HTxnD|%$KOXQUx%G+_vwynl)lTjzw*l_j8?ykk71|lQx5glBL;PfRr&_%# zNNWH3iuq#v!keD!baqO`dZ#`hpf4p7u=ku+JWrw=qSn34#2;PaOA1t)UzgMf4Yxsb zcZbzajm$yy?gD{>4o{d1=BRWD_Tw#2KL>-~OASkO(5=!bs`J2kyu6DJ)8UapN1{f> zsy)L3%t~<{8kJl(q?s5Qqs#6nTTB=*o)2nkv!#CC#yR@s^FE9#-FVGsVp#|K1HPC0 zb*p{?j#@l$yL-jt8t`XnX3jTi8JdVjGcwksorokb$Yt@DsvLh}=tOzmIqnR)`YEw0 zWrg|UnlU>U*2KtwcZo8n$obIF`@*;o1-IJn3oGqM;hb&pP8C?Jn6jl*u`|wWv$VgbXgh(4K!rP|1g{vA44uX zrYr83lVgDcjqtqF-WNW=Yja-2$Vhlz+C9S0AmKF-0KJ(b0e9qh7_M(0vSnxGMmR{T ztaP`d{jDOxKbVjZe<%u

    rH85dUsXI6j^!Ub4Qo4<|-_*`qdlKSecCWK6cO6Hs*% zN8io)OKWQ6sQP+ik6g?&Ao`sB6-ah=HhO~@SOfh0l|$n` z>0XbprKLwMtF1lofC-w9DLF47y{`GTleIbCZPk4TXUeS*_1Kx3$f- z1#_iTJq|}XIrlDXg`cpu7iixeC2f@)zsZ1fEyC5sHO1k`iNOCZ3r@uDkgt;fzwtrhX|(wN_pc*q bjh~Pxlu>+mpG~xiCn5Vx@oC``1ONX6OW~Zh literal 0 HcmV?d00001 diff --git a/note/spring-mvc.md b/note/spring-mvc.md index 952c92a..5458161 100644 --- a/note/spring-mvc.md +++ b/note/spring-mvc.md @@ -1266,4 +1266,130 @@ WebDataBinderFactory接口用以创建WebDataBinder对象,其继承体系如 protected ServletRequestDataBinder createBinderInstance(Object target, String objectName, NativeWebRequest request) { return new ExtendedServletRequestDataBinder(target, objectName); } -``` \ No newline at end of file +``` + +参数绑定的入口位于ModelAttributeMethodProcessor.resolveArgument方法,相关源码: + +```java +if (!mavContainer.isBindingDisabled(name)) { + bindRequestParameters(binder, webRequest); +} +``` + +接下来由ServletRequestDataBinder的bind方法完成,核心源码: + +```java +public void bind(ServletRequest request) { + MutablePropertyValues mpvs = new ServletRequestParameterPropertyValues(request); + doBind(mpvs); +} +``` + +在ServletRequestParameterPropertyValues构造器中获取了Request中所有的属性对。doBind方法便是调用前面初始化的目标对象的setter方法进行参数设置的过程,不再展开。 + +### 参数校验 + +将我们的Controller方法改写为下面这种形式便可以启动Spring MVC的参数校验: + +```java +@RequestMapping("/echoAgain") +public String echo(@Validated SimpleModel simpleModel, Model model) { + model.addAttribute("echo", "hello " + simpleModel.getName() + ", your age is " + simpleModel.getAge() + "."); + System.out.println(model.asMap().get("simpleModel")); + return "echo"; +} +``` + +在这里@Validated注解可以用@Valid(javax)替换,前者是Spring对java校验标准的扩充,增加了校验组的支持。 +为什么参数校验要放到参数绑定后面进行说明呢,因为**@Validated和@valid注解不会影响Spring MVC参数解析的行为,被这两个注解标注的对象仍是由参数绑定一节提到的解析器进行解析。** + +当参数校验绑定之后,Spring MVC会尝试对参数进行校验,如果我们设置了校验注解。ModelAttributeMethodProcessor.resolveArgument方法相关源码: + +```java +validateIfApplicable(binder, parameter); + +protected void validateIfApplicable(WebDataBinder binder, MethodParameter methodParam) { + Annotation[] annotations = methodParam.getParameterAnnotations(); + for (Annotation ann : annotations) { + Validated validatedAnn = AnnotationUtils.getAnnotation(ann, Validated.class); + if (validatedAnn != null || ann.annotationType().getSimpleName().startsWith("Valid")) { + Object hints = (validatedAnn != null ? validatedAnn.value() : AnnotationUtils.getValue(ann)); + Object[] validationHints = (hints instanceof Object[] ? (Object[]) hints : new Object[] {hints}); + binder.validate(validationHints); + break; + } + } +} +``` + +DataBinder.validate: + +```java +public void validate(Object... validationHints) { + for (Validator validator : getValidators()) { + if (!ObjectUtils.isEmpty(validationHints) && validator instanceof SmartValidator) { + ((SmartValidator) validator).validate(getTarget(), getBindingResult(), validationHints); + } else if (validator != null) { + validator.validate(getTarget(), getBindingResult()); + } + } +} +``` + +可见,具体的校验交给了`org.springframework.validation.Validator`实现,类图: + +![Validator](images/Validator.png) + +getValidators方法获取的实际上是DataBinder内部的validators字段: + +```java +private final List validators = new ArrayList(); +``` + +根据这里的校验器的来源可以分为以下两种情况。 + +#### JSR校验 + +需要引入hibernate-validator到classpath中,回顾最前面配置解析部分,配置: + +```xml + +``` + +会利用AnnotationDrivenBeanDefinitionParser进行相关的解析、初始化工作,正是在其parse方法完成了对JSR校验的支持。相关源码: + +```java +@Override +public BeanDefinition parse(Element element, ParserContext parserContext) { + RuntimeBeanReference validator = getValidator(element, source, parserContext); +} + +private RuntimeBeanReference getValidator(Element element, Object source, ParserContext parserContext) { + //mvc:annotation-driven配置支持validator属性 + if (element.hasAttribute("validator")) { + return new RuntimeBeanReference(element.getAttribute("validator")); + } else if (javaxValidationPresent) { + RootBeanDefinition validatorDef = new RootBeanDefinition( + "org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean"); + validatorDef.setSource(source); + validatorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); + String validatorName = parserContext.getReaderContext().registerWithGeneratedName(validatorDef); + parserContext.registerComponent(new BeanComponentDefinition(validatorDef, validatorName)); + return new RuntimeBeanReference(validatorName); + } else { + return null; + } +} +``` + +javaxValidationPresent的定义: + +```java +private static final boolean javaxValidationPresent = + ClassUtils.isPresent("javax.validation.Validator", AnnotationDrivenBeanDefinitionParser.class.getClassLoader()); +``` + +OptionalValidatorFactoryBean实现了InitializingBean接口,所以afterPropertiesSet方法是其初始化的入口,具体的校验过程不再展开。 + +#### 自定义校验器 + diff --git a/pom.xml b/pom.xml index 0cd09c9..79e112a 100644 --- a/pom.xml +++ b/pom.xml @@ -94,6 +94,12 @@ 3.2.5 + + org.hibernate.validator + hibernate-validator + 6.0.2.Final + + diff --git a/src/main/java/controller/SimpleController.java b/src/main/java/controller/SimpleController.java index 4e0211d..603e546 100644 --- a/src/main/java/controller/SimpleController.java +++ b/src/main/java/controller/SimpleController.java @@ -3,7 +3,7 @@ import model.SimpleModel; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.RequestMapping; /** @@ -21,7 +21,7 @@ public String echo(String name, Model model) { } @RequestMapping("/echoAgain") - public String echo(@ModelAttribute SimpleModel simpleModel, Model model) { + public String echo(@Validated SimpleModel simpleModel, Model model) { model.addAttribute("echo", "hello " + simpleModel.getName() + ", your age is " + simpleModel.getAge() + "."); System.out.println(model.asMap().get("simpleModel")); return "echo"; diff --git a/src/main/java/model/SimpleModel.java b/src/main/java/model/SimpleModel.java index 6994a8a..fee1282 100644 --- a/src/main/java/model/SimpleModel.java +++ b/src/main/java/model/SimpleModel.java @@ -1,5 +1,7 @@ package model; +import javax.validation.constraints.NotBlank; + /** * 简单的model. * @@ -7,6 +9,7 @@ */ public class SimpleModel { + @NotBlank private String name; private Integer age; diff --git a/src/main/java/validator/SimpleModelValidator.java b/src/main/java/validator/SimpleModelValidator.java new file mode 100644 index 0000000..9e8c8c0 --- /dev/null +++ b/src/main/java/validator/SimpleModelValidator.java @@ -0,0 +1,7 @@ +package validator; + +/** + * @author skywalker + */ +public class SimpleModelValidator { +} From d4714dee263e9f865dc11e431e159a880751e96e Mon Sep 17 00:00:00 2001 From: skywalker Date: Sat, 16 Sep 2017 21:53:20 +0800 Subject: [PATCH 06/20] =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=E6=A0=A1?= =?UTF-8?q?=E9=AA=8C=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- note/spring-mvc.md | 44 ++++++++++++++++++- pom.xml | 4 +- .../java/controller/SimpleController.java | 15 ++++++- src/main/java/model/SimpleModel.java | 3 -- .../java/validator/SimpleModelValidator.java | 23 +++++++++- 5 files changed, 80 insertions(+), 9 deletions(-) diff --git a/note/spring-mvc.md b/note/spring-mvc.md index 5458161..e51dabc 100644 --- a/note/spring-mvc.md +++ b/note/spring-mvc.md @@ -1389,7 +1389,49 @@ private static final boolean javaxValidationPresent = ClassUtils.isPresent("javax.validation.Validator", AnnotationDrivenBeanDefinitionParser.class.getClassLoader()); ``` -OptionalValidatorFactoryBean实现了InitializingBean接口,所以afterPropertiesSet方法是其初始化的入口,具体的校验过程不再展开。 + 实现了InitializingBean接口,所以afterPropertiesSet方法是其初始化的入口,具体的校验过程不再展开。 + 除此之外还有一个有意思的问题,就是上面提到的校验器是如何进入到DataBinder中去的呢?答案是WebDataBinderFactory创建DataBinder对象时会利用WebBindingInitializer对DataBinder进行初始化,正是在这里 + 将容器中存在的校验器设置到DataBinder中,至于WebBindingInitializer又是从哪里来的,不再探究了,否则这细节实在是太麻烦了,意义不大。 #### 自定义校验器 +我们可以实现Spring提供的Validator接口,然后在Controller里边这样设置我们要是用的校验器: + +```java +@InitBinder +public void initBinder(DataBinder dataBinder) { + dataBinder.setValidator(new SimpleModelValidator()); + //如果有多个可以使用setValidators方法 +} +``` + +我们的Controller方法依然可以如此定义: + +```java +@RequestMapping("/echoAgain") +public String echo(@Validated SimpleModel simpleModel, Model model) { + return "echo"; +} +``` + +如果有错误,会直接返回400. + +#### 一个有意思的问题 + +如果我们把Controller方法这样定义会怎样? + +```java +@RequestMapping(value = "/echoAgain", method = RequestMethod.POST) +public String echo(@Validated @RequestBody SimpleModel simpleModel, Model model) {} +``` + +答案是@RequestBody注解根本就没有起作用?why? + +RequestMappingHandlerAdapter.getDefaultArgumentResolvers相关源码: + +```java +resolvers.add(new ServletModelAttributeMethodProcessor(false)); +resolvers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice)); +``` + +仅仅就是因为ServletModelAttributeMethodProcessor的声明比RequestResponseBodyMethodProcessor早了一行! \ No newline at end of file diff --git a/pom.xml b/pom.xml index 79e112a..7077852 100644 --- a/pom.xml +++ b/pom.xml @@ -94,11 +94,11 @@ 3.2.5 - + diff --git a/src/main/java/controller/SimpleController.java b/src/main/java/controller/SimpleController.java index 603e546..15a4b7b 100644 --- a/src/main/java/controller/SimpleController.java +++ b/src/main/java/controller/SimpleController.java @@ -3,8 +3,13 @@ import model.SimpleModel; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; +import org.springframework.validation.DataBinder; import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.InitBinder; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import validator.SimpleModelValidator; /** * 简单的Spring {@link org.springframework.stereotype.Controller}. @@ -14,14 +19,20 @@ @Controller public class SimpleController { + @InitBinder + public void initBinder(DataBinder dataBinder) { + //dataBinder.setValidator(new SimpleModelValidator()); + dataBinder.addValidators(new SimpleModelValidator()); + } + @RequestMapping("/echo") public String echo(String name, Model model) { model.addAttribute("echo", "hello " + name); return "echo"; } - @RequestMapping("/echoAgain") - public String echo(@Validated SimpleModel simpleModel, Model model) { + @RequestMapping(value = "/echoAgain", method = RequestMethod.POST) + public String echo(@Validated @RequestBody SimpleModel simpleModel, Model model) { model.addAttribute("echo", "hello " + simpleModel.getName() + ", your age is " + simpleModel.getAge() + "."); System.out.println(model.asMap().get("simpleModel")); return "echo"; diff --git a/src/main/java/model/SimpleModel.java b/src/main/java/model/SimpleModel.java index fee1282..6994a8a 100644 --- a/src/main/java/model/SimpleModel.java +++ b/src/main/java/model/SimpleModel.java @@ -1,7 +1,5 @@ package model; -import javax.validation.constraints.NotBlank; - /** * 简单的model. * @@ -9,7 +7,6 @@ */ public class SimpleModel { - @NotBlank private String name; private Integer age; diff --git a/src/main/java/validator/SimpleModelValidator.java b/src/main/java/validator/SimpleModelValidator.java index 9e8c8c0..53bd23b 100644 --- a/src/main/java/validator/SimpleModelValidator.java +++ b/src/main/java/validator/SimpleModelValidator.java @@ -1,7 +1,28 @@ package validator; +import model.SimpleModel; +import org.springframework.validation.Errors; +import org.springframework.validation.Validator; + /** + * 自定义Spring校验器. + * * @author skywalker */ -public class SimpleModelValidator { +public class SimpleModelValidator implements Validator { + + @Override + public boolean supports(Class clazz) { + return (clazz == SimpleModel.class); + } + + @Override + public void validate(Object target, Errors errors) { + SimpleModel simpleModel = (SimpleModel) target; + Integer age = simpleModel.getAge(); + if (age == null || age < 1 || age > 200) { + errors.reject("100", "年龄不合法"); + } + } + } From 9dcf03b7aa0a4995125d9d82e1165bff53390bb0 Mon Sep 17 00:00:00 2001 From: skywalker Date: Sat, 16 Sep 2017 21:56:34 +0800 Subject: [PATCH 07/20] setValidators -> addValidators --- note/spring-mvc.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/note/spring-mvc.md b/note/spring-mvc.md index e51dabc..9a060e5 100644 --- a/note/spring-mvc.md +++ b/note/spring-mvc.md @@ -1401,7 +1401,7 @@ private static final boolean javaxValidationPresent = @InitBinder public void initBinder(DataBinder dataBinder) { dataBinder.setValidator(new SimpleModelValidator()); - //如果有多个可以使用setValidators方法 + //如果有多个可以使用addValidators方法 } ``` From e65834fe9d4ff5a09b9f3da95fbea73239a067e7 Mon Sep 17 00:00:00 2001 From: skywalker Date: Thu, 21 Sep 2017 20:08:22 +0800 Subject: [PATCH 08/20] spring-boot begin --- note/flows/spring_application_run.gliffy | 1 + note/images/ApplicationContextInitializer.png | Bin 0 -> 19319 bytes note/images/ApplicationListener.png | Bin 0 -> 5047 bytes note/images/ApplicationListener_used.png | Bin 0 -> 27988 bytes note/images/SpringApplicationRunListener.png | Bin 0 -> 5271 bytes note/images/spring_application_run.png | Bin 0 -> 38313 bytes note/spring-boot.md | 108 ++++++++++++++++++ note/spring-boot.uml | 71 ++++++++++++ 8 files changed, 180 insertions(+) create mode 100644 note/flows/spring_application_run.gliffy create mode 100644 note/images/ApplicationContextInitializer.png create mode 100644 note/images/ApplicationListener.png create mode 100644 note/images/ApplicationListener_used.png create mode 100644 note/images/SpringApplicationRunListener.png create mode 100644 note/images/spring_application_run.png create mode 100644 note/spring-boot.md create mode 100644 note/spring-boot.uml diff --git a/note/flows/spring_application_run.gliffy b/note/flows/spring_application_run.gliffy new file mode 100644 index 0000000..7b7d4de --- /dev/null +++ b/note/flows/spring_application_run.gliffy @@ -0,0 +1 @@ +{"contentType":"application/gliffy+json","version":"1.1","metadata":{"title":"untitled","revision":0,"exportBorder":false},"embeddedResources":{"index":0,"resources":[]},"stage":{"objects":[{"x":541,"y":993,"rotation":0,"id":61,"uid":"com.gliffy.shape.basic.basic_v1.default.line","width":100,"height":100,"lockAspectRatio":false,"lockShape":false,"order":61,"graphic":{"type":"Line","Line":{"strokeWidth":2,"strokeColor":"#0B599F","fillColor":"none","dashStyle":null,"startArrow":0,"endArrow":2,"startArrowRotation":"auto","endArrowRotation":"auto","ortho":true,"interpolationType":"linear","cornerRadius":null,"controlPath":[[-1,-3],[-1,32],[306,32],[306,67]],"lockSegments":{}}},"children":null,"constraints":{"constraints":[],"startConstraint":{"type":"StartPositionConstraint","StartPositionConstraint":{"nodeId":55,"px":0.5,"py":1}},"endConstraint":{"type":"EndPositionConstraint","EndPositionConstraint":{"nodeId":58,"px":0.5,"py":0}}},"linkMap":[]},{"x":797,"y":1060,"rotation":0,"id":58,"uid":"com.gliffy.shape.flowchart.flowchart_v1.default.start_end","width":100,"height":40,"lockAspectRatio":false,"lockShape":false,"order":58,"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.start_end.flowchart_v1","strokeWidth":2,"strokeColor":"#990000","fillColor":"#990000","gradient":false,"dropShadow":false,"state":0,"shadowX":0,"shadowY":0,"opacity":1}},"children":[{"x":2,"y":0,"rotation":0,"id":60,"uid":null,"width":96,"height":20,"lockAspectRatio":false,"lockShape":false,"order":"auto","graphic":{"type":"Text","Text":{"tid":null,"valign":"middle","overflow":"none","vposition":"none","hposition":"none","html":"

    finished

    ","paddingLeft":2,"paddingRight":2,"paddingBottom":2,"paddingTop":2}},"children":null}],"linkMap":[]},{"x":544,"y":900,"rotation":0,"id":57,"uid":"com.gliffy.shape.basic.basic_v1.default.line","width":100,"height":100,"lockAspectRatio":false,"lockShape":false,"order":57,"graphic":{"type":"Line","Line":{"strokeWidth":2,"strokeColor":"#0B599F","fillColor":"none","dashStyle":null,"startArrow":0,"endArrow":2,"startArrowRotation":"auto","endArrowRotation":"auto","ortho":false,"interpolationType":"linear","cornerRadius":null,"controlPath":[[-4,0],[-4,50]],"lockSegments":{}}},"children":null,"constraints":{"constraints":[],"startConstraint":{"type":"StartPositionConstraint","StartPositionConstraint":{"nodeId":52,"px":0.5,"py":1}},"endConstraint":{"type":"EndPositionConstraint","EndPositionConstraint":{"nodeId":55,"px":0.5,"py":0}}},"linkMap":[]},{"x":853,"y":820,"rotation":0,"id":54,"uid":"com.gliffy.shape.basic.basic_v1.default.line","width":100,"height":100,"lockAspectRatio":false,"lockShape":false,"order":33,"graphic":{"type":"Line","Line":{"strokeWidth":2,"strokeColor":"#0B599F","fillColor":"none","dashStyle":null,"startArrow":0,"endArrow":2,"startArrowRotation":"auto","endArrowRotation":"auto","ortho":true,"interpolationType":"linear","cornerRadius":null,"controlPath":[[-6,0],[-6,20],[-313,20],[-313,40]],"lockSegments":{}}},"children":null,"constraints":{"constraints":[],"startConstraint":{"type":"StartPositionConstraint","StartPositionConstraint":{"nodeId":49,"px":0.5,"py":1}},"endConstraint":{"type":"EndPositionConstraint","EndPositionConstraint":{"nodeId":52,"px":0.5,"py":0}}},"linkMap":[]},{"x":849,"y":739,"rotation":0,"id":51,"uid":"com.gliffy.shape.basic.basic_v1.default.line","width":100,"height":100,"lockAspectRatio":false,"lockShape":false,"order":30,"graphic":{"type":"Line","Line":{"strokeWidth":2,"strokeColor":"#0B599F","fillColor":"none","dashStyle":null,"startArrow":0,"endArrow":2,"startArrowRotation":"auto","endArrowRotation":"auto","ortho":false,"interpolationType":"linear","cornerRadius":null,"controlPath":[[-2,1],[-2,41]],"lockSegments":{}}},"children":null,"constraints":{"constraints":[],"startConstraint":{"type":"StartPositionConstraint","StartPositionConstraint":{"nodeId":45,"px":0.5,"py":1}},"endConstraint":{"type":"EndPositionConstraint","EndPositionConstraint":{"nodeId":49,"px":0.5,"py":0}}},"linkMap":[]},{"x":539,"y":661,"rotation":0,"id":47,"uid":"com.gliffy.shape.basic.basic_v1.default.line","width":100,"height":100,"lockAspectRatio":false,"lockShape":false,"order":27,"graphic":{"type":"Line","Line":{"strokeWidth":2,"strokeColor":"#0B599F","fillColor":"none","dashStyle":null,"startArrow":0,"endArrow":2,"startArrowRotation":"auto","endArrowRotation":"auto","ortho":true,"interpolationType":"linear","cornerRadius":null,"controlPath":[[1,-1],[1,19],[308,19],[308,39]],"lockSegments":{}}},"children":null,"constraints":{"constraints":[],"startConstraint":{"type":"StartPositionConstraint","StartPositionConstraint":{"nodeId":35,"px":0.5,"py":1}},"endConstraint":{"type":"EndPositionConstraint","EndPositionConstraint":{"nodeId":45,"px":0.5,"py":0}}},"linkMap":[]},{"x":848,"y":414,"rotation":0,"id":43,"uid":"com.gliffy.shape.basic.basic_v1.default.line","width":100,"height":100,"lockAspectRatio":false,"lockShape":false,"order":24,"graphic":{"type":"Line","Line":{"strokeWidth":2,"strokeColor":"#0B599F","fillColor":"none","dashStyle":null,"startArrow":0,"endArrow":2,"startArrowRotation":"auto","endArrowRotation":"auto","ortho":true,"interpolationType":"linear","cornerRadius":null,"controlPath":[[-1,-4],[-1,16],[-308,16],[-308,36]],"lockSegments":{}}},"children":null,"constraints":{"constraints":[],"startConstraint":{"type":"StartPositionConstraint","StartPositionConstraint":{"nodeId":38,"px":0.5,"py":1}},"endConstraint":{"type":"EndPositionConstraint","EndPositionConstraint":{"nodeId":26,"px":0.5,"py":0}}},"linkMap":[]},{"x":542,"y":325,"rotation":0,"id":41,"uid":"com.gliffy.shape.basic.basic_v1.default.line","width":100,"height":100,"lockAspectRatio":false,"lockShape":false,"order":23,"graphic":{"type":"Line","Line":{"strokeWidth":2,"strokeColor":"#0B599F","fillColor":"none","dashStyle":null,"startArrow":0,"endArrow":2,"startArrowRotation":"auto","endArrowRotation":"auto","ortho":true,"interpolationType":"linear","cornerRadius":null,"controlPath":[[-2,-5],[-2,20],[305,20],[305,45]],"lockSegments":{}}},"children":null,"constraints":{"constraints":[],"startConstraint":{"type":"StartPositionConstraint","StartPositionConstraint":{"nodeId":21,"px":0.5,"py":1}},"endConstraint":{"type":"EndPositionConstraint","EndPositionConstraint":{"nodeId":38,"px":0.5,"py":0}}},"linkMap":[]},{"x":847,"y":236,"rotation":0,"id":24,"uid":"com.gliffy.shape.basic.basic_v1.default.line","width":100,"height":100,"lockAspectRatio":false,"lockShape":false,"order":12,"graphic":{"type":"Line","Line":{"strokeWidth":2,"strokeColor":"#0B599F","fillColor":"none","dashStyle":null,"startArrow":0,"endArrow":2,"startArrowRotation":"auto","endArrowRotation":"auto","ortho":true,"interpolationType":"linear","cornerRadius":null,"controlPath":[[0,-6],[0,19],[-307,19],[-307,44]],"lockSegments":{}}},"children":null,"constraints":{"constraints":[],"startConstraint":{"type":"StartPositionConstraint","StartPositionConstraint":{"nodeId":12,"px":0.5,"py":1}},"endConstraint":{"type":"EndPositionConstraint","EndPositionConstraint":{"nodeId":21,"px":0.5,"py":0}}},"linkMap":[]},{"x":490,"y":280,"rotation":0,"id":21,"uid":"com.gliffy.shape.flowchart.flowchart_v1.default.process","width":100,"height":40,"lockAspectRatio":false,"lockShape":false,"order":10,"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.rectangle.basic_v1","strokeWidth":2,"strokeColor":"#0B599F","fillColor":"#1c4587","gradient":false,"dropShadow":false,"state":0,"shadowX":0,"shadowY":0,"opacity":1}},"children":[{"x":2,"y":0,"rotation":0,"id":23,"uid":null,"width":96,"height":20,"lockAspectRatio":false,"lockShape":false,"order":"auto","graphic":{"type":"Text","Text":{"tid":null,"valign":"middle","overflow":"none","vposition":"none","hposition":"none","html":"

    环境准备

    ","paddingLeft":2,"paddingRight":2,"paddingBottom":2,"paddingTop":2}},"children":null}],"linkMap":[]},{"x":851,"y":191,"rotation":0,"id":19,"uid":"com.gliffy.shape.basic.basic_v1.default.line","width":100,"height":100,"lockAspectRatio":false,"lockShape":false,"order":9,"graphic":{"type":"Line","Line":{"strokeWidth":2,"strokeColor":"#0B599F","fillColor":"none","dashStyle":null,"startArrow":2,"endArrow":0,"startArrowRotation":"auto","endArrowRotation":"auto","ortho":true,"interpolationType":"linear","cornerRadius":null,"controlPath":[[-4,-1],[-4,-21],[-311,-21],[-311,-41]],"lockSegments":{}}},"children":null,"constraints":{"constraints":[],"startConstraint":{"type":"StartPositionConstraint","StartPositionConstraint":{"nodeId":12,"px":0.5,"py":0}},"endConstraint":{"type":"EndPositionConstraint","EndPositionConstraint":{"nodeId":9,"px":0.5,"py":1}}},"linkMap":[]},{"x":797,"y":190,"rotation":0,"id":12,"uid":"com.gliffy.shape.flowchart.flowchart_v1.default.process","width":100,"height":40,"lockAspectRatio":false,"lockShape":false,"order":7,"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.rectangle.basic_v1","strokeWidth":2,"strokeColor":"#ffffff","fillColor":"#990000","gradient":false,"dropShadow":false,"state":0,"shadowX":0,"shadowY":0,"opacity":1}},"children":[{"x":2,"y":0,"rotation":0,"id":14,"uid":null,"width":96,"height":27,"lockAspectRatio":false,"lockShape":false,"order":"auto","graphic":{"type":"Text","Text":{"tid":null,"valign":"middle","overflow":"none","vposition":"none","hposition":"none","html":"

    starting

    ","paddingLeft":2,"paddingRight":2,"paddingBottom":2,"paddingTop":2}},"children":null}],"linkMap":[]},{"x":490,"y":120,"rotation":0,"id":9,"uid":"com.gliffy.shape.flowchart.flowchart_v1.default.start_end","width":100,"height":30,"lockAspectRatio":false,"lockShape":false,"order":5,"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.start_end.flowchart_v1","strokeWidth":2,"strokeColor":"#0B599F","fillColor":"#0B599F","gradient":false,"dropShadow":false,"state":0,"shadowX":0,"shadowY":0,"opacity":1}},"children":[{"x":2,"y":0,"rotation":0,"id":11,"uid":null,"width":96,"height":20,"lockAspectRatio":false,"lockShape":false,"order":"auto","graphic":{"type":"Text","Text":{"tid":null,"valign":"middle","overflow":"none","vposition":"none","hposition":"none","html":"

    进入

    ","paddingLeft":2,"paddingRight":2,"paddingBottom":2,"paddingTop":2}},"children":null}],"linkMap":[]},{"x":436,"y":80,"rotation":0,"id":5,"uid":"com.gliffy.shape.basic.basic_v1.default.text","width":231,"height":20,"lockAspectRatio":false,"lockShape":false,"order":2,"graphic":{"type":"Text","Text":{"tid":null,"valign":"middle","overflow":"none","vposition":"none","hposition":"none","html":"

    SpringApplication

    ","paddingLeft":2,"paddingRight":2,"paddingBottom":2,"paddingTop":2}},"children":null,"linkMap":[]},{"x":390,"y":82,"rotation":0,"id":1,"uid":"com.gliffy.shape.basic.basic_v1.default.line","width":100,"height":100,"lockAspectRatio":false,"lockShape":false,"order":0,"graphic":{"type":"Line","Line":{"strokeWidth":2,"strokeColor":"#0B599F","fillColor":"none","dashStyle":"4.0,4.0","startArrow":0,"endArrow":0,"startArrowRotation":"auto","endArrowRotation":"auto","ortho":false,"interpolationType":"linear","cornerRadius":0,"controlPath":[[0,0],[2.8421709430404007e-13,1062.0169490172932]],"lockSegments":{}}},"children":null,"linkMap":[]},{"x":690,"y":82,"rotation":0,"id":4,"uid":"com.gliffy.shape.basic.basic_v1.default.line","width":100,"height":100,"lockAspectRatio":false,"lockShape":false,"order":1,"graphic":{"type":"Line","Line":{"strokeWidth":2,"strokeColor":"#0B599F","fillColor":"none","dashStyle":"4.0,4.0","startArrow":0,"endArrow":0,"startArrowRotation":"auto","endArrowRotation":"auto","ortho":false,"interpolationType":"linear","cornerRadius":0,"controlPath":[[0,0],[0,1067.0074976306398]],"lockSegments":{}}},"children":null,"linkMap":[]},{"x":987,"y":87,"rotation":0,"id":7,"uid":"com.gliffy.shape.basic.basic_v1.default.line","width":100,"height":100,"lockAspectRatio":false,"lockShape":false,"order":3,"graphic":{"type":"Line","Line":{"strokeWidth":2,"strokeColor":"#0B599F","fillColor":"none","dashStyle":"4.0,4.0","startArrow":0,"endArrow":0,"startArrowRotation":"auto","endArrowRotation":"auto","ortho":false,"interpolationType":"linear","cornerRadius":0,"controlPath":[[0,0],[-1.1368683772161603e-13,1051.0171264066062]],"lockSegments":{}}},"children":null,"linkMap":[]},{"x":720,"y":70,"rotation":0,"id":8,"uid":"com.gliffy.shape.basic.basic_v1.default.text","width":250.00000000000003,"height":40,"lockAspectRatio":false,"lockShape":false,"order":4,"graphic":{"type":"Text","Text":{"tid":null,"valign":"middle","overflow":"none","vposition":"none","hposition":"none","html":"

    SpringApplicationRunListener

    ","paddingLeft":2,"paddingRight":2,"paddingBottom":2,"paddingTop":2}},"children":null,"linkMap":[]},{"x":722,"y":370,"rotation":0,"id":38,"uid":"com.gliffy.shape.flowchart.flowchart_v1.default.process","width":250,"height":40,"lockAspectRatio":false,"lockShape":false,"order":21,"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.rectangle.basic_v1","strokeWidth":2,"strokeColor":"#ffffff","fillColor":"#990000","gradient":false,"dropShadow":false,"state":0,"shadowX":0,"shadowY":0,"opacity":1}},"children":[{"x":4.999999999999998,"y":0,"rotation":0,"id":39,"uid":null,"width":239.99999999999997,"height":27,"lockAspectRatio":false,"lockShape":false,"order":"auto","graphic":{"type":"Text","Text":{"tid":null,"valign":"middle","overflow":"none","vposition":"none","hposition":"none","html":"

    environmentPrepared

    ","paddingLeft":2,"paddingRight":2,"paddingBottom":2,"paddingTop":2}},"children":null}],"linkMap":[]},{"x":541,"y":583,"rotation":0,"id":37,"uid":"com.gliffy.shape.basic.basic_v1.default.line","width":100,"height":100,"lockAspectRatio":false,"lockShape":false,"order":20,"graphic":{"type":"Line","Line":{"strokeWidth":2,"strokeColor":"#0B599F","fillColor":"none","dashStyle":null,"startArrow":0,"endArrow":2,"startArrowRotation":"auto","endArrowRotation":"auto","ortho":false,"interpolationType":"linear","cornerRadius":null,"controlPath":[[-1,-3],[-1,37]],"lockSegments":{}}},"children":null,"constraints":{"constraints":[],"startConstraint":{"type":"StartPositionConstraint","StartPositionConstraint":{"nodeId":31,"px":0.5,"py":1}},"endConstraint":{"type":"EndPositionConstraint","EndPositionConstraint":{"nodeId":35,"px":0.5,"py":0}}},"linkMap":[]},{"x":480,"y":620,"rotation":0,"id":35,"uid":"com.gliffy.shape.flowchart.flowchart_v1.default.process","width":120,"height":40,"lockAspectRatio":false,"lockShape":false,"order":18,"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.rectangle.basic_v1","strokeWidth":2,"strokeColor":"#0B599F","fillColor":"#1c4587","gradient":false,"dropShadow":false,"state":0,"shadowX":0,"shadowY":0,"opacity":1}},"children":[{"x":2.4,"y":0,"rotation":0,"id":36,"uid":null,"width":115.19999999999999,"height":20,"lockAspectRatio":false,"lockShape":false,"order":"auto","graphic":{"type":"Text","Text":{"tid":null,"valign":"middle","overflow":"none","vposition":"none","hposition":"none","html":"

    context准备

    ","paddingLeft":2,"paddingRight":2,"paddingBottom":2,"paddingTop":2}},"children":null}],"linkMap":[]},{"x":542,"y":494,"rotation":0,"id":33,"uid":"com.gliffy.shape.basic.basic_v1.default.line","width":100,"height":100,"lockAspectRatio":false,"lockShape":false,"order":17,"graphic":{"type":"Line","Line":{"strokeWidth":2,"strokeColor":"#0B599F","fillColor":"none","dashStyle":null,"startArrow":0,"endArrow":2,"startArrowRotation":"auto","endArrowRotation":"auto","ortho":false,"interpolationType":"linear","cornerRadius":null,"controlPath":[[-2,-4],[-2,46]],"lockSegments":{}}},"children":null,"constraints":{"constraints":[],"startConstraint":{"type":"StartPositionConstraint","StartPositionConstraint":{"nodeId":26,"px":0.5,"py":1}},"endConstraint":{"type":"EndPositionConstraint","EndPositionConstraint":{"nodeId":31,"px":0.5,"py":0}}},"linkMap":[]},{"x":480,"y":540,"rotation":0,"id":31,"uid":"com.gliffy.shape.flowchart.flowchart_v1.default.process","width":120,"height":40,"lockAspectRatio":false,"lockShape":false,"order":15,"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.rectangle.basic_v1","strokeWidth":2,"strokeColor":"#0B599F","fillColor":"#1c4587","gradient":false,"dropShadow":false,"state":0,"shadowX":0,"shadowY":0,"opacity":1}},"children":[{"x":2.4,"y":0,"rotation":0,"id":32,"uid":null,"width":115.19999999999999,"height":20,"lockAspectRatio":false,"lockShape":false,"order":"auto","graphic":{"type":"Text","Text":{"tid":null,"valign":"middle","overflow":"none","vposition":"none","hposition":"none","html":"

    context创建

    ","paddingLeft":2,"paddingRight":2,"paddingBottom":2,"paddingTop":2}},"children":null}],"linkMap":[]},{"x":480,"y":450,"rotation":0,"id":26,"uid":"com.gliffy.shape.flowchart.flowchart_v1.default.process","width":120,"height":40,"lockAspectRatio":false,"lockShape":false,"order":13,"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.rectangle.basic_v1","strokeWidth":2,"strokeColor":"#0B599F","fillColor":"#1c4587","gradient":false,"dropShadow":false,"state":0,"shadowX":0,"shadowY":0,"opacity":1}},"children":[{"x":2.4,"y":0,"rotation":0,"id":27,"uid":null,"width":115.19999999999999,"height":20,"lockAspectRatio":false,"lockShape":false,"order":"auto","graphic":{"type":"Text","Text":{"tid":null,"valign":"middle","overflow":"none","vposition":"none","hposition":"none","html":"

    Banner打印

    ","paddingLeft":2,"paddingRight":2,"paddingBottom":2,"paddingTop":2}},"children":null}],"linkMap":[]},{"x":737,"y":700,"rotation":0,"id":45,"uid":"com.gliffy.shape.flowchart.flowchart_v1.default.process","width":220,"height":40,"lockAspectRatio":false,"lockShape":false,"order":25,"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.rectangle.basic_v1","strokeWidth":2,"strokeColor":"#ffffff","fillColor":"#990000","gradient":false,"dropShadow":false,"state":0,"shadowX":0,"shadowY":0,"opacity":1}},"children":[{"x":4.399999999999999,"y":0,"rotation":0,"id":46,"uid":null,"width":211.2,"height":27,"lockAspectRatio":false,"lockShape":false,"order":"auto","graphic":{"type":"Text","Text":{"tid":null,"valign":"middle","overflow":"none","vposition":"none","hposition":"none","html":"

    contextPrepared

    ","paddingLeft":2,"paddingRight":2,"paddingBottom":2,"paddingTop":2}},"children":null}],"linkMap":[]},{"x":737,"y":780,"rotation":0,"id":49,"uid":"com.gliffy.shape.flowchart.flowchart_v1.default.process","width":220,"height":40,"lockAspectRatio":false,"lockShape":false,"order":28,"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.rectangle.basic_v1","strokeWidth":2,"strokeColor":"#ffffff","fillColor":"#990000","gradient":false,"dropShadow":false,"state":0,"shadowX":0,"shadowY":0,"opacity":1}},"children":[{"x":4.399999999999999,"y":0,"rotation":0,"id":50,"uid":null,"width":211.2,"height":27,"lockAspectRatio":false,"lockShape":false,"order":"auto","graphic":{"type":"Text","Text":{"tid":null,"valign":"middle","overflow":"none","vposition":"none","hposition":"none","html":"

    contextLoaded

    ","paddingLeft":2,"paddingRight":2,"paddingBottom":2,"paddingTop":2}},"children":null}],"linkMap":[]},{"x":470,"y":860,"rotation":0,"id":52,"uid":"com.gliffy.shape.flowchart.flowchart_v1.default.process","width":140,"height":40,"lockAspectRatio":false,"lockShape":false,"order":31,"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.rectangle.basic_v1","strokeWidth":2,"strokeColor":"#0B599F","fillColor":"#1c4587","gradient":false,"dropShadow":false,"state":0,"shadowX":0,"shadowY":0,"opacity":1}},"children":[{"x":2.8000000000000003,"y":0,"rotation":0,"id":53,"uid":null,"width":134.4,"height":20,"lockAspectRatio":false,"lockShape":false,"order":"auto","graphic":{"type":"Text","Text":{"tid":null,"valign":"middle","overflow":"none","vposition":"none","hposition":"none","html":"

    refreshContext

    ","paddingLeft":2,"paddingRight":2,"paddingBottom":2,"paddingTop":2}},"children":null}],"linkMap":[]},{"x":470,"y":950,"rotation":0,"id":55,"uid":"com.gliffy.shape.flowchart.flowchart_v1.default.process","width":140,"height":40,"lockAspectRatio":false,"lockShape":false,"order":35,"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.rectangle.basic_v1","strokeWidth":2,"strokeColor":"#0B599F","fillColor":"#1c4587","gradient":false,"dropShadow":false,"state":0,"shadowX":0,"shadowY":0,"opacity":1}},"children":[{"x":2.8000000000000003,"y":0,"rotation":0,"id":56,"uid":null,"width":134.4,"height":20,"lockAspectRatio":false,"lockShape":false,"order":"auto","graphic":{"type":"Text","Text":{"tid":null,"valign":"middle","overflow":"none","vposition":"none","hposition":"none","html":"

    runner调用

    ","paddingLeft":2,"paddingRight":2,"paddingBottom":2,"paddingTop":2}},"children":null}],"linkMap":[]}],"background":"#FFFFFF","width":992,"height":1154,"maxWidth":5000,"maxHeight":5000,"nodeIndex":62,"autoFit":true,"exportBorder":false,"gridOn":true,"snapToGrid":true,"drawingGuidesOn":true,"pageBreaksOn":false,"printGridOn":false,"printPaper":"LETTER","printShrinkToFit":false,"printPortrait":true,"shapeStyles":{"com.gliffy.shape.flowchart.flowchart_v1.default":{"fill":"#990000","stroke":"#990000","strokeWidth":2}},"lineStyles":{"global":{"stroke":"#0B599F","strokeWidth":2,"dashStyle":null,"orthoMode":0,"fill":"none","startArrow":0,"endArrow":2}},"textStyles":{},"themeData":{"uid":"com.gliffy.theme.blueprint","name":"Blueprint","shape":{"primary":{"strokeWidth":2,"strokeColor":"#0B599F","fillColor":"#DDE6F1","gradient":false,"dropShadow":false,"opacity":1,"text":{"color":"#08233F","bold":null,"italic":null,"underline":null}},"secondary":{"strokeWidth":2,"strokeColor":"#08233F","fillColor":"#424D76","gradient":false,"dropShadow":false,"opacity":1,"text":{"color":"#FFFFFF","bold":null,"italic":null,"underline":null}},"tertiary":{"strokeWidth":2,"strokeColor":"#0B599F","fillColor":"#FFFFFF","gradient":false,"dropShadow":false,"opacity":1,"text":{"color":"#08233F","bold":null,"italic":null,"underline":null}},"highlight":{"strokeWidth":2,"strokeColor":"#0B599F","fillColor":"#0B599F","gradient":false,"dropShadow":false,"opacity":1,"text":{"color":"#ffffff","bold":null,"italic":null,"underline":null}}},"line":{"strokeWidth":2,"strokeColor":"#0B599F","fillColor":"none","arrowType":2,"interpolationType":"linear","cornerRadius":0,"text":{"color":"#08233F","bold":null,"italic":null,"underline":null}},"text":{"color":"#08233F","bold":null,"italic":null,"underline":null},"stage":{"color":"#FFFFFF"}}}} \ No newline at end of file diff --git a/note/images/ApplicationContextInitializer.png b/note/images/ApplicationContextInitializer.png new file mode 100644 index 0000000000000000000000000000000000000000..74ce92898776315b8cffa023dda6914ee7d9446f GIT binary patch literal 19319 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

    EPkSwi)6*Lr_cg==S8aXpp z%7UDRlP$5c!H?$3k%Y}%CtiFXpb8=33gadoc`guBGPWi-W*NHdJNQlw{7x{8_GR2k zDHCD&^O=yeg8Y&qe9@zW^yRGu8fMT3$eh89h1X5PmHy?8NL=%1Im=teyiilmIt8}r-Z=|BaUII=I){wk96RLu=8!~PYVf4Z^vDC zMQ!^tQ1z!K?A}NFo0g@-ZELk0RMT@JTHDhfgBmj|;2655(6x z8E8)!q{m_tOD{B1ZK8r{?ln@N3QrcCQtD-qyeJ5`C_nrLp!f9@^KN{Z-qg|$uosO) z%dDfcyLqXcvOlY_o~i@+oZ3h!zADjh-3ogLSR9dm%{e94x_ZG;q`;4Fi#fP?6lPfJ z3i4S=>KL0c(=P|I0=r#{N(P&w94RKd3ql@FlHnE&bdsM=BbflWzRz{7``6Qk*I5;| z5}rJ$cgOgq@$`G-r+i>t4O%36HKuuW^Q9(zrA7azlVMTJQ&MpM} zk?W~A>TS&opz^5hg|uCHtWLo;x=*I^;4UUG__UCfB&9~(7++0fXpZ{PSr>groGY}A zJyuRJzPaaz29N4T@?H)#FQ;7gscRGCK`MjPK3}=vnB2m`%Sop)EX~V;!L!{h`q+=s zQ<~EmXRpi`HbyOq)(FM#&h1y@%95Sg0*ooG)&hC%q2wVcz1~ZA#oCghnUbMizeSfz z=Qj-;sEt;Tr3{s;lZn9o6wvtPH^H*yHd2Q*`vtzev2FvgnzPTbe$c5LupjpNOm4DV zJK%zMu_j89lIWw4FaT40qk6ZJrd>hsfhW7Z^#WD87V%O`Qo#G%Ne|5h7xc^Jf_l!K zBeaKelsgwDIBri-eIwK7XJDEAD;Kzk>tL^B#4$;1LWB4V42)X$2jU3S5+U(PdE~WZ z_$?Ov=yxfunL6f=?f; z5Nhe97^6DdQKc>8!5;3W$9qW{Sk^hv6>oaAAy|q@HZ>ye$o#>yhFE-P@Jk zu2M3?AHpgKg1+3p<)~~F!qRMx1w_b@?V#xHDdBRSX*6Cu56hAJ4Vdr0raNevX6A18 zae6^|{7^}^ma`|JXXliUWxF7=(4*JQXEQfEWqT)cK7$GA(=Qm#-L)ruaeZlLujx%j zs$d2XbR_V(@fvk4?CZRupd-RS>b|Ibari>_HgLklcJJ7mv4Qz+0^Y1R>RkO`Ki_OJ zd!|o<#H>ZhR}#g{8LMI^n;`ajF!_r{EK^1T#*{F$jC1SUR@S~eDMp0Cs!dpCsH+Jv zhtqM`g>K2zi`-)pc|H0%;B)KCKC>z8M7(3pBpL=mAH;&i{XhSvgO=$ogdWd(rOmw(bwP z?^mx<*9LUAWxh1*9TqPutT@)-1?7!pyaEnrG-yo(2eM8=w@;e;3)N=qLNKjX9fz^E zVKSj$0KB3w?|8=xc;z;$>%ry*+m^6*E8yvv*y+(>f}PpJK!G#DGB!2D=Z^v53@MAU z#qQyiH>Z~K4fZ+t=Ap}27Bwp`nKQQH!h^}x@|pv(BN9Sqcx@kZKcR{o?|zME z1ZvXPFmC7A@b2xG^5^8xSh;CYVErH#k@i!$C_6%?U8z!N>+M(hEI%M4ydcy5OpIXN ztHC=37Rz24wc5aS5Fs`6ews)s(M#@qrIkBt>1Uu^%lr2^&nb+ZoRXp%*25&lwVfa4 zRywK$)v)0EDvUEyGaKLA&c^2mNb~W;TYo{!RjX3V?=U8+40i2_5R^NE4%BoW1vvxC z^Jn0Eo5DOJe!=WfRSzKp=7N=-jRm+^}$UpBtU$7vp1wNQn%eUn3 z^wohcA>PwX9E^j!Ts}gMXGBos(te^=7eFx!>go~Rx{PBfb*fyP>5vz!=r(1ip2V-> zI9M!x$8y9T7|2q5Wj6E{6MKwd4#ALz|6)i%lV1$!K=xl4QtjRU#E=C>|0{-+e8c=` zsAVMv7Ouh>?il&H{Pms=Zb$SUJSX5OL-Z#(1Qh#;fW=5>Oq^%gt;hQJ>LAw7Mlu$( zw+@DdqbBPUC6WO&lHohM!ujlQpe?D>l=jC8L?Mpmr>hDOz@qiXp|39JdBoZWrD5Fe zF%~RA!PYd{_tuV@Fc-xr-SM0<4z(=X)YzXa^F&l3yCq7;<{6)FiP&*4o}cHdGF@HH zIlCVBr@j$Mm^~3gh<ZP2Pe0$9!Ecl@^yI#K4T;&C?9{-+3fBc{+f-on-&aNO$5W`n z>XCY$5Od$pn07@_#L72S(5eV%=A8tcnw^ev(gWyZF25Kwr@(R~8XwkN$1c!@?Mm~tS^O&qVkP4MTL7kskFE$@v8am21$jOjYp!lhd3iPjxUk59a5UB;PtM-TB;8`56%t73T)Q zDUvO#O&Vg$OB`@L?93?#gEn;iSglpA_GWfXgbQC_}d#DVhjc@W#cvqD+Z=b!4jMjqwr_jgW&dX|i^Ci=^8FK-Z9RTMPpdV+ea0VGI)EgI zHW|*BMAI^MQI(+s?-=RCu;4v%)n{L&E$+O>xbevCqDQ@q`<(qI$)fZ#=Wyn*_Bes7t+er|Aosc?dC8L z)!wu3(mWg;ePwizYD2dk3^l8f(sa)4cO9j8GqMs4pyS?qRNaR5{4F~>e6}Wsf%b^i z?GCtJm&QOC%9SPsPAX!};5DbF?3(wi0T$!xftIIBT%q;==YZ53H)8mJusQfSUpZpc2>N>mv>IGfHpNzS6E6B37UY5L@qjfJ`88 zTqlyjL@-aGatd$8786B5a~8}VnuO8OQ5z|~cI57(|v&V#mqD-z0wMU7jPkNX<5jS~C8^7?vTL@1_AKwj zLu6+6jsqHa%WK~J#$^g^1F}Eo1>QZtyiq-6DZbfMuS&hZw9d5FPw3pIT#uu+UXw?0M^8;D zoy9=k*-nbtZGA7kw_SDJbEi`hR?QurFKGHDd#+q*C%7aO-?p3A@xd;{2^OAEZA#o+ zGUOMiqZHoG>W34h@{<~}O3Kl69U%tObG%`D7S=WY%%9()BOAHa{!@iq4d`2qn#J4j zJDK&5(*OzKz{bTnz9%)lVQhOmDB2m#oVvQ!4=6i?z%E>nx|iUEwngFVIiWV-*TA|H z?grak_ul=Pz}qfoE6dua@tSTX$r(saVN<25i|^R-knolC|HuM}nyyl2eI-FQ4@7<> zWj>+G9FQlp>Pn((w_%X9Jt#~vZUkc7d?N#9tVt6e3hUD((uSJ5f=cF}uj z!!6)P`oIdiv8jiO>LP35XSpd9thX4SNtphuTVXFTF)}_g5({UhMTplJl1nm9FrC z>9EZw5Qq60tKtz6hHKK>y$7M@NbQ%p_jWeE(KG38!Vf$=NfsNiy%CI`_f zLCI5%lAm-gq7{Y;8`1T&8HU3j3!WMg0lflbs}p3Ho=DFfeN*@6iKd`W-zke2n8G6e zKd>Ik)sAZMsk7DE46`p^cGs64yhQ*;5s zWF?ghkY_?vYDmnrLTa~1`YGH-#6_JlokwAHHJLSHQ3BGPU`DoO%3fUHp)ktzg@!x2*5;+pI-Nq_ z(1MCTpoQ~x6WhU#T)XfhWGvWs@#86$^9;sI)Ax)(XGYtf>Q#x#=wN9{BdFj znksBxbdEiulN0CVSTDGuEq`9U3SNnlGn}KvV~wa)_p!}_-{gL62hveS&L8%B9PJ=Y zPfFD;Ywn%i-*Z|&1lH0x$5FHP(>^d?&0_#AQMbX+yB-^4X8 ziMkw01BThCDq@Wm2GHm|sA%I2trE^6BRigCy*@j`a%;FPMFBdVg&^vg;nOTXoo`hv zfcGeJc2Y^NEeQC{BKiRjltyjeaCEQSZ_gh+yUvhmjr;H@-E-~hq$7+G!#b7mNf%w$DFtl2jiO#+&sIxlr+JLhI=>@x+?rx$f~d&a!}RlM%m-?fS|}!8zF^ z(D-{~O_~8Y8LCQ?At6PZ6;629{2+0H5#^dP=wKtHF&lE(VY5H~^ z>D+{4{Pq)81)FXxN2Mqk(&Q&g+f?1OwYWwftuV-#SrGPKE>Qtiye_5>g~eb()OTfc z616OW(EFTwgoo3B<{$h6I^)N~KPCPSouGUB2FOs- z3!#$OR}m8i_Xz&21%~AV+y2l3Tko_$t%sQ@mpSPWgVZqx|K4K~b!B=Op(ct%u?Xst zt}}d@&Tfi2frfuZmVMmu(M#pr^)uhhj!T4Up*WXchQCN6Vm*N0Fv;Y zof&80Nn3ZPq^j#%8Ii&FZpA$IOXh)C#Mc9le@M{-8cp{AIacr=t^D%77DamF^t2kX zjrh}y78$)sN!~n@5k&}ZZb~6tZaMnD1 zml|)nW5bR3yS{?5wfqlbZ;g^tZw`>z5s!s=l67mydTvt>_MOF!#JtyqMhq`la3|`D z4Ec>r?`7h-=-;f z)VUmNjP>24#jGbUI@%0X1LFL1y-eJazGvgMMAI^&3A?gE<2+`M&|IPUP*XV@BKqqMjb_yC<1`G!1kk;j7 zq+&_z3X^K~GCkBhbWDaCqgB3A8rR1}NX4H^z*YrCXAT4#wxe8~$hcFjOEB5%&u21r zruXx=jkUJT$F(a$x<(`WhmPbA`qFO!E3y-$G? zWe(7jbi_SPZR(GedV?RP$yS;lCnv}B3d#aEk13vW*{me64n`U0dk=d?NItXdYkxH} zYj$eBUbUm9!*EjzDSn8c+?}}=`)K#c4qt`c^uH^ZP9BBI+D!YS*!eJ_%JUCIMCZ$z zfA`YUbj}$&Bd$hzN32?oVmnHdR_VzO^(5Lv3I2IK9iAzxN_~)P0uX zJIko5kKB6(8eo)Vj^3T7c_6k;Bcbt!s0mj4M^O{X)mELhpSFIz+RJKGy^m3siCZ4S z~vSsT|Yx5GEGG32I^qeq1`#sto?^scXZ0vHs3w-Iz_PMiF{#bGH zvR&~FNPMArmH2C6L8mZ}gBkYNznu3yggo8)7wdgvO|+F@hnwp!TB$2uPw~-KsM`H= z@4@<(!N~2pvo%mknFm+}JpG=1T+pMJQjp(Q0IL=nz7n(T4LZhu|C%Y?I*yiJyJs+# zPfSlA5>(Ke2*g~4=2w2Eo&r6R{eq~_!fIm&C1S!<^+BeoT_;59^+f5-|js+~%n*k?6zJE@f=*QxQtt97>jc5INzh%mN|PqTD=KU=#(wUQ@aHPp`w zZ`;O`Pa#~?Jm_5WVM?zRb>{jz;Cey)_4e{<+ZEK!%nBqt^o%ltiGD^id1I!3uhr!2 zBDzNp+_!0zwEbnk@<;JalESX%zE}jRUPN!6)=-OupjT;8N3VkWk5=rNP!EI-n}3T{ zx|7!FOCk*I&o-_%7(_-4TWBX`A>l2t0`k+Vw@gnU*L$^f7i)@)0Oy8M?~}$`6m}0+ z-vv=P#Wou=dp!%>N#VKqErQ?dN6J$LUKBARQU%UK+S6Qes>Wu&Tzcr8OMjI9Kf3fy zxF!^Se{$)i>v{#3-5`snCVT4u$xZc zrB}KRB8Jdy*z$mF=@z@X;poF4v-N6$x1#TJUkp42JP{A^cuKzE+6#tqg_UZfx>=xl z{n@~;fu$}PQa0=UoyJpBx{tS#vG2dWIm4I;Vr_t-PH?awFr{}%l|H-QO(eqpqIo^R ztU(bGJmYz$68t=Afpu7Eh``&j-lw4oX`&QR?%~QfJZNDFFR?z#m(xP^yfGZ z%vO-H*HS3fUkz>8UTsSZ{u|lzU;U2kQ5U<(-w?BMxCyQ{q<^fgis69wR z*#K-F=$o@wsKw)5Q7ehQ6D}XbactqQ%N9@GJ3ACBJeglSFT91OG*}TR5ojrBe<*}V zj5v801%o*|BDpW}S1m}D5p{dw%J&BASdP40!sgA|O538b6t^txYlMAO8f-1AZv5&_ zKQ0v^9)x-}(e%m!-aDdUEwXqV~Fh zX6;rwCO;C?A!it_V6PJ@r%pX17pa*;Tm0r6izE01(cID*?X;XVStxB2f%}_~EX_1F zE&V!w!T9e&GP`3+dAyM5OJy{0^=mtwW#ti=x3A|N*xxD1;>H-KrNzIg&JR2(-yzD< zU)#;kUOx2r-M`O4{ZpX!)xj?XTFfQ@r}>v${oo&W_PwMT%mITcGn%SP+*^^y>!XaU z{W9BW%^O?s%juMJG==?H)7?5vMQit0!y}s~S1EtRV>v>_8}#PXY~QVJMRjW5jD#%I z7mUD@Rwr=n5Pq+L%m-M99_?R+WKyC#8TYJr@bF}M(B-t=UCd~j7hWJvdp}-9$R=Y``0-UgZnbQ-?!tg) zeqRK@{*A1`j;=!&VwJE^Fu!;mI8wJ^Z}m@Ef#m5(o!)Y{EHV0eX$3ox=oQMhx)INw zzpu?!=BKSyq7Anh6!(`C2HI`ONlexHkoH*Wy>$1{r)8X&ep$9irn%rCY1X*vCL|8x!I|Bd*j3onvNAnG$~JQr}j6; zas^uqmgbH_Eo;wx5{tQK)PmjpktFHv@?+XHL}G#VV^)Fon|);ffrD!&DAss{K9X;< zliG5NL!4Fx`7%11+<4G)|5w+ll?|HOqRVEQIyck)T2=y+vv!qwjc!R%h_HGj=f`oI zt2L`Y$n{Y8RSM5M#N8yU`Z2MHjz=4VN=eaGiAGA<1(-rcDarzzTP|=`IR99ar}Fc< zj~ctkj;Sbx6FDMY9N(>9sD+4$k3@&MW`gswg4CvFJ8>F0`dw4=Lve4;*2tv$HcO_j zp&yx{jm`!Ph|8^coeder)#uPIe8qz-^@c9Z+e;qnh3b*93i0{_j$1+9#dd6uj(ouD zt7get&eF;oPwTm@yy>TT9XJT>x_#6AuR&ShGTsQ$(B&6|NA-J5HuZBDZJxOx<|;zw zR$W$p+iFWUt?Cx%Q#vRkU`*nfBD#$F@cYRGO67(9K5nz_mjzN=PFeeC)<`P5epm`NU&8U~w#xLK|w>OHM zS#&8)lDn;|0?cYLwB9ZN(LMmd#A|EnLnG%6xWJQDEI%=>m}o3dW&&vAEwY_SdRSnT z8E-upoc67BXZp_&fsYr_Gyc{tKeo*G&PJY-Qpa1cNyjCVOIxBtY%OJ@9?RSpUKkh< zjLjioc{_tOUb_COY(~HTi+pCD2%c18RJY{@!57|BC3Edq%=&id)%BPz8@r}Z<(OIP zZs(&fgCY1R%m>cr$?71Mxl@`(-D)BBpEpy!pJ=x8+s&CC-U$@A-Jmt1a8m($Ja^ z(-628`|?V2yMp0-tqVwyqrF&(CZV1<;`Nzd(-I8}Jx=#r;bS}oy^6j#&Mvt%L zEs`g0u7CV^1`*Piyx4AcOV&i5>gE`=ova9^uH31LS1m3{?YdjBT4^~pl_3pn_tEi> z4T^yC|2w|t()hpR`ybTRAW0(in*CI!_erV`I5)``Rz(Lz(t<6^1shfix6dwj!<^2x z=?xerEIo6;j?{{=(DlrziMkyW664#KZXwYQ0|};$BJ)v1`|~jhm+1zs3Da0kVe8{g zniFHBW)I*sww?S9mey^R*% z&ELWp8r#^v(z#LTw(XD+MeMalYo1EU^#%rh(GK8*2122Q%>1~OAinTPM!QkkMA3&| zzb&WfM|2|vsORp&rGtGrn$ce(_0N3Y-jje*p3Wo&Sr(B}*MRYl@6^ljLXB{=!Z)Bi z=Zsj$L6o$;=t8jD8@f7p6J z_jS+lTx#8bGkN3noxxDNwyRiQMP!K6+YsZOdnd^YeKorYj+NOl&%2Nun~gE^S-MgP z5An(-ve>3OX(zAZ@h!OLG=(64C*_k3ha?~Uh{I|P#}Rt=-@_eD|EF+=vhR+LAQ-k=Cw?YZ)dWUaZ4v_SiO@&3NMs9Dgpd=hxCz|GB%9L z{A;@mzR5e&$2|%mf6elCp3)$S2tzK+*!9jTfmOK#ZlN5gL`3)6E^dT9iMnw9PJ(r4O&hzxE9RbCPlbL9Sny;zr-CO@IBN(}AqX7zQLn1!gszY~}9r zK-VXr3O(LZ@Z4nMok)(9f>VRjIw-(>cX;4>1yKkH7Od7?oNJ%16)~X{$;#h2a!-v9 z9vddf6r7Qg3QhxNno2_0y?M_^5^7j|f$mY(01SUI!Yn*QB?HvMS4E21lf@@4^ zX$52MN3=MC{K&tQeMxsM@5Z!^v%q8N>w2C;N%v-3DhowQlR@C6SSbSK|D@Rb0+5xRc0ZM2Ey0L3{yNwo|e%vBBC$gYN zWpzyS8Xd;fxD40 z%Of)V3gl(;s0&ZJ{w2(d#0m5~iSK<@O*coAxvtP=(W`{006N?JKfK!%T_gI3 zmN!bfbHwtK>fc;J*w8kpd+!fN1tfG$uX9PVQ03IH3fpb>SP`s*Y8Q923YQQ3xL-RP zvl=Sn8I&xj>hZPfza@kNibih#L#iLE$ww;Htk0LV*?b?jdqPngWalapP_6VTk>pXD z&AzzhffF=WL*zmuST^Bd(t3}fC;YMN3gKWSlp{MVNrlKVTpqfm!=t1!eu(Hz?qmPQ8_*r+-4N2^A8bZgXiH-hG-9NfsJxSrw#|s9D&s zP9~Um*A-XjMk1aV#Zl(F%**aUdPsgevt569S>}pQLvKGmHIQAhe+Wa{Z#X#ijJY`@ zGAG@#n@r>vR;x8u&&`%}m~MPa>KMphWAxwiCOyh(dAxoIR=acN`NPeyx3bmv*5CX&TSb z_)pYgPmk?_lTIiSH(NXCh>aK3iA^&W)MydQTK&kIkJTu|g_nXQAZPfr6%;@x^EG!? z!M!z5P1n8>P;69mW_b(?-J2Oo1VEn`g*6$nVy|F#Wqtj|;cW>RJN<}%BP0S{5|K)t zF*_ArpPW*JI|!0K6A@G(D_CsjfR1`SAq36M+L=nIF9-LYKFKIa4k;#$2eR3xVupR&HZAR%p7YvwSs8DvM+Ws{T&b|P>xZY#){HqW@-nI|Xd5UI zufqnhzT?54@s;Tm+(M1QxJhEQ?RrBhQFqNtos9i5@h*KkM?Daf&559Ftv5`peu(l} z-TJX)DQt(Kz7ANlC5mXHp^|;gR8n7#Jz}7hJYmM=cBiB(njuL0Ef#rc6d$D=?Z!c!5pNJ0PgRFOm`0{Fr;ug&G~+~8gg6Y;79bRMclRD zj=8z4?YFWCHr||DW*7s|)4+&Ke?g`r=hSomXVUfLljeiV!851HM{$=v)*9r)gYPu& z_&9`+yJmOc6VYVfp93d$=I)&3C#5?x{LL%KzO<2j@*|L!Lsef1y61~T#j%*jrUVfK z890$M32HvJtO@`Qe8Kk*rk0j3y^x>`5Wr%hj~7aFiJoro7&RfnFQ9yZNKVx5i5Nas zZmjQ~T&tm?uBvFiEuFh&kL5mH&Y4X^%E%OOn+j= z^<(~QON5yhwYr84gbJo+bgPK8lUysk-Xt`BPUwCMHU3Y!#Zw*7J=&oeKaNpe_gLpI zBHni2$1SRUCe8xCt0l5HIV{KR1(JH%MJ8xFFge|X_cM4T_s%=Q{wv(J9Q=aYDfDc4 zog+sdJSiTG@$o=PV2~LnXZzViMfg7?PKH5$O`QC{0^C|HOl%eH?Mz??3~iwv+Mf>wl}&3on?>nSkvdPHjtqbvnO^bVPkLt0_O`dJH);(;Yc> z8Nm+qSH$q4*l9~BD2d4-RSOo_SP=hf@&s`Y2aj9(;)D7v-l!wOkv8WWMZzRvfnz10U6kvG14PDcPl# z+!|`XDcMT*XyMlJvv#;)Zd<9om%(7Q5jwU(b1h)}tgeNl+kX-*+P{dl8__x1-M)aT+3t>Sg6gtwT5BN5I wGV=Fd5}n11F5$NZ{^=GE|3BxYZ$&fQBypalYp)}2nspB-sqm`kRgfxO0qH_Odgy|LDkxog z6@kzN2~A1>fxr!a-@W&}nfu<%o7vfV_Ut+P?flN}7iplcc?HA*A|fKXqOGO&kcj9K zIiX%gK}^U+Wd!<&i0A{f)s!LLQ=9KLP3U`SJ69Fct0!2&!Xm{6&M>ODV{fXm^0qQ%xbmZ28ZsctA6 zVTgznJ#Pxhg#^)-Ov%;+1|5 zydD*bE`bt)_vO507ZhRo(A_{qIPW{NDVbq~X3JyeNB);COd^8B$NYBSJ(b+epWi)M zE^h5-Kl%do&LtLq=j5gbb3iyxeg3+c?PdDJxx1M1obu+q-LxL{X`YRiXU_9s!GC;@ zO!bmosy3X85op#;ok8HQ#DurBJt$#=*S4OvyiM~FQff<^&_MXJg!$FwICM1!8>#Bw zKO)wdH0WP`?dZgX_xIlPBu`Uw<KB(lF+oZ4n|9A+^5-!a`i+Y4TR2o%bKe#6v1w%q%B6)tZ?F8Q4|1mA!^js= zByA-h7WdlYE02FATQSr1EPUT6ZvsYV6*N|MCn665fabC;K2`4$iOT7%DQ_&^+4qby zeg@=_fnxd#P&3FxTsx$b4CQ-=fNj_r_v3RW-_+%gMdn#5jgw2g$bu3x<$lhmnJS#q z{i^1)Zt8dVY)qoc5?_KlZpz5idaw67p#L=o5ADFlSls?q?uCU08(zjuU$2|0VC{~G z4nQ@+lLyzj)tKmqEv7bpB}Pe8i4nb6n+Ry z@V-!NvbLUE;KnG+Ttcv6SEB`5Ke821d;5Eo0AS*|F`-*s+ceIaE&XvUaGGC^=XEP| z+i?HMxroLqxt0a7_k5?*htmB01L#phwyRQJfgW9LxdAtW=w9g) z+Ly0&XJ)m+fWcjN+d^U~7=P;bP`Vjj?>nBlUHilzPCqSz)?Lo7TIvD@=Yn<35eOheI6vj?cm#`N+r)C$J_jK6?Zf!MH7{E_vevl%GE)Gqx!w z?6(gK%JiAGyNt>O4}y<49_jD81Pvs-3=#jOciT1)%@q^beS2zWC}J%+DvtCmr{_la zH%~E^)7hAhE3~nd=W$OGd8IIKtFEKg!@ptr9IkA9YBZ8}`-35M>7SjNcW4|@I&_5YmrKUVb@8SWsuwZKNa>WbpN`%aR(uaXtfO60)4CR|L#yHgpa=^QZp#&N8I;K!PTRjD#x+xCGX!{ z`IuYBRP1_dYr9bI7hNYcXQ)5ew>0V$VxY68-G?H-`vbOvFid#>_rL{y41pyE&Fl^Y zeq8$28ziLd5jPp#txAw)#r9mno}Hc8kzZri%nyRuJ8&HyR~N9AXK}Y-gATUVLIWL~ zR@F}SeS6MtYJa+IeEDqdHGZ{E^&P<$v7$ob{}4Lz^@QMo3dL+Ley@$3Q#cPUrzMfN zZKuT0Y*wBRm=VLyBGUtw>4gRvTpT8gCB&W&*sjMtFX%$04jj3@m9*8}rsG9F3M9#0 z*#0%@{3=60_*}@|VU}v>NkP)CH5zfsg7t)rHboi;&D%_i2!0^iR{0pwVsI7VUH!87^{E;fYC&U6(@LFZMO zM^_y@Pde;7KmV2MyP=H*`)XL=HAk zk!ntoS9H5IjGRFumIF68P$G>wmB&gyR3!Nyazx_C6n8_$8z-Y)YH@_cb}clF%)*O^I};4!9ZOYR&q=E6>DXPoIv9~GG~4o+ zeyxbhzJ(K$Q`KhYmEU`N9fUMnRy60|QNR!c$fuZ#Ql$GNXhgb5)Q!)5K%gzHuJ%z; zr8iO47p8*nWNwGv_CKrm+PmECp9;ZAP+DuK%IVB1j>A{vc6W6S0-6OpdwJLc99=K> z*}TXL>@%81)+h#gP@#8@c=+ZAanuK|48qv!vQ6@4hYoF9AU5R=R#cN5YbBcPfl|`= znk`vQ;J_>?JDq+)EjdVRzk^cvZ{YKWiPyoz_e(ti+HWT299|#Gcnw zIJuj2!i&l?l$fEdZMY@HPJ;+2Qhc+GWWo3hEHn#m$82uWpx%qLn7No6hzmBS9ED)! zcyXVcA5eW-Q1h+Sz*;CZit;>e3QWJ>hleOsk6R`CbZeu_ot>&>Sy^iSs)HFxN!?4GN?BacrD z2mJd6^}1=ch>8XIUAM-eF76$1NYzS${>FHA7pih1Upqix$c*mE8#2V}!Dn~bS*px` zjjVr4i_-r&-XdDsP#H7R`db>z*4DVWp~QUBSQdm) zmPNF!H#kLi3>!=9`c>f^^Kk+%-qqzg{_=x)`3ik~=l}8nGAUniK)WmFLu) zc#YQp?e3Ke)E^7=`0QX?O1e;214Zv^SrJ0mpQp*i>qH$ej3GZ*i8@DrfCr}t?~-tT zgMf?c1_{*nc2T-DRq>XlrWvsBM!ql~jU!;rDq)$m>RTFOui$)@?qi{hebF2sVwIkm zu2*A3IvcDiOf)2mH9Z&WH94?TJU!n2$R{DN&2PfJhd#yzi&) zX5c3;2~^&*v-9v`$bM=#YA%P$%+1mR{L?sSjKc@+tnJzTd^eQJ+FYB*#@wm!XpT%3 ztV@&9U`RUS8Z@NJ^Nc+EDedSh7$>{8_r{B-ZjT-VsiPz1+|5S=RehFTK=xu7pTahu$Si zJ`;pLZiNIPGm5pvEgc*zVSA3xjl=3+W1BMQ_D1-9@#lMD*zwBf!gSAD&QUp*T*)BE z0Y5QqxyDD}+Q(zhjIX0y?wh6?C)y)vYL!R;nFqvVlL$&b3!!m+r8=x;rO z$o<-3oq~MN+0v4k`C?)yFSHG!&c9LH5zf_StWD8iCN-U+-s~nXlLi*NMit6sx!*`Ju&P#qZk$x}$;H7OZJgN!@FxC#7Ifz@ppy zDONz7{N4~s_`!50uyD@}3OqeFU$B7vxSrQ(_GLFRUAJzfEgo>Fo;)Wis#f=^HWa_;ByQ0vQ+~8Kd*y?yP?)Lq-v%vIXT$@wh9SsMS(1v zj`td#01=&swp-p@GE!1rS!V+wG6~eldv+)0X+7C{{b?vz`wvSC3x-XR*B(MCC6H^| zKX!BBq{+X-NYPkzl6A`WO=lca?BnEeEV=N(zGl`hur18>r#^kl#rt&z>0_7D_I?xl zM&3+#2o!x%s**Fhon#`VP8p2xf zH}WIHA>i+8%rTryaS}4KE28@JC;m`o(3Xb>6;DOiP4lx8ElK|R4ERf5=GdQhlM4iu`aw9@VuSU`<@Yv zO+*nRa!f_Y+&NOkjysr$b0XH(YJ{NW)TlRcpyJAxMzT zY&*>t9yUD$j$+*8#jA%Vd-Uw9C#xexOsl>(Lc*RyR=&{;dw-az^HKqR%AINPa}I!w zzB@fuyB-}f`D}?Pw$Mpb9)4WXNyfHqb8AIU(DS88ypET&N#8&}^J-L4{hB7h{5lb` zyOMq>7yhpLv5HwUbitEpfd$bPwlC~#P>NC-oArvowk2HKob3kgMNsxpT=#J%_;ht8 zDr#_>pi`-XTQRH4z%KmpZ-|nDB*qiMCkO}#7}8R2l@SmgGQuA(p(4Y7 z=c+4a!2dk9lhSfTK)`Ij|9KG0fJp>@@~M-!rjv@TsgtXLg9(BPz{1YJ(aA&?e-MU% zK#m~&Rz%e;dAsS(k!UjZ=amI28=;68M!0n5LKqz{m3UVL(u@P!(MvjDbbml;@lGS` zOppFVM>>`^mCE+^W5M=rCKbZ>;X zGI5lhAp+HN9MLxOi2aqDVT37!`h#!;ROK_39Qvm)@4dRSWY4_~N85RZ6z^lNr=Q-C zW1}MZJ?MlL1vDS6T+P(qvE1!SL{eGEWw>F@d(yXe;Lk0SQCTP&Pgy+yFI}^wH6|?+ z*;Yo^v2XndY3`eA!3lhK_KjAy_A3&($4QYP ziYcpZr-FL!W?703-`y`EdPW(c{$(5cVT&LhuZ; z+mehf-^vz3U=+&vk|H{y5+h)Lu*0>-Yy0W#Pt7=2X0YtyN1n{UMcVV;X7A|vhU>KR z+nkg7`Mr3mFC7@BfsWMJsF>t{kG3}(lTjwq2f5ZB2yJ24&J1rePf3S;0f>PgaMgNQ>ow{@8il4OS*B6o(vqo5Un=M1wI=CLkuY%2=`t>~7#m{Y-W1ae4~ zFzGFBSXm&@?D~e0DO?U9eIeV2;m=VyEc^I)=`9GyLkgZ>$HX>M<}`lk@I0T3S4grD zI;1L7WIpI;nA9vKK=qFl?BgE7ob0I=y7Di4?Y-o1fr=?|ILXJVAB_?T3yyw`0!xwV z^xXf^MKJjGB25D_a{Du?aK7|<6B+dFYBTrUD$bK-5u!R3@nys{noQzi z#bd8K7LhgdbtSL15yPZ#ycSu7T&=?yn(IH=8h;M2nUv!t{a93{_p%dJWv$5=@T27I zxA3C@N-1Uwf8X~+E6>POq-MLny;OdOX9*d5E_qbhRVia`@*I#ottY!x$$ACf+UL# zEREeD>X3(IE1rreA5P$B20xQpa^l@rpD5vGXJKFWmjkYMw~K=hXYkq-umeY zQX3yxFOD90tto4Zx2+w0az@7>UE<-c%S60HCc+BCQ3a%H?-KZY_zpi`JN>BMef2W0 zY0h|UPuA#pz&SQTC!ZC7vsc*|w|rh<@XdF0ggQj2r$S2h$@^zoXy7HUMa{UPGH~6J zaV@#eK}jK9#zRUk>sQi?^u!lauyU7y#^!U11UWoil=H80L}35Bb4st<+Kap6&G$7r z;$+Xd`W;j=>A;acHG+Cdbr;R{q^P^Ld^#bncvuYJNG071%oS4iZ@%uUuGhZvHBCuH_uz+Ehq1m_7F?-!M7IFlLb(Mm-V5$)7(c9nf>uEWjjKMHsliMVYmPj9b?8_wo>J0>PL0dv=|R8&)wQ>H$Afo8JB;^nn%v$SQ4K0&Kn z%KapcJ@yuT0q4{!X1(RQLoOsv3fW7T>)qIe1ck?P1(X=*FwRBam(bJL6DcUdf!Maj<|QYFa6DGZ*gTJamjd& z&l1y|`#$@1i#HipWIa{%b%f$k^DR`^q_!t>;@6_DvJXEHqYENY_SSqXzF*xP&)W?; z%zKb!5?3tmr3-0N!Y?Z*5rt&|K9|C#=gr^)#%QW{ub!WiMWK08YZ#55j&U;64S;+P zMd&sUk;)kOgzMd+_FP%FT-q*b{7o}>Oe_(Z1d` z%w;PE94e~pco?4ISd{)2W}a*-dMS50tQ}tp+E;GDyK9p2t6(Hk%5?5_n?*& z^I5|+Out$COT@L+?Op~|)zF=!kGi9N#`$Bg@@4;YeSS@?eZt!9sj_TnUIQOB(!Qq{ zQfS9$ed^O7Uo4+9y>K&H_;$ETrVn08ySqr!s=dTqP@%p5b9X&-H*4Q22-R5OW;In5 z?q_fI4Y$36TyI1QyA%4Dl&W1oqO1hYpd9nQE1c)ES;WE*XCLl6&Oar`h#|wU4|9^7 zcEuSS(p(ewYeSD&-YnuDi9XB&w~)7QYh*)~u25xYdSiV@MWXvf(yUhwOHPvZf3ON6 z7vFlMsH2qm?eRPV6BQSmY2Hp~?-z`ndyNN5>nI1k#ku_nei~P%XLO>HcX54zB2@%6Muhf+PG zg92Lj?PcoQU6P}`n7gZHzdOUb90l&YfZ9vGDzjT-+P#=Ho<0`0UHVr2r|_feOTD)y z^UbyMZXIpARoT!k{eqqi@mjRd&moq}i-QYVx0|O`lBwQDv|ifLb~*TU_IHDOUi)}! zJ`4+nQG1Mm=LQyp7CZh}npN`r14U%(*X1plP#6v&f#0&Hn(gAs=T?78%CF`&AE_%k zH!H@j7tA6be4U%hKcv%1P*bl;TY#_AzJ&y9l0pYB((VE-?lQrhcV3`N-kbYHo3-IJrn~Ca+iGWmfdOKKb57AW`z41>8jn zFU*!B>0ffg|1(v$*9`8vJG#d9J>4EWn!LR&yJ!&dQs0h-Tul4kiBsD;R@hlZk=}!v zqEypNqHpuI6BO&oJ(N%qc|*xd<@Q^K>;#U~yYvUDzc?=e*~FWc$F~=L5HNb{!3N|H z;Va#na_-M5fGZJ0|8NwcxtYZwW&?#tDy^nM&~=V#UM<9TU}!r|Z#$zZbJjHxB{;f~ zGFJlrwx4f?t58Ef?4b&s6DVNHPK?pRKZ+cC+vsh;3PQBo+FB0GII!yFJ&*c-vMPH7 ze{lZ-^B_CTUk|X+1zHW@JO2J6wvQSteow9sTYgXy8s{jMo5 z{rtNCWlVjtvF<#KlsRybqPj}V+$W@@?#0M?%k;Bc9WHn3xpJM7IS~HyFKk_Tg4r*% zvyrc7DOA+SB=EN@$uzfI#>$*Zw4KN*xNy=yo^I$J4KD>qv%9LH-f@>1c8f! zUV8<>ybRJxaz|OA`0mWGlprmFbR51^^0#KrKoqan>$r0v2rY770{f5+5gVG?hy~Oh zQu8x*f@=B9h^M@u8MAu+3FAL{AXdoJ2`-|?Wq$ClDf9@)Yd$oAWbPd)FFy>bI3p3w zSYOjl^Zf1^ueUT?!x0#nx_WpaS$oi$bS;LDK2NckW>6}**I5Bte87RH#|gC5{R1z79FrwEWhp@o_OuC0q~o{WH2e$MVL%I zaV%zRk_sp6xuN+aCE3jygM&VM`i~m&)~qxm!sq(9!MEsZgI@KMTAXX$g2^g|*K22h z1m8Q;5V8%5!8;#r_8xefpr&GXenwNA z#4ur|Z&S=hA0b|RUk7C#+3Io+N}b(;i8`RV8Jx{vr5y2!IJAR)LInHv?7A6B4Zt||LR5H5YMBM}`f->_NT%GirA0KwC!FIGnPksTSQ14IOuT-kYjYUy|6XVo_1j+n8iTrQXgTPmsm5K3+9Mb1f#;^pDaCIsU$ zTUBHds|3rH7_w2GTIbJ|c=@GrMbpJW^ONS<0CuBd2B{kZDf16X)F;O_f~cY&kkr^zwe37@$s zQFy8Cdy~{B8M$KW8 z)u0P~wWWq3YAMu}YxtTk_h(4LiH3HmsZEzc*@Ouv^jkt%Q?ZM4C1KHIMNRljj)ty8 zodJ;xWI*Av<^;rLgzYAvWae69ldoJ#!^Q&%7Hc-2Y<{v!d|AH^ah%i@xM;_}=wKH5c@|6c zB&T!8EBTQu%HxwVyhj~f>zWZY3Cjvn+R^FeF{QaUm?%m{m>2Zm#Bmr>EIL}0Y5^tM zYaB%!MeaBj&iD@ln~YMy!<)V95=6n~Q~*pI=gPXr5iQD83S7@WSkk}c0h>gLi|7J* z)Z>>J*ZC{MHtlgdFtvEmmnoK8vew?%Bf3XevPrzu+AxQXMmm}2-Ezj-P024hB%1__ ze;MR6j{_Y!ztk?40B8iS@^Ale#jAl#E?5>Pq;B?2@|1~Tj25w!^%!j0jC6gDW}43Q z->x^D=Ry#DB7z<_`o<$kbt-ssQVYaU0i1~#aK7>=Wl2*>Ar7C|nwpW&-qKE>~gH?CNPCxVRPztMsXv5Bjsg;UIk0!KC|aJU$*ibieXY)N== zCaZF>E&RVRgILo18JX#ZE_INH+OhK(ZSB-teKD ziJ8acReedap8dgNRI2#KF(z?{JlI5_51CXyV*G?S;M?hmiUb-qrYJ|Wb?t4-I~0zJ zaMMZcvnHZv4yA3Y9+swJ6C83wr6sC%KyljX5MEGtWm`RybnR;?YE=mi?kzmY%o5<( z7d_(MNf{DQvR(=?<_YA9{3TuyaRgubCv^EVt05o~N*b7lvBNORb>1^lL(e@{w1SM6 z>&Kp1rlzr0^sDDLvunX;!nJ|A*Yz=U8IX-Zonl$G&w8(AY-tH;V~IohN}5D=s8?P+ zW{}2vc_H(v{@ItBF^X6;WIDl*U3=oE1XQD-2V|D0s_2;(Z|r4i>U>nwh!Ewv3W|<4 za~fSKh*+=kKRr`$o&u&OE<@#;xMN_{Duw_@o>++uB?E z69c{nA2|kF@8Qo*AI};{Q$a2^`q4pv9RSi!FJas~<3U!Br2Fbw*}=~I!)9N^NO4O%soUQTKTkPvOFg&78N{Su zP>oy8PsCqb)oFHp`9_KL^X}a!9ykD^g17`r{thE_{VFh*&qe#S$q(5zF3kw*GbLvAV%Cdk1OcqIfJ; zcZsEORrhyA4@8nYPtc)DtKLfQ!_2kL<6GMbHa=3%E7LZGN@?&P@+v>kRTKgYj+iWI z@m=gUspGw3@?m6I3?+J<`}IAm*y!p!Tfqe}xpQ_};q?i6Xp}%#9;ZSO2E=p=g^-q{ z);!tuXv~obSufWjc@ynBE}IDU!I1ohE`@2WBA-C zQP1u;SA;^(S1C1l&RQzR_vWfcqT4QFO|dqaFyM*~eA_G*FTrM*-+Z8dn|^#}Xmg2q zqQNjWTD)s5jA3kU?&?Vrf{#u$IxRW0hc;F_=2~ClGcnq0Dt$A@kfD2l;f zcxm!DBc`{RDkjnEz3x$p$89@_j^a03a%DD@k@|m!Q2z^SU70S`@_Sp|`Y3t3&F#7r zGui5wUQi!-eMPJebT87b+FQZfZRlyZM37|pjjGhl_EdLqCE2!#`VmP}oa@Lc;wdtTXG}trhRwUaDvyWZ>ik=0`(bm~1QC7MBUG#tyd^X-T+i*;%sK3=(ksIqI>;G1? z>si1$$!v%x?L#DXIy`2gDbheDY|V1MS`*}s5vH_d;;)Rs2!qZJs%E|~-n#c)Vwfs> zGRrnkN17>OY-&Q-gT>V%_m4He{qK*x^}gu*czrr2g(faMe>s~aP}2V0#tGdkxHek= zO7OKI%}L*GgCLH@csIOT2sJl70TY`A1J zr&m$Y1Fjk}YWgG*H#Ze!y{gY>a9PpS+0~qdEycg@ow?k0<~OIl zX>xEuc4pkVAdEB0Iy($66K<*RL_&V;xA!TE*WGCS4tqge(yE|+`Z3-+{7fd(khs+-SAq5C0cxtcW)|wSp`b&# z3b&+onTQX=J|!Q`t^qV%SQJuHxj3v8vKH&HzyB* zA#4-9w8Gi;axotb6e3KtlB6lqh)P+q^bHQf{6Gp^)BT=vZ!nT3L92$vI3FwvD;ObG zo2p-*3iiO!bcJ+vfE#yf2F*$rl$q8sS*3PjD}nfYIY6Zr+P99s={(%eMW{Pp-7A1A zDxXIJiJDro>9yYEqgK1KDSh+`D#BTFi12*OqHD`UmuK3&$Y9lhWD+WKbgIG>Y;83e z+84aF>3C2Nm17B7lC@g`!aVfCjZeeo2SO@zsCAv`yPG<&>T^nG zyTnUOO9{X)Z@ocT1p#@8IiI@TVt9U*SbR$zBHBZq5LxxXqFQNh7wm2CYA&aj{Dy!u{-`qf+87c+Nh4Z9i>Oe|3y6IVLC=oahtmmK=E zhM?gxeQSQ%HmcWDT%%3Tu7>qhY=l!W9TKai4C023vH@A4z8P#ZrDj60=0lgu3cIhc zv6ZZ((aBEF44F%zRaLXK2${=GEgJA;Puxy>576~;d$)R^DZ30)mN|ZDt*WY@rEzS? z`Yi5i*Rf{2BfkXpm~^qa$CI19uX}m9RlxHRt37FpSppHmYE+jW* zVVWBf4U~e)G5c8e6hxaiJy52?h{7UvbX-RRO9Y&2M`VWZLO~3tv$N`(P(>qN;_Z6f z_m)tm)d{6lfh5~JrMzI&7)pEhK5P7r!FGVWOR!H4B1ybHCXo6uK5{`o@8?xh*rHT5 zd?St`Z}&UQe&Q+3E7K|y9Vi9HA>9ec9CMNyA5=-?-}jcyI+jPE*1wTYBN8I6!XUCoy0M8kzdrV zjMLNU__huN4yLJ+Nkr8@D$f+I2G-VtE&wugO^(s*H*~NQNdrIv&&BnwqIlyEk zLcR)pW0SZ{Z;Z?j^QqwE9&DyNK~rV~MoHTlh+@dNOthLVd<6^=AOjU+(Cry0M|ZvZ zozt}4uO7_enib_-+UA}i*OwE0-(IfC(bcw4!KBrR7BTGT3Sk%f;J(FVP9O7SaM586 zI2O@QC%w2Xw(8W5^FSd0SGkI>#{SdlA!Kch%Clv!YENUP1o{;P*S{v=(pd|FDqZDM zxZ_hisBTgn0&PFRyh_nMepaHSM7-I+wWDCuAZue-wvo^lJz$zpx6fuZVy-a?EhFlx zqw=3XB~Bw<9Ith*h}(SuasIEsHsjb*`GP4hSY_;iEI22^2tTUSW!W+Nxk8H9EY=&Y z)SMWsc`K7oqkfHtt(CP8jGh$WvddZCGQn>~9w5mA~k5^m@N!JoUi_2tINg z{S?~i&fT0!8{3_sh4&bk3`(V_f61=(?zShc>(F*d>Bdo61it+3nTP1aB6T zdx`DOf$g~heG3pE67DOM)l@K;dy?@8CmONYK|PG|DN0>Ebm;_hKi1XFqN3hhwfP8af}nPOLvYDAqd=vrwv zwF`V7E}kD??wcLBHDMXW-xd^f)J(mY(QrS=A>iWT@`x3ed@kgX*cUl#bo=fPcSf>Q zimvpSL=ijFb-#}9U*62l4Du;muvh_*FeA3;5*v3i+~}=P=LMH)MUE-NMD@PYkt`1l zt=BQ(-=TVfs_44{zyFwD%jtfEZnQ_FcAsn~jk~Yz`LV4tzHgADnGkHNIB^lKtf6Jhl{$dg<`CA}#LTRoQiJXxe!K z=TlW)N85I=y{#(YpI7k^n;5y@#F%>$`&yvd!<^=lj17`V;YS9zYLf%JwvDl7Upk;v z>JCW$t6pw4uSVE?xMP-ri$>?#bz=d%dxu1My5LYpyY1qnlWx2uH~4OD)9lFz_x!Yp zh*@G%7^~Q6i!B`NKLexSeVIx17*P7UU#?7 zz14Qj(&$n?+~v8&;Mq~3Q6*FU{!1pP$pB|C8<*TrM%ci1fv)Z+-W)akpg}0arH5wX zPt-OwSmQF&lp;SfaTQ@RH7?t8Te9QEscxGFx$R(XQr|9*0>G(l2Y=EO{b3}^d*H(0 zPCHl;L_~zNGcqX-N^RI(?4bpBv-r3NGT1hbK&oJRPTKp5hf8A=rt=;n_I$7GH{8LF z1tr#7M|1==X4E~R)5Dyx`%dW```_~outubk^Wgy*C;93Uqb46gzUvU$m&lO{Vk`EZ zl=5;akr5hQd1_+J^iJYKH80MBhR5^-crOc-&9Lt=?tJ|pG0uGJpD}LZn&p4NIIWr- zvW;Pd8!P&S@}%|^o<2;pn`Gx`d0= z6O)f)Y}`7KTl#vFfq#*VuUCiWHSSBLOW)H=Pl|INlTD3h($=Z7jRs4wHS}Oav&sAY zRlLH^a4}^bUro2wBuo7VhG^^QAbBFo?7U8(S&7j?x>GQikFicCB5i1pt$ANTxT?fx z@wV%H;qm!M2Yv(aCnO4vbmjL*NAxeGn}s8t;g3Uh);DZx!b=RuEv!k$WA4CrFH%Tf z8dULt>0zeuOpelC(CSGPm(+&C)gf>9V)SA0kjcIrx_$2cF9sx_wMI(F?PFULOwbf(vv9&CV+8p9d>ax_)d&mZ zZz+3%tWb%a-#mkwy9h$kD|faBH_qxgNR9z9!74DZ)B%u6{+L)mPgHHA$!29>)xy@? zDef8@-`d_+^*|aR4AArrMuWh$gq#&&lX(PGa{+?>hH<;v6?DNK7IP6$sWKJ*>MZGI z^VqBk4BoARgdNUZ?MErY_`x}vjEB3Pdk4J?WyM-knw^^DU* zUV0PlX9T_JAW!Uce{C%yTsRc|Aa`keqHaTZuHkFRk^r>5V)rV*@fL2?_JjtUCUl>O z6a22<_?z)VS3Vp0ZkY0OZTL2?TZ;t~tyY`?UDrk&gQ=r5*YeoeXX|Sko>s#h)010i zFyWU27`_iw`Ex0eifB7fI#5l5HZ0{r!%7O&!rt;#fkW>}LqyLv$&NyAI;FoDw>NY) zYDc28=>GRs0oUI=i~ESHcbQ6G_7%Xmk0?$fCaP!WJsyIyOdtp(CGD>K_yxw*S9XHT zmFBMgN1-e0^3Y4VsQ1#9g$#13BVX5CTj%&agT5`>kBh`Kj_vfQ$GWCO7~gYNJU@%A zr!$NFF$Mc_^V^Tl3{CH@A$M7 z=pAE15140ke`zPnfJX4o>XP>DU8bvc*zycYk)5AmhO zB>kZnndM=|P{NeW4lm|V*dAJ|bJX^iQNXY>?8c)A`O1#)E=3Y8T5WxnL z6@$h1zN-n!aci(Rt{C%hG$`lWGbsF~FKN@tb+_pRm;HZZG#qotE_4S!dGk>+)V`!? ze0q&}hGcvl$mJdEQ$a!mn8izkrlw#0#%6_Q3iBI~OEp=Bg){Kp$Ve{SoTYQlSZEK- z-1y8o$&uO{Bw}v}q$h3KkG`O8q6@dA^J^Lv$ouZde*K&1d1=nf(I=(-1 z+M9Cyr#7;_m8%&dviZGLFO=5(z6gkYRV25W!bH*t&izLBVIk< zTkupA?AMa^TSW0X3*^2CX0~zH{XO2?`|0T1`0RmS!gI8EjGu$Wh%FyJ)O7eQ8aY%R zRrlHme3!O&E{$2@OUf>TN3mHyV|!5^CZcd*_P&|gI>chTI(W349xg4Igrht`DR2|Z za>UYn{JfI!j6Mkn*Z*Eyjugz`{g-Qc@SaGg=ygY)&`iy-u5#**++_3?Kiq>I1}5ol z5Sw&_XUy;VsXnCbcQo@0v%Hxut|z)U(KgKocIZND^(Cl-pB}3YUTu7Puk|ER<~&Sp z(;+$V^M&ngeQJy7v#u3!q0SV+~9UDwC6FB-=~(Mp087ef)rUn_3?m< zuWjRA&Kw;%W}3;|N^PG~c~N(Uiw@B|dRho#E-QmNRvZqxH-dTH4@H=D+!A7mcFI^b zIugHac#0N#?-TZ6QdIsl8af=PYIANb8@m0tr~e-0O~dIr)<}!_ZIpA(OzmOpYuh+; z_<2X?6>p`rP9uW2ROb zcu=|q>$M`SD?;Lz#)QIRiDzo@^MwKi-sir*SPtfhu)ulU-&4V8#cr|e*mh!a%%HZg zM>1{9zUPj}X{|S(7+N9ov7n%{QnRc8u5^y6`X-NJJ->6e)%`u}>@)D_NllgL0k$Q!@)0i=uKx(@BgOv4vMBTjn{jv|n>#)yN?N7c zo}VTXZWHt5YX3arW7(mcOtcJejfVAC=BWk>Ei-$pIissfmR_A2S77Dpe@JFo)LdbO zHnG#AC#lBuj@=u`iEqTIKF?fylc?)aG86r*<`A;!F;F42165!rNQQpC(KO_y+0ppt zuv9w~fOaeG4ic~(+2b*WlWfA4;pdSP zW7mvaC0jRzv{JRShRWk$#C+CZFI;{3O@Nv{8!c zdbawJPIwTTM532s4e&E6e;yKp@#uTvlcy23TE_2`;+Y~QR(Q}ZBN($hk^@r3)G-m= zQQh~~d6j10q-G_CMM~HGMuTNXqVY%#bl3YLV z!`2(<>{&e7fTsvq(J)s!8`RIIs^Sxo^eo zWHbku5(`+AVL3cj^y#g`*IQl`RNTKbqiqnNRu$VApsP=YUNGgx3>S$N7F?u&HV@fD zq94>}3mo7EKLTtBK)b^fuvjz4310XVE9>O>^-%E@;wbQ zal>iw04N?O0IfYZm)CkYYEWH8!Jg6;JaUag+9A&cP+gsgv;-(05di(!QWq%%z{CY^ zrR+D~Mji&VVTW_*J>STOZ)wo0Bqo<3z8k&xT>m+nL%TxHk8l#Sj>Jg7gn6Nb-ds{t z$=8?6RBS90TEk0&J>;==S(Xr2Arykd>JiAgK=FJrmU-;zifvW1g*YBclKGr(b(9{r zb%9(_Jz&&@@T4g`%?gsYXM2fbK!+FFcs1wQc-UL?{M3gKD7vh1*L{(vus=;XsR=wt zBEUx*v|dxVO{+Gkn!JyBr9k@d5#`aQIpq$HN-CgbF8 zH3kadd)Io5ag^SJJivEb@)dBS8~Z_umat43ev_c;klS?Gpq>q!lE3hLsfd4t6?1#m zHE6SD*Cvph#&7I-Cz82_Df_ZwP|?h^*4fIH(wrMo4sQuxpWkvQHXl4dh#?bh(Gu*$ zvNgC`vEj}Q=p`9h52#?rvczEGcFUc0$NdsK+-cmKm3h)|$MYmHvx;=+S(<$7GzGhp zj*K?k{&3F|Ho>oVa90UQVdL$Y#Q8#`HL3M}@DtU-gt4*1K$_J{w2yo_tx)akY=Hu# zupsa51oV-^d85_V7Kh_po11S^B~)4yxHLoN-ADF)^&g`FiJR%ta~r3|MZFCQl58{W zHj8~J@t~&qc%I9z1RnY?e}t5aTB_4($Gn|40g(H)x#YSjv1%q2=<8?0t+YrI{VSm> zE=vn$_z_UCxb)WT^HXnHLk%S_xgZl|_*ZCGH7rtrMghb-L-P{vGa$Y5#myEC!VZ;> zo7!%T@OPSUiJf(mT>OD!!xvk}b%>%v#BuP(e1BlPR;WZnv>tp5){cgH(cZi$6Ly}t z&NzQC@4b+?lnDj=j7C?dwDa=#tg-|V*Q3UordeEuKgB|3co^1MP;hAY#=m#D;Y3fc z?X=dN>rjJh2k874b~ts9jfKqQ(~4;$aiYvh?7xt)>P@|UYRoCkc@(30Fal~mw*FnA-WD>yzg z#cV_O+f8r+m$L=K82!cTo7CfRxx7^yUdmV*qMQpWa!1fT6d;!foT$= zJsMbC#U-}FzoOs=Cqzf(Z&f1Xn@4NF$n{Xy9q~&)$a+HCVgDq!HHh|xv- z*F4Im!LF`HcwU+F!gmEmMAcvU?*pF5Y?Xh3r*&j29_nSl1RmU<^z;ml(WfchhrrMQ zX9sIDSL13vJ`+oyL7Id zwPXLq6M`Vw&%gM9PkJ8D>3c;HoypmiwluYLrLH8I1#kK2r`|Ph$yx5^x+@aD zYDyRnj0)At%(+-5DHHgm3$+p_dKOCrR2b)IDxxW0R12TZ{mm9S1Y5=LEfN#+ZIl1x88U@5;}Hk986^I(&QU!e$JM`;QAre z*!X!!3p}pl$5~WGP9j>wkVRxeoEcR+O#taxrQt!AjpCVBg2O%b!g-uH-XrJfMNQp^ zs`R~Xw!$vybzb9@*I$FbqC}=5c3>>?7WTXdG0qXQkQE-yNV%L;Z8hKy>9da`!CT_p zO4phjoD8w9Agt3R@dFZ^mka>`ktZILi#_$%PcSxxJZ@;-QFnI-B+2Utb_4$2F;4z<+cm z2J~)+8^ay#t5Vqd%ehtu38>KIBkd^Tz8xb@h*Xg2klN&dh>MctMp0XI-^%&LHscZ6 z-Z4A$$$g=g<+@Mcs7U)p#o=PWnimvfCP&N46+q}W5d9!`m5JfpYHn3WIraRDh+RL; zjZ>=4bBVlQsj1=*WilWwu=BE%&QPLgHimNjEZ7UP5?&+OawHIVCYD^;SfIKhsPEAi zZc~NpVx(%^QxzW8h4qRQPKP{1qE!MZYO}^m$ejd^q@)A#mO}o-aR-bvF3W!xgn8A5WtbkebCUOj==3gEI?XD!t*(@)d-%A{^yaiBhXqr%LUS2*Hn$Y3 zp_elpYC_4RbU#aHjCzeDd_DTOFSg6=CY3tXeTA@(6M6VIS2#HGn=53|`P~(A2mZ+w z*1=t&sbx#!hkufVbw;-TmW3Bff0l)!WNSM{rz1hD=yNj*Ey0_O=@692vvei`0ALcOpH*+Y6_mAdKM`Ixc6&qeO44>KA8Bzj`$*$i8;|m=s)64_UryEg&{rsDN2p7B&m-8ooq5LTmq-+vg!lIf zw(yp1uj=?e!kg#Q)^Q1FELC{nF4Rpo_4diKe{zN&|HB#15UA1sOU^b4fL#Mu>D4R& z)EvowwDioX|7hurC>DI0}$7I1wOkGp1sw{qih^rj=om0JP+2iKDdJ?iJzoaTLW@r8S^JeA(=3i z$}Y?$)QRS0;wW^dF!gbP6)ReRhU`cAdCs2J05#1d8^!~j<&}28TngR*{+%p)eyicU zoe}hobaMC@?KL>x?`E^y32jS*sU%?j3M?s^1Sd29ZlCg{rsxW-v`R8=-Dle@_XsDI z;r2O-o!+uS^Ab9X*edk`aU=v2-p&(Y*hb->!(w}abYu8WCBE45UnRc3yzKu_ANp^$ z&AEU=P2H0KaCx})fjGUSUK{48W3BdQc{rDf{`;VWn%T)Q#}G4cP0z3-3664V37)zr zS2+<_PyRFJm7BeLA)I`?cfH@Do$R^fUz+`gK}0zhh}K(zpF928nzhyluBIfY$cRNu z@Iq5e%ub$xvq!Hg$+jzsQmOw3nvRJ&g$R0BGaTO{{dq`F`VHRwrVXp`ywl=e;=c}S zdA)yi{lqFX-tF=|{vbhF%WvWC$+s(i*`abT3NdbCbS-(k67 z(99yhW|olYzQ7k5j7;OFsSScz4Ta zCnjo&xAnRq7)-fvDyyFBZc7%pAjfBJ?C%Xfos4%fl9z#xdI$+8doN4t`69jY z`QfVX7UOH@rh+PT$~Z5;uXA>Fxs3&%dv=DJDLZlxcrL!7({+qcr&hXz63WaSfK{;7 z-#Mq`Xr(aD^|E&?+Tbwo`iWdouKa!Sp&4W5znMU%|84^1Qs3=EdT5f|hluhGjxHfO zVQLTMLyJmgcJuw~L}fm6$7+Zr$8REAYsjq2*_0ph}N=T@{Ma{zDliYV{|_BMt2 zWayy`SZ9r#$QSjiP>eg(4{{}M=2Qsw0zLF~gshYFZD6rS`~TU)vt^67N$nlfGvAs9FxET&*3uNvxb*xLH?Hljb;9S5f$vOzpO2k}yyJR3 z1n)joUhv44|Iq~)v7lercw_OC^<5ijW)#mm=}aXy)B7NpP++{F_unHEpVj~C$bpvXS{4Nb7vE$tZ*?79B%$5zUf({t`BrLv_wx{bK<@vp0DiAOlQ{S zTkNyPJ0{VRIN^CL7+g$@e29JcbHp*d_LG1lCjn(tu@kY)h9qCL${oByxJ_fvJ6PG4 z$^Vx=pV$BwV)Mx~WT!%J@4bLlyncoVOtNgAst}1F!LF)+A?&g@;yldGKU%S>J#E@Etb7#L;kjaF_)(S5(5Hi($27)=Z;0zj)|eQT zwR)jO4wP}8&w;AcOrByCnNAm=FNC56$G(#~^wbav1+6)$!oyUSrj<_M^pgfw`pV^L ziOwaI=U5LmUMFK@Xr&I)11jwim%@1GBUWiR(?l@)+~P3qHQyF5D&5XjUKk!Zaez71 zw4KoW@1qq)rxy=SUDl30brUf?Ks{{*yA(sKP`dFAidHyN&apX9o3Cb*u|Zehm$XTh zCk@=ik(*v5dsZ)1j$Fnx2Nj@>(=GFHR5~xRap)-%lbk~-N7VJlzL4-wiFG*-Gw{=o zWwQW#N2U~#PsaPfglB74e;d7M6-wOPF_y`9u4f0WN26!rhed-*?3Ll6^Xv>!i=J{s zba}KfMRZw!I)8>ad(8*E*HRk~1bkR3hsdMA80Si2>4wwP?6Xk!B_^;_#C zRZSD8)~N)v8W#tQ)W<j-E@ z%vG19;S|JD71hHVFBtAVv`D%m@+u@8J^Zj#Yc==D4JnDFT6wR!qeGy^8IB|wTic#2 z63wVBI_ZUSa8khWK3BZ`1~`AwHW{6l%fh^Q6m; zck48`kpbDki+WFagaq3Q?6*W&V61O<|19fX^8BZ)6aBZWOZi>aDZg?#w0BfYzE^c* z;7Pcu>+o6;|6SFYexA72h9B>U*%8MovCXLltkG-d)tx=%Ei=~MT^rem_~AzYA3;U> zD6uNW*G`4_M|JRlrFnaIU1et<*{XUYSdof|Bdiz7TWKAIifO-?A)v7q2JW3zawVCv z|9zT*Z$R0&=nx1U#$#gRsvi=6mOxmY^!^4usmXm}ry4^MRhVdLC%sxdoWC0Q{i4UM z3Y-fAclVH{SMg2RXa{@TXyoh-ZPWy7T8-NH z*N!eiGV4AQ=KqCty2R;Bb=ojXFBT9LH&))!*Dux;8yfYQlbdY_Fhmf{1GMcr+*hYv zKRx)U$-*kO+OxRm#uV*8kgn_B&At11o_(6T;XtN*hTr`hLW<<5?O**I-*S4Iyo%6c zUUDtWTB3A^-N{RqK9c_ITE5AicSTq6H~H)h2i0bnp@pOi8)aSzHS1T6&+9%Kpa*^W z^;I!^L)SNoE(#XA(JBkkht_6qc4aJYy5Pww_-h6cW>9f0>oK$eU*@M&QHm1ict-we z{Sit=vWZ#X1rM5iLG}`YrFGF}^)l@Bx<~cs#3u+#R&*Pxhf?Tt=|o;E3}R#B?pac# zK041})&&sQ`Ok3-I(Q&$H98bIR|{M!c1nS_^|G=b!3S_UeNiJzV?HPN!gb+Ryow-! z&K^f&B6WS#%+(m45#0~)uru0!WAxd^gS8P8{~YV|b>CJkQrYd@#7xVPYu z|AB+oOmIcC7}43o36xB&K2?Ua>#v=x@(+V}dE-oMXu`b!wcs$Hz#jG|bA11E=Bs8~ zI#T=guWqi;*O6579`h36nAalIKHvSP2@M+?BS|5ZGSh^@F{D>W{vL!w#)({1t3+4hp_KMuvw7Tkj4|_H@40C8=W+TceC@C6?I;wa)4L*RPfD~Tn zGA9+M;51SysBu_X&^GbCDI5gV8!(&A7m*rRn^HxW=z1=|TGcczG*(<@&7n5gj|^q9 zW!Ig6esfH-DJmm$x7u;G=_KEGOE17Iw8^cp&x*QNGe7^Dy^p4o||!b)MT_rMK3Ev1&PA&xcg0xRkv# zranDYJFC%pbQ9k@2|sWsgZ18GsMBX57XCX5{vXuWGSzUYoB=PNQe51qKj|-zVO0xh z2#ePXK=e{PaFI_Cm2|M7i|LJ-LCjVF;QwLooF;(i1F=`vDo!5ZBt$#)0fBF~=)dr^ zvf<&c2M>P)R+5p`52x<9q);WNHx6m0evV9DPde(>Cw*h>yMfnn-?vZh5N9OAbazAt z8)NAs;fC7p@r6a|V(O^e{aM@!Y#t-(WlD_Ir&{EB!}@?uQ!MI27LOm(*;n(+5h)N*6DM3y9zD5vRQCzOOwH1#{baP&^G>z(+^=~(_5(@S%YkdY zK;9Q$tP_)L>q-o-0q+1db3f>OEF-_Ko76Xhk%=rR2^x{vS~70@B?AIFc~oh#RzK-- zg}(0qA`4`!HKaE=9zgfDCw@?;bqnXPyaei7utse*wG?z0C#wwEI=9pE#&#IWkMy(n zs!$Y5Ugk;KBp+ZM^S<`m=EMU|vTDvwu3oLa>$9}h`x6+qe}yqs#f~ueL4#XhKNMmn zka3D+B^4b!5}p#$o0uPf&rJRrG&K79*m-m0Oj1ln-F-;JMyF>z=cY>QTtAKVYstVn zQ?t!ILSZM@AKLiW%_0d0s#)%Kz2Gl3nO&t9C!)x`9FSYcjc|QFE#|W;iKRgrg^5jQkXXyLM2tx|mOb0Jhs|2N=6^?Ow zB5s_Z0dgWbO>-86A%!pb{D7FGc4F7qkrA0=+O|S^w-1GctyV?m70xN1qEA#@uU7RQ zk*+d{+=E_o{z2skOW;M3wwMZsVo#$DgM%dsqHD6Dak947(7=-HX{WslGqGvE5EaRG z0eD{(9iOLIG!GcPCXwFptyNXnSkQ?mVL`-g^fMMR?KC=(&98|JxxWSGKa7px?hqWI z)qc!Wl{9z*ZRZ-pu0G;>BZehnqaV7o#Tt6#$8@}V<6in?RIr${2QG}g$yQ0Rn#D$D zqiBflQ=xODA@n4FR0ILqvvVeKRVxV5-&!GTG04M3O4dXM&YmL>u*uwC9w#V9lTD~j02_#_2XQ{N?wx5Q-#+T}nAXdEfj!c7) zY;|ClljY|~((oSJ+X2TuBxgS4uT2+mL* zkg*F1-dS3)%IQ33nf31IRMY263VB{~ZnBkowx&ol>rFyahK}h7tr%4kT=-7>HS3^; zU{R~*dCJ`{{L}^Qc9cb*_9{=eCdBPuzPTJ23n@-@?V36(1ChVBZ$qXa9zY1UnJy)7 zJf^FfauS*O)zKN6dq*iibG@oNp9BzejPpJ==Jy1TlPsMAunQt!RxYcAelte5iV=?> zSQ>|IoS>;)CjJsEjPrh~h#P->qLFG}Q>L?yM0Vo{Vc8D;o(TNZFf zhi1=dr$zA_A5Ye6#aNmJ?@wRfvuX0x((ivOaXn-<{YzcwVAezeI_ zAOh0vb`4q^#dA=dJH@ajC%Cldp_`bygelMsLOSXJpB;9uK+9iIA5^vfUdBfLg3&Sk z=8Lk@;8B0jq1>FfPc<}WR^p?cS&R3_C}BeHdA}A=$FyLd&qV-4ib)U9dG28t>}R;k zc~eotTp}`~LZvH-_#Z@~Jp~?|=UwA^z{9ii1%G6cm3QWqg8sfA!D##cD;;Kf_$2Wvssa zIo`N;m+;RB7wb6cf1Q2|>VEZS!poeH03Fm6S$;7}xCK3y2Jp%{7$SXV7V2z5_*Xd> zCIZLGTll?z?(j7?;*;Pe{u44*?(a=B2AdKy?gl&z+Ml)@QknU_>v#P)sXXpV)!deL zqEq=0!~XH(Z38nD%r5}b=p201&z?tdH$9v`G{&4y?F<9P#6dQpO!8xQ7Q~8b(A0vbnW4dP{N2no03cIpQ%q&zL2wH z7)5HXMwQ48mabfgqQc29T(Nuw0f(J!$DJ}}=pQG3-hm&%?Rf{tmG|q}w28Fz`f{>C znh%~071ek*DpU2wCyN(&dij36mK_a@ps`&NcXZ+c0+nJ#Ke)`FIy-Si9kWX>Me69V zL`MP8@0au^1-U>&Dg^bqbp0-~hM-@kgGHj2j$n;iKM4W7i5{`i-uL-z&oADG)kLSaJGfp8 z6KFmw^6s~c?6GP)K} zsSNk#^RkpjyTZ!(lw{$xIl|lyM}%I?n|5TV5ge+&Ha>{{LkYJkR zBA>Q@)M7_-5kMvm0btpxtS8 zY)$WNRe}mn=Zape(e;ZSXACG)&%i|QC345E662m;BmqAkSNJG1!NYq2UzIN4vu$#t zuQ@Inmxxe>M-~(puW#;#G%$7p$oFSktd*3io649|+Y5RUheF#|Zpc;t^g~x`Z++!) z`npO>$H4Hs&ofF4vX;U$$|z>qVo#};Nky|Q*Mtaz84#QybAb~Yh+g1~S@jAN{{MJ4 z>Vz9zjY(_rML0X08VWRoa@=PE%03N^aI$*NRAPD7Hwcxh)=uDaP!|Dh??Et%aArDBxUQzz`)_2d{5S*q zNBF@)#HQ*s*_K6(C(&zGDW?&YwQFltN9~`FCxddkTl#9=a8?KP=}CPPPF`|a_{GeN z&wihEypT(9Sa>~X7s;!*_6}?5sjVa+rEd>L9Qa7$t>cDPMM1*gSIsC!uVfwd9Zx~! zWvpji0LMB|@5XGQapn-c%NB5|#xW(OW?fm4 z%#>=1L9q~()1Bg3GFYbh#bxSaGWS!$8e$3sh9vQ^A0=$oDdbXFFF0^7wF{B6I$q7< z8#h>er78B>Lhi6EqQoyABahgZCkL*EB{NHyVSUJuZ&nX^JcW3MXOjGQRJkh<*5|%! zjE(wH7_5VGO%$(|iM~@3ml-IH+1&P?;3pUTR|5ipeBqL=9zVocb#QB5!FN#SJ+Dg5 z=`l+dnA+4B=_H?B_ zfUIpRqAFiX*0ct2-uK-t#BtLm#r)#b37I@>2n$i2Cu{mNl~V^l)X{VFh#uP8C7n&i zlDqpQ)3G$hNp2`2U7q#4aQAy*d2&3)$|fQ{SM>cmX`_Dq$dFR%o+_%i)qhA6-kl2! zvtDH>;5D6?xL224raLk?J66C-p`2;dUpG5rY%;yNouL~mBp5kE6{*9}uER6}aIF(= zrl&f>x)b_eGQUK=YPl|$L$3~ghxDuSq)KhyW_^uRfwVST7P2gvRvMPrDKEaU{+ZthCKUDoj7ApLj3e$ z$#4FGXO9%?e0CNz413m}{VOwZM+GGbJLb>L;Uv28mFVl~bAvQFy(_IQy1-}sfr83> z`TZPh;a0++qX~EBB=H){s&?%gN{@>B`=-JwZ;f4lYO3{9U2$8Bu${EFnaZnPITsT& zqDwtgve;CK4#H;g&Bquqe99FToZ@!5!9Bzaz!oNBmWjyV%0ha?B6^6gB zA-!Ha#Zk6^cPD`g#^Sj)q&ulXbvU_$4}icy?E2%cYfP^ecTFtqx#lFx$uS3TvJGTRX6 zcB{zK8t~wD2Iwj60KoJphKv08wp)eM(m>i?<(XfCne6+Y{8H!sgzYAZ-Yk@Xzn3Kr z@c8iT&IUc;GD-Ehts`rc9d1q*`4r*k|4 zCW*p%@Jp~A&=^Wj?T5Mc^X8Gg4)(sMx9{7^YpH3GhJWD7Bj7IZPwz-CqkzSq`FQ_N z#Kndm&Hl0Jo6$e6O>aFohd=(HT*8 zTDz+!`)iJ@T3L#&VM^827HH~u(n04H6yI!xDV^@&^T|xJb^S`T-!CvcV+l7Sc47WG z%56p3Sqe^Cd(3%1MVrMa)la?SZ?NL#@3{Bqrg|Z-W8(6=h0~^b7V|o;tr3<>jgy~i z!+k_NC6_#vp<9di*_nsDHUZMK&b6n8*ozSYrj9d7e(dL2L+l!~Od3akQuUCNuJ*0FU(RMX_6)F*v2pT)Tc6aw_xJ5 z^?)0kxGz>g6R3m2tdCn&OP??V05sOQtqDD?8ATia$Q?I~J$9F$N!tX-(Ai#qR2~oD zry_RdCrsIJFnMaEXx2U`kFj|2f=RX_6G#T+xxW^^1^HfXY`*$yS!@pDe2z}w@Y1rH zfTF!n68K7R^r)4b>)?WiyT>)u#FJ^qz5_`ZS~meH165&fh5GJ)JEaX-(}rhKSZt9Q zz=ydUQGTVmc@|suGdCr+i<)M-~< zVUR}r96xJ0{rTqbhe@Iv<*0NQ_X?T_g6ooMJO0(0TM;9;gX~?MZGt#p+HoF>$8G=O zBjmUnPvr9RhK1WNwfoBp5Oi_j=|GLXRF0Pvs;!nahE{{)0dlx1NOAtBtkPPDuYbA; zr_z`gr@nUo#zc`kd9!j!;fXlS*8x4VMya&_6Cc6;*L(z3-H?mqUDHW5%zH6k^q5=! z6_E`kOEkWLIHyxrwU>v{X`QCYn1L80q`0@C-jWzd zNW?AY)rQ`o-@D$kX1Hp1hpmLqFr1Wa@m`KsbT%+ojgDSijd)ttG?v_o369gQKp>o| z0kN5wZx)!;)EJ_JLSx*$uspP7qna!txRQFE9RhE0 zEd#d`78SFO9tVl$T77AhT6l69uuXxlh+K3mE#EDc8rg5=<4qT4%2ax@2(&u(wNt>8 zVlsu#aff6S1jmFA0I3@ao*DYw zh>T5Wn<<)PB`fs)Hkh8;PRYUJiy?cA5?gp{0cJht4-icb%THvp66w>>st+HU@~}pAEnHpp;9%VfK{>rKs8?&`B#U-?HgC zC>!QB-j~MGTgo?_5}p1!-#2FQxDe-FzaSL0Ri^$HF}#XK@sIkB+%uE)wd?6;Ug(bu+_Eb(gU#UZs! zp`Xt(<8FEWoBEwuEtX4fsQW-l0 z|7MT2(&A9iX6MHcJ&SxyN3@Jv5eqdxUW-!@W5DAq^2oy* z^ltHZBwr+`dtY#k3V(@F1z#(A1{G(G*+1*uFv%M@Yy&YqE%oXC%%Bt?N$gfxz~F@- zJ0TS^#e;sngGP3S<>7|o6{oMX4jZpq_wd$T(;Kk?x8vA;Y=lu`Yr^8h#s)#ciZ%Ja*WmnIhyqM*s20cxT)?(s@}-GE z%_aRBGp#AKWwsBK4S9*>;mNohBuxVb3D?EzrK>OmFIxa~+;H*63970zI1XE?Ux)y8 zwPvC4j01SjtH(y>xbanr@@K;!J_bE5PmzNai0_-~b?vfKyZ^;2qmSKstNG**$B+D! z?%(XacgUM7(7hn6gm4j_cIjUl%3?b(6<(|O%uFwbjUHIpx+|uxZF-GBPK;8h%WHmn zS?HmIdsqit5&hOz4|8ozJ|2*FbQaJ(%rYfEg!ex`|KWrFe>o&?K6B^TH-FL15A^xc zYtM$^k_9?*$H|0KL~NnMajBfxDMbeOcAQWsBUnSuESilE8mSZ;rx~JUIVRh;-}ZXY zp?}FlHD@c%U%LFo%o(u)6b~eoA^WXu*hLZ9i}gg!Na_!p_`o61{xw~~wQ>?jAj%c{ zm14Q!$HD-q*F5vb*WX#O6>4}}TToJa`mGxQoFjP6G;;39#d-e$ztLljRKcY&HS1=K zK=0r}@1ppPRM+f=h$PE9XJOkk^RMJ}KW|L$2WMcuN1#Q)4<_k1joZd2TtZU79kt&g z_S;8FnUsV9XVT=@;|BroVe+|1=6JlNTjT1xyB&DyXmc zB>UbL61A)KZmVPI$0*%{l}1x(kTQH`@2yCeKo{sS+NCF_!#8`DuC}Xtki*JlV*kck zU!S+Zzx$-?$9Rb8C4-q{w~B%%esG6lr5x1Ggkhl>W}V*|Idvi8HatCNUdjyd zFNefVD$hdK)If>6^BHVTBa)$Ynl^F5Kp?h7Jgyi>Q$ZK8C+*}jVmTQ|;$6`xjYwGBF=($e-@v2+T?Qz&rhpi`${N2tWU=Wxwa9bV?Hl%CHdI z*R!&?s{riHbF_DxByaUEO@#~C=*3REh84=;hQAel_wrrCiIWP09QYH#UjJc~nfQYju|9H+iSn6OT32WCcV*>YDd-j*Cb zop|{510?iPAuVLfLN5IoywsZBm67Cv0$S11(?8Vd+wp=o!_JWtSmCoiCNH<_>ElGM z>_Su6GDOQdpuk|*Od!mh!E8At7fE=#!b#BXqH5Cf-BFw{$O+%ani{1Ys$m7SzFb_q zAy?BLmk6-p2T$NzZs^PE3JCTV<5<%6Hpp8CT*z|sSi$j4esPsyuyai1Q@^7&a9Lxha(;_U!PxGR`|i77&bFmzH;+}tviwPz6Ec@Fw*w{qJ@LA z!hUxQ^>%~;|TN3T^C&OW~CqA8d|-gklB*7 zD4vC*S585qjaZCykMDb3#v}55PHF$2_kKaH=rmkRL+|+uKFghdE3yD9{!HXCo+B+5 zmL3lE&4FhWs+VOs?~OcR6X8Il+iaQ)RN{fl5)WK8z;{9V&2nC-BJEHcfSjI+&vUZM z&k=kA#hslB$=!Gb#Zdd)v_=d;6SgX#*eq_Rm`VigV=1`GDreL}z-=fDofi3xT2_4Q z8pa}HzxC64rivAmAFa1PHbrc~hdUE(ztk|~g3b#O!;m5tU?1=Y)IjH%?;rnV!s}A1+Taa{SqU7|Gw`X8if2WbHK9PCz zqAvAnmzQ5&yTS_B?g*^@;6daR=Nk;kJ#;^No^D>&G^Kql7zIJfBM1I4HNyUTIFo zh8rx|BSo6+?p&wh^H>!h8D|P|>Z`q?a=NdhLUQlvA(zM;z=1-thwy^McT zn2pTo?mu!u!K66JTCrS=b>2Q>jXehspL1UZt77PTM8?y(93nBL}{xwmEZjRc?G6osQ^hzlJ}m=4dHaUNK|}I@?)l_z0TgjeX~2E!UAw z=150QcY7KZGC&wH9Kk)F@$ixc{&Uob0DgoD*yZ)GwINI~D(_vum(BcCk2v{1(5Kir zr-RXz{D&p&=HIYgL2Z|v4uy~YnFHRmkDK_99FX#tisY?}5$_l-=AkNj>Fe1(fo XE2a^BK!*P!+7%^vwHFo7EZ+PVqp$jf literal 0 HcmV?d00001 diff --git a/note/images/SpringApplicationRunListener.png b/note/images/SpringApplicationRunListener.png new file mode 100644 index 0000000000000000000000000000000000000000..84333c42fe66e583793b1d6aa35c428197455c93 GIT binary patch literal 5271 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 literal 0 HcmV?d00001 diff --git a/note/images/spring_application_run.png b/note/images/spring_application_run.png new file mode 100644 index 0000000000000000000000000000000000000000..b12727d1026d3261f5eb9907383923fd9125a64f GIT binary patch literal 38313 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 A+yDRo literal 0 HcmV?d00001 diff --git a/note/spring-boot.md b/note/spring-boot.md new file mode 100644 index 0000000..95bfea5 --- /dev/null +++ b/note/spring-boot.md @@ -0,0 +1,108 @@ +# SpringApplication + +启动程序首先初始化了一个SpringApplication对象。来看一看在它的构造器了发生了什么。 + +```java +public SpringApplication(ResourceLoader resourceLoader, Object... sources) { + this.resourceLoader = resourceLoader; + initialize(sources); +} +``` + +initialize方法: + +```java +private void initialize(Object[] sources) { + if (sources != null && sources.length > 0) { + this.sources.addAll(Arrays.asList(sources)); + } + this.webEnvironment = deduceWebEnvironment(); + setInitializers((Collection) getSpringFactoriesInstances( + ApplicationContextInitializer.class)); + setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class)); + this.mainApplicationClass = deduceMainApplicationClass(); +} +``` + +## web环境检测 + +deduceWebEnvironment方法用于检测当前是否是web工程环境,检测的标准也很简单,classpath中必须同时存在下面这两个类: + +- javax.servlet.Servlet +- org.springframework.web.context.ConfigurableWebApplicationContext + +## ApplicationContextInitializer + +下一步便是检测应当使用哪些ApplicationContextInitializer,这货并不是spring-boot的专属,而是定义在context下,这东西是在喜闻乐见的refesh方法执行之前留给我们进行自定义初始化的钩子。典型的使用的场景是注册我们自己的属性来源、设置激活的profile。 + +在简单的web应用场景下(没有数据库/mybatis),共最终引入了下列的类: + +![ApplicationContextInitializer](images/ApplicationContextInitializer.png) + +来自于三个jar包: + +- spring-boot +- spring-boot-autoconfigure +- spring-beans + +## ApplicationListener + +这货是典型的观察者模式实现,类图: + +![ApplicationListener](images/ApplicationListener.PNG) + +在简单的web应用场景下,系统共初始化了这些监听器: + +![ApplicationListener](images/ApplicationListener_used.png) + +## SpringApplicationRunListener + +就像它长得那样,就是用来监听SpringApplication的run方法的监听器。看看这货用到了哪些实现类: + +![SpringApplicationRunListener](images/SpringApplicationRunListener.png) + +# run + +从这一节开始,就进入了SpringApplication的run方法的势力范围。整个方法的流程总结如下图: + +![SpringApplication.run](images/spring_application_run.png) + +## 环境准备 + +相关源码: + +```java +ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments); +``` + +Spring里面的Environment到底是个什么东西,详细参考隔壁(Spring.md)Environment接口一节,总结来说,这货就是属性配置来源(比如系统变量)和profile的综合体。 + +### 属性来源 + +在web环境下共初始化了以下4个属性来源: + +- System.getProperties() +- System.getenv() +- servlet-context-init-params +- servlet-config-init-params + + +有意思的问题:此时servlet-context-init-params和servlet-config-init-params实际上是一个占位符,无法从这两个来源获得任何真实的属性,等到refresh方法执行时才会被真实的来源替换。 + +### profile配置 + +SpringApplication.configureProfiles方法: + +```java +protected void configureProfiles(ConfigurableEnvironment environment, String[] args) { + environment.getActiveProfiles(); // ensure they are initialized + // But these ones should go first (last wins in a property key clash) + // 默认空 + Set profiles = new LinkedHashSet(this.additionalProfiles); + profiles.addAll(Arrays.asList(environment.getActiveProfiles())); + environment.setActiveProfiles(profiles.toArray(new String[profiles.size()])); +} +``` + +active profile取自上一节中的属性来源,key为`spring.profiles.active`. + diff --git a/note/spring-boot.uml b/note/spring-boot.uml new file mode 100644 index 0000000..82f4ca3 --- /dev/null +++ b/note/spring-boot.uml @@ -0,0 +1,71 @@ + + + + + + + + + + +spring-boot +1 + +classes +qZA94hFdS0SLO4Ma0W4NXAAA +1 + +SpringApplicationRunListener +69VGSXSIBUW7p8ufeBl/9gAA + +/njh2Q/xeUGIf6Vw8nEdJAAA +1 + +clMaroon +$00B9FFFF +508 +96 +177 +59 +sdkNone +4NdjgA17bE2i/3g5wzvqpwAA + + +1 +SpringApplicationRunListener + + +<<interface>> + + +False + + + +False +4NdjgA17bE2i/3g5wzvqpwAA + + +4NdjgA17bE2i/3g5wzvqpwAA + + + + +1 + +SpringApplicationRunListener +69VGSXSIBUW7p8ufeBl/9gAA +3 +7pos0T+U7062k2pRb9krYQAA +vZkbhaFErUiZYOVv+9sHpwAA +030TeKKn3EuzD7i4zkelCQAA +1 + +void starting +4NdjgA17bE2i/3g5wzvqpwAA + + + + + + From 2089a9f7d43e71bb3b588dcba989ff2675f7cb7e Mon Sep 17 00:00:00 2001 From: skywalker Date: Sat, 30 Sep 2017 20:43:06 +0800 Subject: [PATCH 09/20] =?UTF-8?q?=E4=BF=AE=E6=AD=A3@RequestBody=20@Validat?= =?UTF-8?q?ed=E5=90=88=E7=94=A8=E5=A4=84=E8=AF=B4=E6=98=8E=E7=9A=84?= =?UTF-8?q?=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- note/images/EnvironmentPostProcessor.png | Bin 0 -> 11982 bytes note/images/start_event_listener.png | Bin 0 -> 10966 bytes note/spring-boot.md | 69 +++ note/spring-boot.uml | 458 +++++++++++++++++- note/spring-mvc.md | 12 +- pom.xml | 15 +- .../java/controller/SimpleController.java | 45 +- src/main/java/model/SimpleModel.java | 18 +- 8 files changed, 599 insertions(+), 18 deletions(-) create mode 100644 note/images/EnvironmentPostProcessor.png create mode 100644 note/images/start_event_listener.png diff --git a/note/images/EnvironmentPostProcessor.png b/note/images/EnvironmentPostProcessor.png new file mode 100644 index 0000000000000000000000000000000000000000..61af9944d58daef4de6f5ca7fc8841aac243a400 GIT binary patch literal 11982 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 h-)V`yrd`8o@qa=R($dLe*wza@V)>5 literal 0 HcmV?d00001 diff --git a/note/images/start_event_listener.png b/note/images/start_event_listener.png new file mode 100644 index 0000000000000000000000000000000000000000..dfbe55fb33d41d50dad07d2222880db02939b9fb GIT binary patch literal 10966 zcmaKyby!sG-nJ1CBm||qLmDXsh7#%SE@7lWx(5USK|;D)nxTgrq&ua%hwg5^(PuyJ zyZ5)>z5f7)`(W0=%&c`^=lQ!c7%fYtH)>q#677Abu3rL%;#vzq-!XEzf^AcC5mcgkp87gCimlgZUjqIm3`s(F9D5G z8{lyNtohQ(C#zlc^pncCz5c>+yR_i9iW9>7U5+{`tY~HtA5wm7X>@#J2jC$v5In~$ z*~8)f!m5(!lSpj*iCF)YD72uN5l3j@{t|d|_|TZ|yDj**?VI!r8S%4dxy%t5f&hO& z^@0aCYx>Vp;fqiOsu$0YQ_%ljn4aB3emre;dM@;6WS`D-JIGV(xG_Lrm(e&3zSxKI z*9Bfju~P1;R&~ttB=*%b>~!<^Kn13|oSXzG=Y61_JePaRY3XE#;Q%T&4aH)^`gFm6x{U^mKJPNOQV?HtuWIM;%!jGC}z}|Tc+XpT-#T8SDXQj`t z9Pr3H1)?R;IIMb$M{^Dar;4~`%()sG9^av+uN-;~WShT1GCXH|VWVF2)1|GE_7O&L z2ePsS$3;JUcN1}c21uIdX;=+p+q+$50XeV)Crs3(-{@daxR0tpD^RAwb{fUG8JiqBpU7L4X`@;hW&HZ z)$$#Ojfv65lMImE!4o>)+ z`EW6vIcFqIHf^w2XwM;gw*>3L*UJ^E>Tc!2xF)JH-+n+E{^Z&W6yqHX z_P%;RM_qIevX{m=gPgh!YeCHG4N%Qq5{EZeiz|@ni&Sr|~syHtr zGoee2rqu~?%lhHX%W!Z*{pOAc*2e06vaKo`<(rAs#JotY+nUoU{4$KK2FqVw=a@7hsM3=Afzv0Hym3e0z7N zDX!7(w68}srcHKOiJ#8-`{ZxO!KD>A+))*q(PFLT6pzzpmu@8Y z0R_(CW>U-}I$@V=4w7ARF>GUsMtCI&Xv)j+A3*Fkw=l4;mf4Tm_)rAs9tP=Ssvnd2LO_}1M@JSY!!v={l*Mc4cA-tV?V@m=^t!4?{EZZCNV zw5YU)Z3cz?b}>e#G_H=7(0YWm1+xIXiFa{eC@Al_F9a9JVY5Oys!3#J-g17L;DI|z z%V0O_MV2HrAczDUbmx3bvX;;+0~ELTE)yGe&lp)FM^^Ihc?7wo2cK?M20E&<)Y>L{ z9Xg%py{kPaJ@QmSq5)T?KO}pYneVLCyGo1qE-gymh=b0PB7L{4H`9cz1Nnc}A<6}Q zvd+M`xMYDYn1Wlzcvo}n7dE|{2bx8`7dMUCWzOeShQGmXzjnHi855egSzSxX9~2UF zHvqMG;YI=&O%Yoqfh;X&Ms!#QPdtJ{K$IVajWWm$qBXCU1Ms~rijG`wX&EF#wP>+6 zMztuqe-%>(S<IxHJ)hXeXSna)((UGS=Rk)MU^}@ewT*CnO}l}8_$o2R z@BUuUcvV;f%=^6SG&aA@aKK7l;*u+p*=d&3?^-b>Sk40OJqk;ci2K_JrC5{>M(&p`X8ocIAwY7kk=+w1`n7w7X~Q z<)R@10v0C+6ZkCx_;nnoUzNCHnS|T`!JgP>?(tr|=V9Ax6Jq`2dOXxcqYQBu1f<(W zLs==22F?422_E#Ol$V6E3gxZ6O2-ElI98|~)!lOCab7m??fFbB(CudLFr47<^jl-J z5S8$1$?l7``j;VZP%(xd=FGa1VOsom^fD~ZJ5QtYW6Fayzd=(N9~4W&(m5_p>MKJ9YEh*p3l2rLWk1F zMWwD=F=Tvut_QfGP8-CxGr=CX#t`@L)fti4Hg432X^;BdVPU}P4B=BmF^wM|8^M;j zAG~J&T+~95SAk8H?#aJ@p}eWVf1LEQEY;Yn6%m|PUy?&dPQi3I?eXm5lj8Ntu%%sI z++@bm77Sb!Il?RxX>Pklzja3ZY{ z8RF+m%ddYug%AH-1sZ(8SdAL*&oTaYq2j=v;yVA(Z35KO>3f|~K_FB4(A!HLK|Ukl zxypRnb<;#bYhDBe{D=-4Dlc&6)!5LSYLzTB{k&|Mw;j34#$lYF+qXJ5@Tx>CWKFKi}pST_)IKn*=oJs`qv|7Ug@vG&TXGSVtpd{o? zX?fL<cMQ_1078Q3J8d+>Tj@GP%CKJ3=7Y-&QN-1bhKq$AGs0M`96ZGsw@&yXNHzC1O}$; zBTr@rG3yC$uGW-ADwYgkmxG?I{>)Z4CM*O_C8CJPh!@@f(XC;C{Ln)CK%5Zqp z*oea@v^G?qj-Ls<%1S?*(q$sR>#Of^BvkmFBMG>Jw1gtXOjlTu^I7jWZYf@?nneG_w7?}Ojq-7e z&Cu&S1>Bbn61X@@uIwqZn~o@da7;1UZ6viG zM_UlAPc^{uz(M?NsGMjI=)Q%VkJ1js<5%S5?bFT<@5w?y5SCfHc~7>W0+M+i&WHEZ zT9r0GWT_$zg8{eWc`>E>x6K&L4aSF-+$f!B{B>^306v|<7jOoNj6bNj_7=Xm#d6wG z{(?a${6To~>Oo8GVn6^-fROOCm^&kuI{x$2EQ<$I;PSHXvIt0y?N-PI=6f_u8~J9! zImHb@UX6uoFgD2-N9WxGu&c{-a<5MIDtffDf>tm@uxcl(i715CfV!B~PECE^+sq#% zJ-ox(XGxQ0@T&J+B7~;?$;vw&Rc=~+r3oyKB5eNH1b!V=;o5=RJjnRKv#IFMZB{*0=jUP&>T1w9kRx zSo?v8UQ7o*!QX~j@Siz(77(8FZAm1O!?NYXTHdL6mmQ(2zKkZUBT9pyt_SSN82}Z_ z(y~Mv7Rx%1aYF1)h5Tx$B;SRq_Tub(L|1uV@5xSYx<*6NzBiDg}oL zVJfBc)(|y_JH3m%pPg^=I-axhp?`;h9J>>7dr$T*LO&7yjin-%1M8kt3S=OG+)-~I zz2HR|1)c{ZuMxrL<=5^sp|(I^poo5bTSlppNXTAaU0koI*Y2oR!_C*_y)q5z0$uK1 zLC@AQZ7wlrRiyC?f{OMSKeNH;O&rU2Y4pcUZT*~IyHzLK8zg6^HQWRmkw9l>bPaSX z;(IGEPiV9NJGJ#&xq`GFF71Zd``SPVBkFO;FK^=bFq=W} zs_d~DXfSEzNI->6n@}Vh)E)SQ|G+RRS&tinOsziwB%xxSs!q1m|Yom zODHfCv>eB~zTzl08O)yA7?2_6SEJtwc7yJ_8$^shL^la8O^TUX*HSBUds zsMV^uh6bd4Dc8K_&y|IXqD^oK@@`}vON|X*|1}0>l(xmE^7Bk$FB@T|b`hn4&NX*;dNwg%jj_~&D5OjK?p$(s73@mt0}*2hNonURo2;>Tg^1@Q2i zy#hyiuJTU?j3Hr!g-3E_*tg5D3zP+&ra)s{Wnd${Vp#Q~yJMhvZmuPfC}U}jv&EenJXvu0+?fv=M-a3nWJtZ#Ecx_E? z(6M4PfysLMr>qv`OW)*erVjHb{_&LuS~g0gxl7h@AT13RsLr)|IE$tYoFvF;|0anx z+wk95^1n#&Z;bJu7j_>uqQV_>HH&9@D23ka&X!d=!(Mbp?9mtu0_DRucNE*zJv^l8 ziPKC}wu@LIM5(k%lS`);Z&p%LZ;t@Ulkt+%u!v8=O{hW$@m@V&2lc>O(JM30idTczT5zjU$*x5}R;!a@_ ze+aROs&)Hp+%)Rkd9hbTo_gPUDZ_e~gzfA0`S$Ygjo`PS-lYAz`$F7Q4TAbnX7dkX z_`C*t=6ym$@XOQ#_WjqHT=W|TlnMvymTHt^&;@aL8OU2QwIb>*gq^}!M62Nh{3d*2 zy^#bR{l_$|3#VhMTEI5+LvIo@ha3CpHZ00t>zKA_>lZPB$`f%0}vrY`W{RMRoW_28#^ zyP}{7KWXqE6T&3SwJ|Ta0M7nu0Val(_8pXR)i3$+5NsIpagY6lBoN%Lc3uae&`GCOxMYw zsJ4#c2Ks}D*`nH#U&O-!cC^$cTCu*#>*f1$| z^Fx9fz?aJ=ckN_}fcO=gIn0%*)QctJ*TV2GfU3Nr1E(IxonOP@V;Kh7M^yJC#6&;cg21uv%1ib&U%=w8fn>>|v zHz2B=RuHc5;oM6rYf4>2DTx-Z4s^*Vbiz?>b>jQG!Y-6W+NpQ#)s#5nk?Fh;4*x{+ zI_?2|qBF{tKXGrI_yfo8HQy?3P8hK&2m$CC`>oKw9z0%E^H;nZME7X)FcSXZglt}b z;M~cV^{4ET=KG%?sBTrYlE#oED*b?x->NkfJ5N?^zDI2Ptx|6qhJ~oGlLS^anT0um zZC>tC$B;A2kW6LANaXdTk}>zFLJXL5y3w%!r@>}tk4x7Ny)p%rmK5E`z;3_j(CTjCn?+dRv|rl%U#D85o|_wuD|9+Nt{NhIt*3)S?fifbDhop} zk8E{z`<(99*W!G$?EGpl;O&)fWyhWFHJuGTxGKy<`&I`f69w`6=+>5|rPD0!pEQ>% zjpKY%$CIt18EnfHn$#y)pfO98QW*<`xKFe}89pJldgcH_*^=asTdz-9*@PA=ZXna9 zdf`l!8!O*OgYmX zl+Vca+&L0~NH4L<%&2U9A0-1xX-jrzC2oeD{%at@5wXKZoW{3SDWmgTn(c7FO3}D>{hj#Z^m2n|`aq;x(QfAE z+)BK!ttwM1Q2>qE&Tk9Bd-f-LC+}8{zUI$UOk$YBd_9dnR~)NsoB~<*)?oM%{}RTH zf5P~T+6$&lzsOsZ%cL0jj1OyfG2lW{#im{~aqNlhf_MI8(VQ?cxcfe;y4~}tMdWwz z#-c z>WBx7Nuga(CqqHx=wTVNK`R|x@H~dkU4?Jt zd1TVc)UQ{~13dPh98!JYHh#U1b%r^eur`Zl;D3j={B{x(XkU_Y%bkJu6nlpB)Ub0@ z&nELkf$u<&P40dt&coR)c!Ip_Xh>UlwNhz9kWO3Zzu0?ya0dB^$F6Vla4MaStX)CI zw0+sh?Z+lMc=YaH6;E+`uVMbya4h3?-3!wj;OE#eBB*~SXh1&LpCfKpyi?qlkPN$A zLz``DLLMCS{iY*jO!&hdN9h&~WlEPsOlTd^#PHa+SKB$L)0m@OobfF$(FXmk=3~Ws z(kSsKEsl)NJ~W1PW`c!TGY_}Q>UWOGSLAcsN?c;|9GQ(AjJ7SnruG@2W%?RjC4y}Dknf<5b! zWBnui=UvH|t?QG+Z{LcAv_785n4w)`99YQ?$`&TQETu;ZJktmD(jfh_!9$J#3Q3ui zqg4Xm9FwKZ31ur^d<09|iPkAIn7in)Kno0Qu%{d@nX}&sf%CAKb2s_Ibxamr)I(G~ z;!1@hf?~aA)&AtTKHb=~dl)@pT)&1m%J9vrLemLtV;eva*-;L?q>gICTY{j%ep*)} zi}tUrs*X==drY4i?nuA+UrG0eQO?sE%0&Nm$?79zYKv4xM|ZPsc=hD4A?SVAOJs_R z`@GZkVkJud_6caLHiac-6EOI__&AfT-*HAzPXo(bIr+CD6O9;gN!G`gT=HADn8Kr) zJ$Ko?cqoZW$bb`9^&WhA0;n8ZBlI(#o@%XJPE3g9p8Xyg1$$EO^sHz|xl}ikW!G}|kHd;WipC*WCH zh$v|%u~#V;ipgsoBX{Bm zeYZ23W?*q?fb4c$?~01lc_yjZjGS2kW$r9fZ}NRdW17`D{I&j%yw@-~TrLqzrjvCr zN}d9>xhjYFsu<%|KYLN)_($QU?&$aEA(COQS+ATbmsk9&!t*X_-dsc-o#W@(;s9x8OnYHWMHVXNrEoqK16?0p|wZ1rvJZ%o~H>bEVMXY@)*un zQaoPtF8*qjV&2&&R%MGIRbQyAuK9m8c(et$!3$3Oe+FN#o!TJwsi1t;-UgA$J=rqp zgB*jJ_ooMdoLo}3Y(Cs<>o1U?^eRyq{kt|)|nMTc5bMq z`n4`VPMn~^=+@?0Cwde3Xf=OKX_58S;d=+LfB<5nau1(oxvCY6SY1Vi+oisojec zbKfssba}+NGk)+RzwZhy4h9B{AxtEwX&+xmz4o>g@@Y%h za?;%+U@K=Wh^A{f1DkW7qQ4DU!|oUke;BCpJ3D?CFXbr_7e;Za!l1V`nbMnZcla3g zGupMRdKC}Rhqng-0o~~Ly#UXOst$xK>|;};es2{>v&p_;sqi7dLj9hJzwRx-+9w|} zx#WNrDw64X#Ahwc?|)&Anr-yVs^TB?k-=DBVaxPc@yucBKu~*ePyNr5kxaTAeqXfnz=+^Cg}*+S&=q#dJB`tjq=q;5p6OxGfC- z3HS+dF^RpjJ|DdKs~Xb8T@jlKX9Ax?&ZTHN&clxhw1%v%xm144ts+TH$e#|Vfh{!Xa186lm#HKRP_ZzB zFrAy>-U%_|^qg;CW3w-wEBdd+0+YMbKQT!+oJsu50d64j1urydoQNDwA->*f?^NR# z(QyY4^BvVTkzl98sq5p&#Z`z_^Gp%zP8TEa3I^-FL*I9EBg|?_qp0$z4RPtQRSGV9 zC6PC%y&SPmI><;opfn)t!ri7h@^bp=c1p(>$iEd5FR6?Tr(CT&BQAn8lh@PzMUP4Q|)zZu_0fi+6Rc?^(fb-A1zj&?jK0U54 z{!Q@~icbCXXP^qP&?^4Ni8oYtG$5a-#!jqRy-YdyPqD!MXeoybIDG|1ozN~{dxd=eJ$*tacI>@CqjGcw6xGTtb(F6Z ze^Hv!rWy*FErKfTcS@UWqZhhBbPA!l_bxk*p_@uU)-_@d8OQNiix0ciDSsdae94Qc zmLOGvKdDSAi5VY_VIfYzas;2W#{a-VcFX<&x#Je@6&?0B(k%B*_Uee)!?$+lnCW=s zX>7kpzBV?1%MYkDy>(rDdrB_+U=~&p5)!n^w|gXAdXLadypyFCUFUf2Go3}j&n>^m-{XX&jEA4_BIBVVAH2Ev__OEqh7;TDC^ z0LfU$!(*ae5Dc%RwzCXB$qVD3Mzc(=9IRtbW%o;bEY}a@2|ayPhDwKq$bLBA5Ja#j zryP>icoXYJIz?!x(9+`5Eb_n2H1Lmsb`BT!dI;XPJ;V>^EoAlv4cqlr*2up{9YYVgX~-JZ zlL>UqKIMtBxZC<^n6oAQi*{Z^H8#5_r~ja#Bz9x)&*|SZ)7eB!u8t;+j)}RNu4%S6 zle1PPx4pCWd(=H!;xe6O1(kIqKslnfQIp5{q^Fqb*^onci&RWo#>JcqD=L;?-h{;z zjhp0n(6Njo#cw(Y*<9I$amz2M=>?voQfz9Tq<^Jqt$$iU^{M24*nX~H zYRYZ~bhF&VoZ;3}{3}GctdniJt!2DEYr0R}tLxRz13*>O);$jZ5i%hibc8vQi`7Uq z`=Iw#=6Q^7=}9{nOSz6)8O2S<(2f7EI68eZ$|#-Jm)<4lFsDw6aT3k2~N zUwqXBW04N!sNUqsj$rRwiL__69p*L1ER!GNYZY54dMvmnG`$4eS_e*~yDb$MMs(eb za|M~~yAb=4JQJ18$2W2k2Apo{=oV%2ll<-y;KX&eVH{L- z!PJAqaj>a(L-SbqzO!Ak__YK{_|N*9Zd>!RzU?37%bq=+meD~j<)YNPNvWr*PyW%6 zD1MkZFsQO{6X556A4z5^4CH(xjE3aX<5+L=XWFuN-vq~=?6s|nmRzlnP3p@JHlLO2 zV(d!pb1PApiW%e54}cp7Jn0EBn)bDtiGIj(3V!$}T+rR}6#(vpT-_0PZNFRKgp#!dZb>6y4n~{B0t)Oh{KnF# zt{c}~&!=OmmdT1U-q9-DWurHgq>&D6=p5MRugM%K?Y_bk{NhghnO$DNITc090F|%^ zrcy}pSI<+e>!Mi|C5jN;KQT95@(UHPvsi3L%4DyTVOPGFtL|g|`^4k3sHW5`_*2^? z|4VHn9`#>qo1QrBON#0@eS@@rhD7@n!X<-G+fonoODz%c00!eXiq_!fH5@!&(S7Ae z{^kkf{b8*18qhzO?PJ(^-7v$8XS&~7rh0G? zn?&-oiI#gksa{`-zq^RX^!wfqG1_OfyuWYPoK}C<2|p0Bze1ogytn!1h0aIRC*4mq WB-={9!0$;#kdaV)U;572|NjB9hOeXm literal 0 HcmV?d00001 diff --git a/note/spring-boot.md b/note/spring-boot.md index 95bfea5..c30c11e 100644 --- a/note/spring-boot.md +++ b/note/spring-boot.md @@ -67,6 +67,24 @@ deduceWebEnvironment方法用于检测当前是否是web工程环境,检测的 ![SpringApplication.run](images/spring_application_run.png) +## starting + +SpringApplicationRunListener其实起一个广播器的作用,将消息广播给ApplicationListener一节初始化的10个Listener中的某几个。 + +debug可以发现,对启动事件感兴趣的只有LoggingApplicationListener一个。 + + 当LoggingApplicationListener监听到启动事件时,所作的主要工作便是决定采用哪一个日志框架,其判断逻辑如下: + +- 如果系统变量`org.springframework.boot.logging.LoggingSystem`存在,那么由其决定。 + +- 依次检测classpath中这些类是否存在: + + ```java + ch.qos.logback.core.Appender; + org.apache.logging.log4j.core.impl.Log4jContextFactory; + java.util.logging.LogManager; + ``` + ## 环境准备 相关源码: @@ -106,3 +124,54 @@ protected void configureProfiles(ConfigurableEnvironment environment, String[] a active profile取自上一节中的属性来源,key为`spring.profiles.active`. +## environmentPrepared + +### 配置文件加载 + +监听器ConfigFileApplicationListener负责spring-boot配置文件的加载,ConfigFileApplicationListener默认会从以下的位置搜索配置文件: + +1. classpath下的application.properties或application.yml +2. file:./下的application.properties或application.yml +3. classpath:config目录下的application.properties或application.yml +4. file:./config目录下的application.properties或application.yml + +此监听器是如何加载的?源码: + +```java +private void onApplicationEnvironmentPreparedEvent(ApplicationEnvironmentPreparedEvent event) { + List postProcessors = loadPostProcessors(); + postProcessors.add(this); + AnnotationAwareOrderComparator.sort(postProcessors); + for (EnvironmentPostProcessor postProcessor : postProcessors) { + postProcessor.postProcessEnvironment(event.getEnvironment(), + event.getSpringApplication()); + } +} +``` + +显然核心的加载操作是通过EnvironmentPostProcessor接口实现的,此接口允许我们在context刷新之前自定义配置加载,并且Spring推荐此接口的实现类同时实现Ordered接口。类图: + +![EnvironmentPostProcessor](images/EnvironmentPostProcessor.png) + +加上ConfigFileApplicationListener自己,spring-boot默认共初始化了三个加载器,其它两个是SpringApplicationJsonEnvironmentPostProcessor和CloudFoundryVcapEnvironmentPostProcessor,下面按照其优先级顺序进行说明。 + +#### SpringApplicationJsonEnvironmentPostProcessor + +尝试读取spring.application.json或SPRING_APPLICATION_JSON系统指定的json配置文件,从这里加载的配置具有最高的优先级,当然,默认是没有的。 + +#### CloudFoundryVcapEnvironmentPostProcessor + +从Cloud Foundry加载配置,这是什么东西问度娘。 + +#### ConfigFileApplicationListener + +这里就是加载配置文件加载一节所说的配置文件的过程。 + + + +TODO: 多profile配置文件加载 + + + + + diff --git a/note/spring-boot.uml b/note/spring-boot.uml index 82f4ca3..70da408 100644 --- a/note/spring-boot.uml +++ b/note/spring-boot.uml @@ -13,7 +13,7 @@ classes qZA94hFdS0SLO4Ma0W4NXAAA -1 +2 SpringApplicationRunListener 69VGSXSIBUW7p8ufeBl/9gAA @@ -51,7 +51,322 @@ -1 + +EnvironmentPostProcessor +69VGSXSIBUW7p8ufeBl/9gAA + +qm+rHb6SNkqLBiTGk7pzbwAA +11 + +clMaroon +$00B9FFFF +576 +68 +494 +59 +sdkNone +yKVxOflA2UaI4FHsb8TGJQAA + + +1 +EnvironmentPostProcessor + + +<<interface>> + + +False + + + +False +yKVxOflA2UaI4FHsb8TGJQAA + + +yKVxOflA2UaI4FHsb8TGJQAA + + + +clMaroon +$00B9FFFF +232 +236 +267 +43 +jCjCGZgJxk+c3RZE5Qq57gAA + + +1 +CloudFoundryVcapEnvironmentPostProcessor + + +False + + +False + + + +jCjCGZgJxk+c3RZE5Qq57gAA + + +jCjCGZgJxk+c3RZE5Qq57gAA + + +False +jCjCGZgJxk+c3RZE5Qq57gAA + + + +clMaroon +$00B9FFFF +619 +236 +288 +43 +W0cRRKVVBkCp+2Q9SH3UxgAA + + +1 +SpringApplicationJsonEnvironmentPostProcessor + + +False + + +False + + + +W0cRRKVVBkCp+2Q9SH3UxgAA + + +W0cRRKVVBkCp+2Q9SH3UxgAA + + +False +W0cRRKVVBkCp+2Q9SH3UxgAA + + + +clMaroon +$00B9FFFF +1027 +236 +173 +43 +Vw0ZAZppPEm7AlpNNggtGgAA + + +1 +ConfigFileApplicationListener + + +False + + +False + + + +Vw0ZAZppPEm7AlpNNggtGgAA + + +Vw0ZAZppPEm7AlpNNggtGgAA + + +False +Vw0ZAZppPEm7AlpNNggtGgAA + + + +clMaroon +$00B9FFFF +360 +68 +86 +59 +sdkNone +7GxYzq4AIkizabw6oPygqQAA + + +1 +Ordered + + +<<interface>> + + +False + + + +False +7GxYzq4AIkizabw6oPygqQAA + + +7GxYzq4AIkizabw6oPygqQAA + + + +clMaroon +$00B9FFFF +370,236;395,126 +4SbHHRophkuTs8QFsOr8fQAA ++k8WnQ0zkEC8VT9QQz9+OgAA +P6KG9fgsi06u+3WM6dvcmwAA + +False +1.5707963267949 +15 +4SbHHRophkuTs8QFsOr8fQAA + + +False +1.5707963267949 +30 +4SbHHRophkuTs8QFsOr8fQAA + + +False +-1.5707963267949 +15 +4SbHHRophkuTs8QFsOr8fQAA + + + +clMaroon +$00B9FFFF +425,236;739,126 +yYUBNggzPUG/3YZMjF72QQAA +lqFX6n755k6Hba7ST1jy1wAA +P6KG9fgsi06u+3WM6dvcmwAA + +False +1.5707963267949 +15 +yYUBNggzPUG/3YZMjF72QQAA + + +False +1.5707963267949 +30 +yYUBNggzPUG/3YZMjF72QQAA + + +False +-1.5707963267949 +15 +yYUBNggzPUG/3YZMjF72QQAA + + + +clMaroon +$00B9FFFF +715,236;445,116 +sdi/nrb10kCJ64hqARaXWAAA ++k8WnQ0zkEC8VT9QQz9+OgAA +E4P16TqYkUG2+qH+WaJtbwAA + +False +1.5707963267949 +15 +sdi/nrb10kCJ64hqARaXWAAA + + +False +1.5707963267949 +30 +sdi/nrb10kCJ64hqARaXWAAA + + +False +-1.5707963267949 +15 +sdi/nrb10kCJ64hqARaXWAAA + + + +clMaroon +$00B9FFFF +770,236;811,126 +fzumzPlz/0iBgpfrrvOhJQAA +lqFX6n755k6Hba7ST1jy1wAA +E4P16TqYkUG2+qH+WaJtbwAA + +False +1.5707963267949 +15 +fzumzPlz/0iBgpfrrvOhJQAA + + +False +1.5707963267949 +30 +fzumzPlz/0iBgpfrrvOhJQAA + + +False +-1.5707963267949 +15 +fzumzPlz/0iBgpfrrvOhJQAA + + + +clMaroon +$00B9FFFF +1027,238;445,107 +rG+WOaqFYkG6GXUZeUtgRAAA ++k8WnQ0zkEC8VT9QQz9+OgAA +3yHZR7jfDUqU/q5rcoobfgAA + +False +1.5707963267949 +15 +rG+WOaqFYkG6GXUZeUtgRAAA + + +False +1.5707963267949 +30 +rG+WOaqFYkG6GXUZeUtgRAAA + + +False +-1.5707963267949 +15 +rG+WOaqFYkG6GXUZeUtgRAAA + + + +clMaroon +$00B9FFFF +1075,236;875,126 +WvChNZk63UG/CiWuRWPIIwAA +lqFX6n755k6Hba7ST1jy1wAA +3yHZR7jfDUqU/q5rcoobfgAA + +False +1.5707963267949 +15 +WvChNZk63UG/CiWuRWPIIwAA + + +False +1.5707963267949 +30 +WvChNZk63UG/CiWuRWPIIwAA + + +False +-1.5707963267949 +15 +WvChNZk63UG/CiWuRWPIIwAA + + + + +12 SpringApplicationRunListener 69VGSXSIBUW7p8ufeBl/9gAA @@ -65,6 +380,145 @@ 4NdjgA17bE2i/3g5wzvqpwAA + +EnvironmentPostProcessor +69VGSXSIBUW7p8ufeBl/9gAA +3 +lqFX6n755k6Hba7ST1jy1wAA +XWuGtHMimECYIFoc8Id7dAAA +PuXfMWbnrkmQIc3bXK6+QwAA +3 +yYUBNggzPUG/3YZMjF72QQAA +fzumzPlz/0iBgpfrrvOhJQAA +WvChNZk63UG/CiWuRWPIIwAA +1 + +void postProcessEnvironment +yKVxOflA2UaI4FHsb8TGJQAA +2 + +ConfigurableEnvironment environment +bqCtvisSyEimrYDDokeTzAAA + + +SpringApplication application +bqCtvisSyEimrYDDokeTzAAA + + + + +CloudFoundryVcapEnvironmentPostProcessor +69VGSXSIBUW7p8ufeBl/9gAA +4 +P6KG9fgsi06u+3WM6dvcmwAA +fwYEhFbAhUW3txmAgc6qEgAA +XgsnnzJS3kOgNGcfKe2LEAAA +7HVPFqKJv0OTq86odgxmrAAA +2 +4SbHHRophkuTs8QFsOr8fQAA +yYUBNggzPUG/3YZMjF72QQAA + + +SpringApplicationJsonEnvironmentPostProcessor +69VGSXSIBUW7p8ufeBl/9gAA +4 +E4P16TqYkUG2+qH+WaJtbwAA +HAwEJWdWF0eLnSxluskdBAAA +QFvkquiBMUiXeeNJe0VS3QAA +P6UaJPEPAE6fmOFcWEi3iwAA +2 +sdi/nrb10kCJ64hqARaXWAAA +fzumzPlz/0iBgpfrrvOhJQAA + + +ConfigFileApplicationListener +69VGSXSIBUW7p8ufeBl/9gAA +4 +3yHZR7jfDUqU/q5rcoobfgAA +sdZbRO+xb0uDTPgTM6Lz+gAA +KMRwxm47bUyte4AAmIEBnAAA +Mvw1MqFvQUW8zi2QVAw1/wAA +2 +rG+WOaqFYkG6GXUZeUtgRAAA +WvChNZk63UG/CiWuRWPIIwAA + + +Ordered +69VGSXSIBUW7p8ufeBl/9gAA +3 ++k8WnQ0zkEC8VT9QQz9+OgAA +qEDeKjCCC021n71FXBamZgAA +MSfclWLhBEit3GHQJwf2+wAA +3 +4SbHHRophkuTs8QFsOr8fQAA +sdi/nrb10kCJ64hqARaXWAAA +rG+WOaqFYkG6GXUZeUtgRAAA +1 + +int getOrder +7GxYzq4AIkizabw6oPygqQAA + + + +69VGSXSIBUW7p8ufeBl/9gAA +jCjCGZgJxk+c3RZE5Qq57gAA +7GxYzq4AIkizabw6oPygqQAA +4 +64DFsXJ9JEeMUdpHsp+BugAA +y4EYtuEhC0ejkpIFceijzwAA +ZqEP5ycHu0aULbvZeaAu5wAA +QZ3NELwfEEOEgDHx4Ad/0AAA + + +69VGSXSIBUW7p8ufeBl/9gAA +jCjCGZgJxk+c3RZE5Qq57gAA +yKVxOflA2UaI4FHsb8TGJQAA +4 +eMyi+V4XhU+fT2JcvxNy4gAA +0mI/GAzW3U2+8VVBXIA5cgAA +MpO/Kw7VvkyRo4J+uIMuMQAA +Fu8EySBCT0+2rffldBqC+AAA + + +69VGSXSIBUW7p8ufeBl/9gAA +W0cRRKVVBkCp+2Q9SH3UxgAA +7GxYzq4AIkizabw6oPygqQAA +4 +3KueoVb0B0GJo5g0vX1NwAAA +cY+m06Faz0atMYj13QVUYAAA +yGAvTLcEFkCW/6F7LIIqzwAA +4nqMprd7tk6rMmDSKpyW7wAA + + +69VGSXSIBUW7p8ufeBl/9gAA +W0cRRKVVBkCp+2Q9SH3UxgAA +yKVxOflA2UaI4FHsb8TGJQAA +4 +HEBTMl5oFUifogqi0PAFVwAA +vvwUyIq6CEaFxWnsUq45aQAA +91vML38v0km69tVVLw1gOAAA +oJZMrIQ9EEieSvWnR8uABQAA + + +69VGSXSIBUW7p8ufeBl/9gAA +Vw0ZAZppPEm7AlpNNggtGgAA +7GxYzq4AIkizabw6oPygqQAA +4 +LM843eYjt0C96pmFrb1MDgAA +lxiHS0IIwEGS3Qvj/RsQWAAA +1evGo2PIFE2NlPSch++0xAAA +uabWPM723027n3XYs7lbtgAA + + +69VGSXSIBUW7p8ufeBl/9gAA +Vw0ZAZppPEm7AlpNNggtGgAA +yKVxOflA2UaI4FHsb8TGJQAA +4 +EmKsh5dzpEicXS/RjKzVjwAA +DfiAwKtWlEiz8tMZurmB4wAA +JG6V5rxzlEyDNR1rZluiMQAA +eQzpRi6zz02EOalo8lsBVgAA + diff --git a/note/spring-mvc.md b/note/spring-mvc.md index 9a060e5..4361e72 100644 --- a/note/spring-mvc.md +++ b/note/spring-mvc.md @@ -1425,8 +1425,7 @@ public String echo(@Validated SimpleModel simpleModel, Model model) { public String echo(@Validated @RequestBody SimpleModel simpleModel, Model model) {} ``` -答案是@RequestBody注解根本就没有起作用?why? - +答案是@RequestBody注解先于@Validated注解起作用,这样既可以利用@RequestBody注解向Controller传递json串,同时又能够达到校验的目的。从源码的角度来说,这在很大程度上是一个顺序的问题: RequestMappingHandlerAdapter.getDefaultArgumentResolvers相关源码: ```java @@ -1434,4 +1433,11 @@ resolvers.add(new ServletModelAttributeMethodProcessor(false)); resolvers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice)); ``` -仅仅就是因为ServletModelAttributeMethodProcessor的声明比RequestResponseBodyMethodProcessor早了一行! \ No newline at end of file +虽然ServletModelAttributeMethodProcessor位于RequestResponseBodyMethodProcessor之前,但构造器参数为false说明了此解析器必须要求参数被@ModelAttribute注解标注,其实在最后还有一个不需要注解的解析器被添加: + +```java +// Catch-all +resolvers.add(new ServletModelAttributeMethodProcessor(true)); +``` + +至此,真相大白。 \ No newline at end of file diff --git a/pom.xml b/pom.xml index 7077852..d4cda3d 100644 --- a/pom.xml +++ b/pom.xml @@ -82,6 +82,17 @@ 1.3 + + org.codehaus.jackson + jackson-mapper-asl + 1.9.13 + + + com.fasterxml.jackson.core + jackson-databind + 2.5.3 + + mysql mysql-connector-java @@ -94,11 +105,11 @@ 3.2.5 - + diff --git a/src/main/java/controller/SimpleController.java b/src/main/java/controller/SimpleController.java index 15a4b7b..97a525f 100644 --- a/src/main/java/controller/SimpleController.java +++ b/src/main/java/controller/SimpleController.java @@ -3,13 +3,18 @@ import model.SimpleModel; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; +import org.springframework.validation.BindingResult; import org.springframework.validation.DataBinder; import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.InitBinder; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import validator.SimpleModelValidator; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.PostConstruct; +import javax.servlet.http.HttpServletRequest; +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.Validator; +import javax.validation.ValidatorFactory; +import java.util.Set; /** * 简单的Spring {@link org.springframework.stereotype.Controller}. @@ -19,22 +24,42 @@ @Controller public class SimpleController { + private Validator validator; + @InitBinder public void initBinder(DataBinder dataBinder) { //dataBinder.setValidator(new SimpleModelValidator()); - dataBinder.addValidators(new SimpleModelValidator()); + //dataBinder.addValidators(new SimpleModelValidator()); + } + + @PostConstruct + public void initValidator() { + ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); + this.validator = factory.getValidator(); } @RequestMapping("/echo") - public String echo(String name, Model model) { + public String echo(@RequestParam("name") String name, Model model, HttpServletRequest request) throws InterruptedException { model.addAttribute("echo", "hello " + name); return "echo"; } @RequestMapping(value = "/echoAgain", method = RequestMethod.POST) - public String echo(@Validated @RequestBody SimpleModel simpleModel, Model model) { - model.addAttribute("echo", "hello " + simpleModel.getName() + ", your age is " + simpleModel.getAge() + "."); - System.out.println(model.asMap().get("simpleModel")); + public String echo(@RequestBody SimpleModel simpleModel, BindingResult bindingResult, Model model) { + + Set> result = validator.validate(simpleModel); + for (ConstraintViolation r : result) { + System.out.println("错误消息: " + r.getMessage()); + } + + String hello; + if (bindingResult.hasErrors()) { + hello = "Ops, error!"; + } else { + hello = "hello " + simpleModel.getName() + ", your age is " + simpleModel.getAge() + "."; + } + model.addAttribute("echo", hello); + System.out.println(simpleModel); return "echo"; } diff --git a/src/main/java/model/SimpleModel.java b/src/main/java/model/SimpleModel.java index 6994a8a..94ea6ab 100644 --- a/src/main/java/model/SimpleModel.java +++ b/src/main/java/model/SimpleModel.java @@ -1,5 +1,10 @@ package model; +import org.springframework.format.annotation.DateTimeFormat; + +import javax.validation.constraints.Max; +import java.util.Date; + /** * 简单的model. * @@ -8,7 +13,10 @@ public class SimpleModel { private String name; + @Max(value = 90, message = "年龄最大不能超过90") private Integer age; + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date date; public String getName() { return name; @@ -26,12 +34,20 @@ public void setAge(Integer age) { this.age = age; } + public Date getDate() { + return date; + } + + public void setDate(Date date) { + this.date = date; + } + @Override public String toString() { return "SimpleModel{" + "name='" + name + '\'' + ", age=" + age + + ", date='" + date + '\'' + '}'; } - } From d148fd31c5995c8db719294f49b0ce2c2a51c0d3 Mon Sep 17 00:00:00 2001 From: skywalker Date: Wed, 17 Oct 2018 20:11:57 +0800 Subject: [PATCH 10/20] Update pom.xml --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index d4cda3d..68ddf1d 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ http://maven.apache.org UTF-8 - 4.3.2.RELEASE + 4.3.18 @@ -90,7 +90,7 @@ com.fasterxml.jackson.core jackson-databind - 2.5.3 + 2.8.11.1 From 6434e4deb62283cdf342fcee9af6e262bed95334 Mon Sep 17 00:00:00 2001 From: seaswalker Date: Mon, 19 Nov 2018 11:19:31 +0800 Subject: [PATCH 11/20] upgrade pom --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 68ddf1d..9152dfd 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ http://maven.apache.org UTF-8 - 4.3.18 + 4.3.18.RELEASE @@ -90,7 +90,7 @@ com.fasterxml.jackson.core jackson-databind - 2.8.11.1 + 2.9.0 From bb7a2c624f6f2799548846fe0385ccd170c41477 Mon Sep 17 00:00:00 2001 From: seaswalker Date: Mon, 19 Nov 2018 11:20:32 +0800 Subject: [PATCH 12/20] upgrade pom --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9152dfd..4722752 100644 --- a/pom.xml +++ b/pom.xml @@ -90,7 +90,7 @@ com.fasterxml.jackson.core jackson-databind - 2.9.0 + 2.9.5 From ed4ee98341b8a59c025d2f101fc691a25ff6dfee Mon Sep 17 00:00:00 2001 From: skywalker Date: Tue, 29 Jan 2019 10:54:29 +0800 Subject: [PATCH 13/20] Update pom.xml --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4722752..3992b4c 100644 --- a/pom.xml +++ b/pom.xml @@ -90,7 +90,7 @@ com.fasterxml.jackson.core jackson-databind - 2.9.5 + 2.9.8 From 57cc3aaa5d209302b2cee24ff8f81a25e4a90794 Mon Sep 17 00:00:00 2001 From: qqq19923 <18718185869@163.com> Date: Mon, 18 Feb 2019 15:51:54 +0800 Subject: [PATCH 14/20] add Table of Contents --- note/Spring.md | 102 +++++++++++++++++++++++++++ note/guava-cache.md | 34 +++++++++ note/spring-aop.md | 77 +++++++++++++++++++++ note/spring-boot.md | 22 ++++++ note/spring-context.md | 137 +++++++++++++++++++++++++++++++++++++ note/spring-mvc.md | 70 +++++++++++++++++++ note/spring-task.md | 24 +++++++ note/spring-transaction.md | 34 +++++++++ 8 files changed, 500 insertions(+) diff --git a/note/Spring.md b/note/Spring.md index 6424696..0d04abd 100644 --- a/note/Spring.md +++ b/note/Spring.md @@ -1,3 +1,105 @@ + + +**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* + +- [基本](#%E5%9F%BA%E6%9C%AC) + - [ClassPathXmlApplicationContext](#classpathxmlapplicationcontext) + - [构造器](#%E6%9E%84%E9%80%A0%E5%99%A8) + - [设置配置文件路径](#%E8%AE%BE%E7%BD%AE%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E8%B7%AF%E5%BE%84) + - [Environment接口](#environment%E6%8E%A5%E5%8F%A3) + - [Profile](#profile) + - [Property](#property) + - [Environment构造器](#environment%E6%9E%84%E9%80%A0%E5%99%A8) + - [PropertySources接口](#propertysources%E6%8E%A5%E5%8F%A3) + - [PropertySource接口](#propertysource%E6%8E%A5%E5%8F%A3) + - [路径Placeholder处理](#%E8%B7%AF%E5%BE%84placeholder%E5%A4%84%E7%90%86) + - [PropertyResolver接口](#propertyresolver%E6%8E%A5%E5%8F%A3) + - [解析](#%E8%A7%A3%E6%9E%90) + - [refresh](#refresh) + - [prepareRefresh](#preparerefresh) + - [属性校验](#%E5%B1%9E%E6%80%A7%E6%A0%A1%E9%AA%8C) + - [BeanFactory创建](#beanfactory%E5%88%9B%E5%BB%BA) + - [BeanFactory接口](#beanfactory%E6%8E%A5%E5%8F%A3) + - [BeanFactory定制](#beanfactory%E5%AE%9A%E5%88%B6) + - [Bean加载](#bean%E5%8A%A0%E8%BD%BD) + - [EntityResolver](#entityresolver) + - [BeanDefinitionReader](#beandefinitionreader) + - [路径解析(Ant)](#%E8%B7%AF%E5%BE%84%E8%A7%A3%E6%9E%90ant) + - [配置文件加载](#%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E5%8A%A0%E8%BD%BD) + - [Bean解析](#bean%E8%A7%A3%E6%9E%90) + - [默认命名空间解析](#%E9%BB%98%E8%AE%A4%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4%E8%A7%A3%E6%9E%90) + - [import](#import) + - [alias](#alias) + - [bean](#bean) + - [id & name处理](#id--name%E5%A4%84%E7%90%86) + - [beanName生成](#beanname%E7%94%9F%E6%88%90) + - [bean解析](#bean%E8%A7%A3%E6%9E%90) + - [Bean装饰](#bean%E8%A3%85%E9%A5%B0) + - [Bean注册](#bean%E6%B3%A8%E5%86%8C) + - [BeanDefiniton数据结构](#beandefiniton%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84) + - [beans](#beans) + - [其它命名空间解析](#%E5%85%B6%E5%AE%83%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4%E8%A7%A3%E6%9E%90) + - [NamespaceHandler继承体系](#namespacehandler%E7%BB%A7%E6%89%BF%E4%BD%93%E7%B3%BB) + - [init](#init) + - [BeanFactory数据结构](#beanfactory%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84) + - [prepareBeanFactory](#preparebeanfactory) + - [BeanExpressionResolver](#beanexpressionresolver) + - [PropertyEditorRegistrar](#propertyeditorregistrar) + - [环境注入](#%E7%8E%AF%E5%A2%83%E6%B3%A8%E5%85%A5) + - [依赖解析忽略](#%E4%BE%9D%E8%B5%96%E8%A7%A3%E6%9E%90%E5%BF%BD%E7%95%A5) + - [bean伪装](#bean%E4%BC%AA%E8%A3%85) + - [LoadTimeWeaver](#loadtimeweaver) + - [注册环境](#%E6%B3%A8%E5%86%8C%E7%8E%AF%E5%A2%83) + - [postProcessBeanFactory](#postprocessbeanfactory) + - [invokeBeanFactoryPostProcessors](#invokebeanfactorypostprocessors) + - [BeanPostProcessor注册](#beanpostprocessor%E6%B3%A8%E5%86%8C) + - [MessageSource](#messagesource) + - [事件驱动](#%E4%BA%8B%E4%BB%B6%E9%A9%B1%E5%8A%A8) + - [事件](#%E4%BA%8B%E4%BB%B6) + - [发布者](#%E5%8F%91%E5%B8%83%E8%80%85) + - [ApplicationEventPublisher](#applicationeventpublisher) + - [ApplicationEventMulticaster](#applicationeventmulticaster) + - [监听器](#%E7%9B%91%E5%90%AC%E5%99%A8) + - [初始化](#%E5%88%9D%E5%A7%8B%E5%8C%96) + - [事件发布](#%E4%BA%8B%E4%BB%B6%E5%8F%91%E5%B8%83) + - [监听器获取](#%E7%9B%91%E5%90%AC%E5%99%A8%E8%8E%B7%E5%8F%96) + - [同步/异步](#%E5%90%8C%E6%AD%A5%E5%BC%82%E6%AD%A5) + - [全局](#%E5%85%A8%E5%B1%80) + - [注解](#%E6%B3%A8%E8%A7%A3) + - [onRefresh](#onrefresh) + - [ApplicationListener注册](#applicationlistener%E6%B3%A8%E5%86%8C) + - [singleton初始化](#singleton%E5%88%9D%E5%A7%8B%E5%8C%96) + - [ConversionService](#conversionservice) + - [StringValueResolver](#stringvalueresolver) + - [LoadTimeWeaverAware](#loadtimeweaveraware) + - [初始化](#%E5%88%9D%E5%A7%8B%E5%8C%96-1) +- [getBean](#getbean) + - [beanName转化](#beanname%E8%BD%AC%E5%8C%96) + - [手动注册bean检测](#%E6%89%8B%E5%8A%A8%E6%B3%A8%E5%86%8Cbean%E6%A3%80%E6%B5%8B) + - [检查父容器](#%E6%A3%80%E6%9F%A5%E7%88%B6%E5%AE%B9%E5%99%A8) + - [依赖初始化](#%E4%BE%9D%E8%B5%96%E5%88%9D%E5%A7%8B%E5%8C%96) + - [Singleton初始化](#singleton%E5%88%9D%E5%A7%8B%E5%8C%96) + - [getSingleton方法](#getsingleton%E6%96%B9%E6%B3%95) + - [是否存在](#%E6%98%AF%E5%90%A6%E5%AD%98%E5%9C%A8) + - [bean创建](#bean%E5%88%9B%E5%BB%BA) + - [lookup-method检测](#lookup-method%E6%A3%80%E6%B5%8B) + - [InstantiationAwareBeanPostProcessor触发](#instantiationawarebeanpostprocessor%E8%A7%A6%E5%8F%91) + - [doCreateBean](#docreatebean) + - [创建(createBeanInstance)](#%E5%88%9B%E5%BB%BAcreatebeaninstance) + - [MergedBeanDefinitionPostProcessor](#mergedbeandefinitionpostprocessor) + - [属性解析](#%E5%B1%9E%E6%80%A7%E8%A7%A3%E6%9E%90) + - [属性设置](#%E5%B1%9E%E6%80%A7%E8%AE%BE%E7%BD%AE) + - [初始化](#%E5%88%9D%E5%A7%8B%E5%8C%96-2) + - [getObjectForBeanInstance](#getobjectforbeaninstance) + - [Prototype初始化](#prototype%E5%88%9D%E5%A7%8B%E5%8C%96) + - [beforePrototypeCreation](#beforeprototypecreation) + - [createBean](#createbean) + - [afterPrototypeCreation](#afterprototypecreation) + - [总结](#%E6%80%BB%E7%BB%93) + - [其它Scope初始化](#%E5%85%B6%E5%AE%83scope%E5%88%9D%E5%A7%8B%E5%8C%96) + + + # 基本 本部分从最基本的Spring开始。配置文件: diff --git a/note/guava-cache.md b/note/guava-cache.md index e9ed021..f729c2f 100644 --- a/note/guava-cache.md +++ b/note/guava-cache.md @@ -1,3 +1,37 @@ + + +**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* + +- [创建](#%E5%88%9B%E5%BB%BA) + - [数据结构](#%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84) + - [segments](#segments) + - [ReferenceEntry](#referenceentry) + - [初始化](#%E5%88%9D%E5%A7%8B%E5%8C%96) + - [ReferenceEntry数组](#referenceentry%E6%95%B0%E7%BB%84) + - [引用队列](#%E5%BC%95%E7%94%A8%E9%98%9F%E5%88%97) +- [put](#put) + - [Hash算法](#hash%E7%AE%97%E6%B3%95) + - [ReHash](#rehash) + - [Segment选取](#segment%E9%80%89%E5%8F%96) + - [Segment.put](#segmentput) + - [线程安全性](#%E7%BA%BF%E7%A8%8B%E5%AE%89%E5%85%A8%E6%80%A7) + - [过期/垃圾缓存清理](#%E8%BF%87%E6%9C%9F%E5%9E%83%E5%9C%BE%E7%BC%93%E5%AD%98%E6%B8%85%E7%90%86) + - [垃圾缓存](#%E5%9E%83%E5%9C%BE%E7%BC%93%E5%AD%98) + - [善后](#%E5%96%84%E5%90%8E) + - [writeQueue移除](#writequeue%E7%A7%BB%E9%99%A4) + - [accessQueue移除](#accessqueue%E7%A7%BB%E9%99%A4) + - [加载终止](#%E5%8A%A0%E8%BD%BD%E7%BB%88%E6%AD%A2) + - [移除算法](#%E7%A7%BB%E9%99%A4%E7%AE%97%E6%B3%95) + - [过期缓存](#%E8%BF%87%E6%9C%9F%E7%BC%93%E5%AD%98) + - [扩容](#%E6%89%A9%E5%AE%B9) + - [设值](#%E8%AE%BE%E5%80%BC) +- [get(key)](#getkey) + - [get(key,hash,loader)](#getkeyhashloader) +- [参考](#%E5%8F%82%E8%80%83) +- [总结](#%E6%80%BB%E7%BB%93) + + + # 创建 以CacheLoader的方式为例: diff --git a/note/spring-aop.md b/note/spring-aop.md index 0a6db04..4a6d4da 100644 --- a/note/spring-aop.md +++ b/note/spring-aop.md @@ -1,3 +1,80 @@ + + +**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* + +- [开头](#%E5%BC%80%E5%A4%B4) +- [aop:config](#aopconfig) + - [解析](#%E8%A7%A3%E6%9E%90) + - [proxy-target-class & expose-proxy](#proxy-target-class--expose-proxy) + - [aop:pointcut](#aoppointcut) + - [aop:advisor](#aopadvisor) + - [aop:aspect](#aopaspect) + - [aop:declare-parents](#aopdeclare-parents) + - [其它](#%E5%85%B6%E5%AE%83) + - [MethodLocatingFactoryBean](#methodlocatingfactorybean) + - [SimpleBeanFactoryAwareAspectInstanceFactory](#simplebeanfactoryawareaspectinstancefactory) + - [总结](#%E6%80%BB%E7%BB%93) + - [代理子类生成](#%E4%BB%A3%E7%90%86%E5%AD%90%E7%B1%BB%E7%94%9F%E6%88%90) + - [入口](#%E5%85%A5%E5%8F%A3) + - [postProcessBeforeInstantiation](#postprocessbeforeinstantiation) + - [调用时机](#%E8%B0%83%E7%94%A8%E6%97%B6%E6%9C%BA) + - [源码](#%E6%BA%90%E7%A0%81) + - [应该代理 ?](#%E5%BA%94%E8%AF%A5%E4%BB%A3%E7%90%86-) + - [基础类检测](#%E5%9F%BA%E7%A1%80%E7%B1%BB%E6%A3%80%E6%B5%8B) + - [跳过类检测](#%E8%B7%B3%E8%BF%87%E7%B1%BB%E6%A3%80%E6%B5%8B) + - [AOP逻辑](#aop%E9%80%BB%E8%BE%91) + - [Advisor寻找](#advisor%E5%AF%BB%E6%89%BE) + - [适用性检测](#%E9%80%82%E7%94%A8%E6%80%A7%E6%A3%80%E6%B5%8B) + - [检测结果缓存](#%E6%A3%80%E6%B5%8B%E7%BB%93%E6%9E%9C%E7%BC%93%E5%AD%98) + - [TargetSource](#targetsource) + - [postProcessAfterInitialization](#postprocessafterinitialization) + - [Advisor寻找](#advisor%E5%AF%BB%E6%89%BE-1) + - [适用性判断](#%E9%80%82%E7%94%A8%E6%80%A7%E5%88%A4%E6%96%AD) + - [引入](#%E5%BC%95%E5%85%A5) + - [其它](#%E5%85%B6%E5%AE%83-1) + - [Advisor扩展](#advisor%E6%89%A9%E5%B1%95) + - [排序](#%E6%8E%92%E5%BA%8F) + - [创建](#%E5%88%9B%E5%BB%BA) + - [JDK动态代理 or Cglib](#jdk%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86-or-cglib) + - [JDK动态代理](#jdk%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86) + - [equals & hashCode](#equals--hashcode) + - [链式调用](#%E9%93%BE%E5%BC%8F%E8%B0%83%E7%94%A8) + - [Cglib](#cglib) +- [aop:scoped-proxy](#aopscoped-proxy) + - [解析](#%E8%A7%A3%E6%9E%90-1) + - [入口](#%E5%85%A5%E5%8F%A3-1) + - [装饰](#%E8%A3%85%E9%A5%B0) + - [代理生成](#%E4%BB%A3%E7%90%86%E7%94%9F%E6%88%90) + - [Advisor](#advisor) + - [引入](#%E5%BC%95%E5%85%A5-1) + - [例子](#%E4%BE%8B%E5%AD%90) + - [自定义Scope](#%E8%87%AA%E5%AE%9A%E4%B9%89scope) + - [配置](#%E9%85%8D%E7%BD%AE) + - [测试](#%E6%B5%8B%E8%AF%95) + - [原理](#%E5%8E%9F%E7%90%86) + - [doGetBean](#dogetbean) + - [代理子类](#%E4%BB%A3%E7%90%86%E5%AD%90%E7%B1%BB) + - [CallbackFilter & Callback](#callbackfilter--callback) + - [Callback](#callback) + - [CallbackFilter](#callbackfilter) + - [回调](#%E5%9B%9E%E8%B0%83) +- [aop:aspectj-autoproxy](#aopaspectj-autoproxy) + - [属性](#%E5%B1%9E%E6%80%A7) + - [proxy-target-class](#proxy-target-class) + - [expose-proxy](#expose-proxy) + - [栗子](#%E6%A0%97%E5%AD%90) + - [切面](#%E5%88%87%E9%9D%A2) + - [被代理类](#%E8%A2%AB%E4%BB%A3%E7%90%86%E7%B1%BB) + - [配置](#%E9%85%8D%E7%BD%AE-1) + - [解析](#%E8%A7%A3%E6%9E%90-2) + - [原理](#%E5%8E%9F%E7%90%86-1) + - [总结](#%E6%80%BB%E7%BB%93-1) +- [拾遗](#%E6%8B%BE%E9%81%97) + - [AOP切面的坑](#aop%E5%88%87%E9%9D%A2%E7%9A%84%E5%9D%91) + - [总结](#%E6%80%BB%E7%BB%93-2) + + + # 开头 aop部分的解析器由AopNamespaceHandler注册,其init方法: diff --git a/note/spring-boot.md b/note/spring-boot.md index c30c11e..0993d3b 100644 --- a/note/spring-boot.md +++ b/note/spring-boot.md @@ -1,3 +1,25 @@ + + +**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* + +- [SpringApplication](#springapplication) + - [web环境检测](#web%E7%8E%AF%E5%A2%83%E6%A3%80%E6%B5%8B) + - [ApplicationContextInitializer](#applicationcontextinitializer) + - [ApplicationListener](#applicationlistener) + - [SpringApplicationRunListener](#springapplicationrunlistener) +- [run](#run) + - [starting](#starting) + - [环境准备](#%E7%8E%AF%E5%A2%83%E5%87%86%E5%A4%87) + - [属性来源](#%E5%B1%9E%E6%80%A7%E6%9D%A5%E6%BA%90) + - [profile配置](#profile%E9%85%8D%E7%BD%AE) + - [environmentPrepared](#environmentprepared) + - [配置文件加载](#%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E5%8A%A0%E8%BD%BD) + - [SpringApplicationJsonEnvironmentPostProcessor](#springapplicationjsonenvironmentpostprocessor) + - [CloudFoundryVcapEnvironmentPostProcessor](#cloudfoundryvcapenvironmentpostprocessor) + - [ConfigFileApplicationListener](#configfileapplicationlistener) + + + # SpringApplication 启动程序首先初始化了一个SpringApplication对象。来看一看在它的构造器了发生了什么。 diff --git a/note/spring-context.md b/note/spring-context.md index 585e539..fec3dcc 100644 --- a/note/spring-context.md +++ b/note/spring-context.md @@ -1,3 +1,140 @@ + + +**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* + +- [开头](#%E5%BC%80%E5%A4%B4) +- [annotation-config](#annotation-config) + - [BeanPostProcessor注册](#beanpostprocessor%E6%B3%A8%E5%86%8C) + - [AnnotationAwareOrderComparator](#annotationawareordercomparator) + - [ContextAnnotationAutowireCandidateResolver](#contextannotationautowirecandidateresolver) + - [ConfigurationClassPostProcessor](#configurationclasspostprocessor) + - [AutowiredAnnotationBeanPostProcessor](#autowiredannotationbeanpostprocessor) + - [RequiredAnnotationBeanPostProcessor](#requiredannotationbeanpostprocessor) + - [CommonAnnotationBeanPostProcessor](#commonannotationbeanpostprocessor) + - [PersistenceAnnotationBeanPostProcessor](#persistenceannotationbeanpostprocessor) + - [EventListenerMethodProcessor](#eventlistenermethodprocessor) + - [DefaultEventListenerFactory](#defaulteventlistenerfactory) + - [逻辑关系整理](#%E9%80%BB%E8%BE%91%E5%85%B3%E7%B3%BB%E6%95%B4%E7%90%86) + - [运行](#%E8%BF%90%E8%A1%8C) + - [ConfigurationClassPostProcessor](#configurationclasspostprocessor-1) + - [postProcessBeanDefinitionRegistry](#postprocessbeandefinitionregistry) + - [BeanPostProcessor注册](#beanpostprocessor%E6%B3%A8%E5%86%8C-1) + - [ImportAwareBeanPostProcessor](#importawarebeanpostprocessor) + - [EnhancedConfigurationBeanPostProcessor](#enhancedconfigurationbeanpostprocessor) + - [类解析](#%E7%B1%BB%E8%A7%A3%E6%9E%90) + - [bean名字生成策略](#bean%E5%90%8D%E5%AD%97%E7%94%9F%E6%88%90%E7%AD%96%E7%95%A5) + - [postProcessBeanFactory](#postprocessbeanfactory) + - [AutowiredAnnotationBeanPostProcessor](#autowiredannotationbeanpostprocessor-1) + - [postProcessMergedBeanDefinition](#postprocessmergedbeandefinition) + - [入口](#%E5%85%A5%E5%8F%A3) + - [源码](#%E6%BA%90%E7%A0%81) + - [变量扫描](#%E5%8F%98%E9%87%8F%E6%89%AB%E6%8F%8F) + - [方法扫描](#%E6%96%B9%E6%B3%95%E6%89%AB%E6%8F%8F) + - [bridge方法](#bridge%E6%96%B9%E6%B3%95) + - [PropertyDescriptor](#propertydescriptor) + - [postProcessPropertyValues](#postprocesspropertyvalues) + - [入口](#%E5%85%A5%E5%8F%A3-1) + - [注入](#%E6%B3%A8%E5%85%A5) + - [Field注入](#field%E6%B3%A8%E5%85%A5) + - [方法注入](#%E6%96%B9%E6%B3%95%E6%B3%A8%E5%85%A5) + - [RequiredAnnotationBeanPostProcessor](#requiredannotationbeanpostprocessor-1) + - [postProcessMergedBeanDefinition](#postprocessmergedbeandefinition-1) + - [postProcessPropertyValues](#postprocesspropertyvalues-1) + - [结果缓存](#%E7%BB%93%E6%9E%9C%E7%BC%93%E5%AD%98) + - [PropertyDescriptor](#propertydescriptor-1) + - [测试](#%E6%B5%8B%E8%AF%95) + - [CommonAnnotationBeanPostProcessor](#commonannotationbeanpostprocessor-1) + - [postProcessMergedBeanDefinition](#postprocessmergedbeandefinition-2) + - [父类](#%E7%88%B6%E7%B1%BB) + - [子类](#%E5%AD%90%E7%B1%BB) + - [postProcessPropertyValues](#postprocesspropertyvalues-2) + - [postProcessBeforeInitialization](#postprocessbeforeinitialization) + - [postProcessBeforeDestruction](#postprocessbeforedestruction) + - [EventListenerMethodProcessor](#eventlistenermethodprocessor-1) + - [入口](#%E5%85%A5%E5%8F%A3-2) + - [源码](#%E6%BA%90%E7%A0%81-1) +- [component-scan](#component-scan) + - [初始化](#%E5%88%9D%E5%A7%8B%E5%8C%96) + - [use-default-filters](#use-default-filters) + - [扫描器:创建 & 初始化](#%E6%89%AB%E6%8F%8F%E5%99%A8%E5%88%9B%E5%BB%BA--%E5%88%9D%E5%A7%8B%E5%8C%96) + - [resource-pattern](#resource-pattern) + - [name-generator](#name-generator) + - [scope-resolver](#scope-resolver) + - [scoped-proxy](#scoped-proxy) + - [exclude-filter/include-filter](#exclude-filterinclude-filter) + - [annotation-config](#annotation-config-1) + - [扫描](#%E6%89%AB%E6%8F%8F) + - [逐包扫描/BeanDefinition解析](#%E9%80%90%E5%8C%85%E6%89%AB%E6%8F%8Fbeandefinition%E8%A7%A3%E6%9E%90) + - [@Scope解析](#scope%E8%A7%A3%E6%9E%90) + - [bean名字生成](#bean%E5%90%8D%E5%AD%97%E7%94%9F%E6%88%90) + - [根据注解](#%E6%A0%B9%E6%8D%AE%E6%B3%A8%E8%A7%A3) + - [默认策略](#%E9%BB%98%E8%AE%A4%E7%AD%96%E7%95%A5) + - [其它注解解析](#%E5%85%B6%E5%AE%83%E6%B3%A8%E8%A7%A3%E8%A7%A3%E6%9E%90) + - [冲突检测](#%E5%86%B2%E7%AA%81%E6%A3%80%E6%B5%8B) + - [代理生成](#%E4%BB%A3%E7%90%86%E7%94%9F%E6%88%90) + - [BeanDefinition注册](#beandefinition%E6%B3%A8%E5%86%8C) + - [Component注册](#component%E6%B3%A8%E5%86%8C) +- [property-override](#property-override) + - [作用](#%E4%BD%9C%E7%94%A8) + - [类图](#%E7%B1%BB%E5%9B%BE) + - [解析](#%E8%A7%A3%E6%9E%90) + - [properties-ref](#properties-ref) + - [order](#order) + - [ignore-resource-not-found](#ignore-resource-not-found) + - [ignore-unresolvable](#ignore-unresolvable) + - [local-override](#local-override) + - [BeanDefinition](#beandefinition) + - [运行](#%E8%BF%90%E8%A1%8C-1) + - [属性加载](#%E5%B1%9E%E6%80%A7%E5%8A%A0%E8%BD%BD) + - [属性转换](#%E5%B1%9E%E6%80%A7%E8%BD%AC%E6%8D%A2) + - [属性设置](#%E5%B1%9E%E6%80%A7%E8%AE%BE%E7%BD%AE) +- [property-placeholder](#property-placeholder) + - [解析](#%E8%A7%A3%E6%9E%90-1) + - [system-properties-mode](#system-properties-mode) + - [value-separator](#value-separator) + - [null-value](#null-value) + - [trim-values](#trim-values) + - [BeanDefinition](#beandefinition-1) + - [运行](#%E8%BF%90%E8%A1%8C-2) + - [处理](#%E5%A4%84%E7%90%86) +- [load-time-weaver & spring-configured](#load-time-weaver--spring-configured) + - [javaagent](#javaagent) + - [解析](#%E8%A7%A3%E6%9E%90-2) + - [LoadTimeWeaver](#loadtimeweaver) + - [LoadTimeWeaverBeanDefinitionParser](#loadtimeweaverbeandefinitionparser) + - [aspectj-weaving](#aspectj-weaving) + - [是否开启](#%E6%98%AF%E5%90%A6%E5%BC%80%E5%90%AF) + - [AspectJWeavingEnabler](#aspectjweavingenabler) + - [SpringConfiguredBeanDefinitionParser](#springconfiguredbeandefinitionparser) + - [切点(pointcut)](#%E5%88%87%E7%82%B9pointcut) + - [inConfigurableBean](#inconfigurablebean) + - [beanConstruction](#beanconstruction) + - [preConstructionCondition](#preconstructioncondition) + - [leastSpecificSuperTypeConstruction](#leastspecificsupertypeconstruction) + - [preConstructionConfiguration](#preconstructionconfiguration) + - [postConstructionCondition](#postconstructioncondition) + - [advise](#advise) + - [前置](#%E5%89%8D%E7%BD%AE) + - [运行](#%E8%BF%90%E8%A1%8C-3) + - [LoadTimeWeaverAware](#loadtimeweaveraware) + - [BeanClassLoaderAware](#beanclassloaderaware) + - [入口](#%E5%85%A5%E5%8F%A3-3) + - [setBeanClassLoader](#setbeanclassloader) + - [服务器agent](#%E6%9C%8D%E5%8A%A1%E5%99%A8agent) + - [Spring agent](#spring-agent) + - [反射](#%E5%8F%8D%E5%B0%84) + - [总结](#%E6%80%BB%E7%BB%93) + - [ClassFileTransformer](#classfiletransformer) + - [Aj](#aj) + - [缓存](#%E7%BC%93%E5%AD%98) + - [WeavingAdaptor初始化](#weavingadaptor%E5%88%9D%E5%A7%8B%E5%8C%96) + - [aop.xml](#aopxml) + - [解析](#%E8%A7%A3%E6%9E%90-3) + - [注册](#%E6%B3%A8%E5%86%8C) + - [总结](#%E6%80%BB%E7%BB%93-1) + + + # 开头 入口方法在BeanDefinitionParserDelegate.parseCustomElement: diff --git a/note/spring-mvc.md b/note/spring-mvc.md index 4361e72..b217063 100644 --- a/note/spring-mvc.md +++ b/note/spring-mvc.md @@ -1,3 +1,73 @@ + + +**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* + +- [初始化](#%E5%88%9D%E5%A7%8B%E5%8C%96) + - [容器初始化](#%E5%AE%B9%E5%99%A8%E5%88%9D%E5%A7%8B%E5%8C%96) + - [根容器查找](#%E6%A0%B9%E5%AE%B9%E5%99%A8%E6%9F%A5%E6%89%BE) + - [容器创建](#%E5%AE%B9%E5%99%A8%E5%88%9B%E5%BB%BA) + - [ApplicationContextInitializer](#applicationcontextinitializer) + - [配置解析](#%E9%85%8D%E7%BD%AE%E8%A7%A3%E6%9E%90) + - [注解驱动](#%E6%B3%A8%E8%A7%A3%E9%A9%B1%E5%8A%A8) + - [静态资源处理](#%E9%9D%99%E6%80%81%E8%B5%84%E6%BA%90%E5%A4%84%E7%90%86) + - [拦截器](#%E6%8B%A6%E6%88%AA%E5%99%A8) + - [视图](#%E8%A7%86%E5%9B%BE) + - [Scope/处理器注册](#scope%E5%A4%84%E7%90%86%E5%99%A8%E6%B3%A8%E5%86%8C) + - [MVC初始化](#mvc%E5%88%9D%E5%A7%8B%E5%8C%96) + - [文件上传支持](#%E6%96%87%E4%BB%B6%E4%B8%8A%E4%BC%A0%E6%94%AF%E6%8C%81) + - [地区解析器](#%E5%9C%B0%E5%8C%BA%E8%A7%A3%E6%9E%90%E5%99%A8) + - [主题解析器](#%E4%B8%BB%E9%A2%98%E8%A7%A3%E6%9E%90%E5%99%A8) + - [HandlerMapping检查](#handlermapping%E6%A3%80%E6%9F%A5) + - [HandlerAdapter检查](#handleradapter%E6%A3%80%E6%9F%A5) + - [HandlerExceptionResolver检查](#handlerexceptionresolver%E6%A3%80%E6%9F%A5) + - [RequestToViewNameTranslator](#requesttoviewnametranslator) + - [ViewResolver检查](#viewresolver%E6%A3%80%E6%9F%A5) + - [FlashMapManager](#flashmapmanager) + - [HandlerMapping初始化](#handlermapping%E5%88%9D%E5%A7%8B%E5%8C%96) + - [RequestMappingHandlerMapping](#requestmappinghandlermapping) + - [跨域请求](#%E8%B7%A8%E5%9F%9F%E8%AF%B7%E6%B1%82) + - [拦截器初始化](#%E6%8B%A6%E6%88%AA%E5%99%A8%E5%88%9D%E5%A7%8B%E5%8C%96) + - [HandlerAdapter初始化](#handleradapter%E5%88%9D%E5%A7%8B%E5%8C%96) + - [@ControllerAdvice](#controlleradvice) + - [参数解析器](#%E5%8F%82%E6%95%B0%E8%A7%A3%E6%9E%90%E5%99%A8) + - [@InitBinder支持](#initbinder%E6%94%AF%E6%8C%81) + - [返回结果解析器](#%E8%BF%94%E5%9B%9E%E7%BB%93%E6%9E%9C%E8%A7%A3%E6%9E%90%E5%99%A8) +- [请求响应](#%E8%AF%B7%E6%B1%82%E5%93%8D%E5%BA%94) + - [请求上下文](#%E8%AF%B7%E6%B1%82%E4%B8%8A%E4%B8%8B%E6%96%87) + - [请求分发](#%E8%AF%B7%E6%B1%82%E5%88%86%E5%8F%91) + - [处理器查找](#%E5%A4%84%E7%90%86%E5%99%A8%E6%9F%A5%E6%89%BE) + - [适配器查找](#%E9%80%82%E9%85%8D%E5%99%A8%E6%9F%A5%E6%89%BE) + - [请求处理](#%E8%AF%B7%E6%B1%82%E5%A4%84%E7%90%86) + - [Session同步](#session%E5%90%8C%E6%AD%A5) + - [参数解析](#%E5%8F%82%E6%95%B0%E8%A7%A3%E6%9E%90) + - [策略模式](#%E7%AD%96%E7%95%A5%E6%A8%A1%E5%BC%8F) + - [自定义参数](#%E8%87%AA%E5%AE%9A%E4%B9%89%E5%8F%82%E6%95%B0) + - [参数名是从哪里来的](#%E5%8F%82%E6%95%B0%E5%90%8D%E6%98%AF%E4%BB%8E%E5%93%AA%E9%87%8C%E6%9D%A5%E7%9A%84) + - [Model](#model) + - [总结](#%E6%80%BB%E7%BB%93) + - [返回值解析](#%E8%BF%94%E5%9B%9E%E5%80%BC%E8%A7%A3%E6%9E%90) + - [视图渲染](#%E8%A7%86%E5%9B%BE%E6%B8%B2%E6%9F%93) + - [ModelAndView](#modelandview) + - [渲染](#%E6%B8%B2%E6%9F%93) + - [ViewResolver](#viewresolver) + - [View](#view) +- [拾遗](#%E6%8B%BE%E9%81%97) + - [@ResponseBody](#responsebody) + - [HttpMessageConverter](#httpmessageconverter) + - [自定义](#%E8%87%AA%E5%AE%9A%E4%B9%89) + - [默认](#%E9%BB%98%E8%AE%A4) + - [转换](#%E8%BD%AC%E6%8D%A2) + - [参数解析 & 结果转换](#%E5%8F%82%E6%95%B0%E8%A7%A3%E6%9E%90--%E7%BB%93%E6%9E%9C%E8%BD%AC%E6%8D%A2) + - ["纯"对象参数接收](#%E7%BA%AF%E5%AF%B9%E8%B1%A1%E5%8F%82%E6%95%B0%E6%8E%A5%E6%94%B6) + - [参数对象构造](#%E5%8F%82%E6%95%B0%E5%AF%B9%E8%B1%A1%E6%9E%84%E9%80%A0) + - [参数绑定](#%E5%8F%82%E6%95%B0%E7%BB%91%E5%AE%9A) + - [参数校验](#%E5%8F%82%E6%95%B0%E6%A0%A1%E9%AA%8C) + - [JSR校验](#jsr%E6%A0%A1%E9%AA%8C) + - [自定义校验器](#%E8%87%AA%E5%AE%9A%E4%B9%89%E6%A0%A1%E9%AA%8C%E5%99%A8) + - [一个有意思的问题](#%E4%B8%80%E4%B8%AA%E6%9C%89%E6%84%8F%E6%80%9D%E7%9A%84%E9%97%AE%E9%A2%98) + + + # 初始化 spring-mvc的核心便是DispatcherServlet,所以初始化也是围绕其展开的。类图: diff --git a/note/spring-task.md b/note/spring-task.md index 4212b0c..f84e8e1 100644 --- a/note/spring-task.md +++ b/note/spring-task.md @@ -1,3 +1,27 @@ + + +**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* + +- [开头](#%E5%BC%80%E5%A4%B4) +- [定时器](#%E5%AE%9A%E6%97%B6%E5%99%A8) + - [用法](#%E7%94%A8%E6%B3%95) + - [解析](#%E8%A7%A3%E6%9E%90) + - [注册](#%E6%B3%A8%E5%86%8C) + - [scheduler](#scheduler) + - [scheduled-tasks](#scheduled-tasks) + - [调度执行](#%E8%B0%83%E5%BA%A6%E6%89%A7%E8%A1%8C) + - [scheduler初始化](#scheduler%E5%88%9D%E5%A7%8B%E5%8C%96) + - [任务调度](#%E4%BB%BB%E5%8A%A1%E8%B0%83%E5%BA%A6) + - [Trigger](#trigger) + - [Cron解析](#cron%E8%A7%A3%E6%9E%90) + - [调度](#%E8%B0%83%E5%BA%A6) + - [总结](#%E6%80%BB%E7%BB%93) +- [异步执行](#%E5%BC%82%E6%AD%A5%E6%89%A7%E8%A1%8C) + - [配置](#%E9%85%8D%E7%BD%AE) + - [原理](#%E5%8E%9F%E7%90%86) + + + # 开头 从功能上来说,spring-task这个组件主要包括了两个/两种功能: diff --git a/note/spring-transaction.md b/note/spring-transaction.md index c6d59d8..296635e 100644 --- a/note/spring-transaction.md +++ b/note/spring-transaction.md @@ -1,3 +1,37 @@ + + +**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* + +- [配置](#%E9%85%8D%E7%BD%AE) +- [解析](#%E8%A7%A3%E6%9E%90) + - [TransactionalEventListener](#transactionaleventlistener) + - [主要组件注册](#%E4%B8%BB%E8%A6%81%E7%BB%84%E4%BB%B6%E6%B3%A8%E5%86%8C) + - [代理类生成](#%E4%BB%A3%E7%90%86%E7%B1%BB%E7%94%9F%E6%88%90) + - [Advisor寻找](#advisor%E5%AF%BB%E6%89%BE) +- [运行](#%E8%BF%90%E8%A1%8C) + - [调用链生成](#%E8%B0%83%E7%94%A8%E9%93%BE%E7%94%9F%E6%88%90) + - [调用链调用](#%E8%B0%83%E7%94%A8%E9%93%BE%E8%B0%83%E7%94%A8) + - [TransactionInterceptor](#transactioninterceptor) + - [事务管理器](#%E4%BA%8B%E5%8A%A1%E7%AE%A1%E7%90%86%E5%99%A8) + - [DataSource](#datasource) + - [事务开启](#%E4%BA%8B%E5%8A%A1%E5%BC%80%E5%90%AF) + - [是否已存在事务](#%E6%98%AF%E5%90%A6%E5%B7%B2%E5%AD%98%E5%9C%A8%E4%BA%8B%E5%8A%A1) + - [事务已存在](#%E4%BA%8B%E5%8A%A1%E5%B7%B2%E5%AD%98%E5%9C%A8) + - [PROPAGATION_NEVER](#propagation_never) + - [PROPAGATION_NOT_SUPPORTED](#propagation_not_supported) + - [事务挂起](#%E4%BA%8B%E5%8A%A1%E6%8C%82%E8%B5%B7) + - [PROPAGATION_REQUIRES_NEW](#propagation_requires_new) + - [PROPAGATION_NESTED](#propagation_nested) + - [debug环境搭建](#debug%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA) + - [事务对象](#%E4%BA%8B%E5%8A%A1%E5%AF%B9%E8%B1%A1) + - [Savepoint](#savepoint) + - [其它](#%E5%85%B6%E5%AE%83) + - [事务创建](#%E4%BA%8B%E5%8A%A1%E5%88%9B%E5%BB%BA) + - [事务提交 & 回滚](#%E4%BA%8B%E5%8A%A1%E6%8F%90%E4%BA%A4--%E5%9B%9E%E6%BB%9A) +- [总结](#%E6%80%BB%E7%BB%93) + + + # 配置 以最简单的jdbc事务为例: From bb36b4d9d02b9fd5df4468fc6de772e0f6529cec Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Nov 2019 03:59:15 +0000 Subject: [PATCH 15/20] Bump jackson-databind from 2.9.8 to 2.9.10.1 Bumps [jackson-databind](https://github.com/FasterXML/jackson) from 2.9.8 to 2.9.10.1. - [Release notes](https://github.com/FasterXML/jackson/releases) - [Commits](https://github.com/FasterXML/jackson/commits) Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3992b4c..08ecb2f 100644 --- a/pom.xml +++ b/pom.xml @@ -90,7 +90,7 @@ com.fasterxml.jackson.core jackson-databind - 2.9.8 + 2.9.10.1 From 2614b08cfd35ab537b9f003849ebb7d1b3f43a5c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Jan 2020 17:07:09 +0000 Subject: [PATCH 16/20] Bump hibernate-validator from 6.0.2.Final to 6.1.0.Final Bumps [hibernate-validator](https://github.com/hibernate/hibernate-validator) from 6.0.2.Final to 6.1.0.Final. - [Release notes](https://github.com/hibernate/hibernate-validator/releases) - [Changelog](https://github.com/hibernate/hibernate-validator/blob/master/changelog.txt) - [Commits](https://github.com/hibernate/hibernate-validator/compare/6.0.2.Final...6.1.0.Final) Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3992b4c..e8235ba 100644 --- a/pom.xml +++ b/pom.xml @@ -108,7 +108,7 @@ org.hibernate.validator hibernate-validator - 6.0.2.Final + 6.1.0.Final From a41e7b00f3205ab420bb8aebaa47c500ae186773 Mon Sep 17 00:00:00 2001 From: Rocky <846106184@qq.com> Date: Thu, 13 Feb 2020 15:49:14 +0800 Subject: [PATCH 17/20] =?UTF-8?q?=E7=BA=A0=E6=AD=A3postProcessMergedBeanDe?= =?UTF-8?q?finition=E6=96=B9=E6=B3=95=E7=9A=84=E6=89=A7=E8=A1=8C=E6=97=B6?= =?UTF-8?q?=E6=9C=BA=E7=9A=84=E6=8F=8F=E8=BF=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 纠正MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition方法的执行时机的描述 ```java protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) { // Instantiate the bean. BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { //createBeanInstance方法已经创建了实例 instanceWrapper = createBeanInstance(beanName, mbd, args); } final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null); Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null); // Allow post-processors to modify the merged bean definition. synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); mbd.postProcessed = true; } } } ``` 代码中createBeanInstance方法已经创建了实例 --- note/spring-context.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/note/spring-context.md b/note/spring-context.md index fec3dcc..8bc22f5 100644 --- a/note/spring-context.md +++ b/note/spring-context.md @@ -570,7 +570,7 @@ private static final Callback[] CALLBACKS = new Callback[] { ##### 入口 -其中前者首先被调用,时机是当BeanDefinition被合并(和父Bean),但是还没有用来创建Bean实例时。回顾下其调用入口: +其中前者首先被调用,时机是已创建Bean实例但还没有对实例执行初始化操作。回顾下其调用入口: AbstractAutowireCapableBeanFactory.doCreateBean(简略): From 578992b09e22aadb85c63d822bad679213eda4d3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 Jun 2020 15:44:33 +0000 Subject: [PATCH 18/20] Bump jackson-databind from 2.9.10.1 to 2.10.0.pr1 Bumps [jackson-databind](https://github.com/FasterXML/jackson) from 2.9.10.1 to 2.10.0.pr1. - [Release notes](https://github.com/FasterXML/jackson/releases) - [Commits](https://github.com/FasterXML/jackson/commits) Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 45a8476..adb42cd 100644 --- a/pom.xml +++ b/pom.xml @@ -90,7 +90,7 @@ com.fasterxml.jackson.core jackson-databind - 2.9.10.1 + 2.10.0.pr1 From 214462c4c583633ca4abf01b7b868dc085425d20 Mon Sep 17 00:00:00 2001 From: YuHui Date: Tue, 23 Feb 2021 17:02:32 +0800 Subject: [PATCH 19/20] Update spring-boot.md --- note/spring-boot.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/note/spring-boot.md b/note/spring-boot.md index 0993d3b..a05c5ba 100644 --- a/note/spring-boot.md +++ b/note/spring-boot.md @@ -71,7 +71,7 @@ deduceWebEnvironment方法用于检测当前是否是web工程环境,检测的 这货是典型的观察者模式实现,类图: -![ApplicationListener](images/ApplicationListener.PNG) +![ApplicationListener](images/ApplicationListener.png) 在简单的web应用场景下,系统共初始化了这些监听器: From d1ae25dd4dc96efa25d4c0edc7708d32b8776457 Mon Sep 17 00:00:00 2001 From: Carpe-Wang Date: Thu, 23 Mar 2023 16:03:41 +0800 Subject: [PATCH 20/20] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=B0=91=E6=95=B0md?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- note/Spring.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/note/Spring.md b/note/Spring.md index 0d04abd..0bc359e 100644 --- a/note/Spring.md +++ b/note/Spring.md @@ -220,11 +220,11 @@ protected ConfigurableEnvironment createEnvironment() { ![Environment继承体系](images/Environment.jpg) -Environmen接口**代表了当前应用所处的环境。**从此接口的方法可以看出,其主要和profile、Property相关。 +Environmen接口**代表了当前应用所处的环境。** 从此接口的方法可以看出,其主要和profile、Property相关。 ##### Profile -Spring Profile特性是从3.1开始的,其主要是为了解决这样一种问题: 线上环境和测试环境使用不同的配置或是数据库或是其它。有了Profile便可以在 不同环境之间无缝切换。**Spring容器管理的所有bean都是和一个profile绑定在一起的。**使用了Profile的配置文件示例: +Spring Profile特性是从3.1开始的,其主要是为了解决这样一种问题: 线上环境和测试环境使用不同的配置或是数据库或是其它。有了Profile便可以在 不同环境之间无缝切换。**Spring容器管理的所有bean都是和一个profile绑定在一起的。** 使用了Profile的配置文件示例: ```xml