Skip to content

Commit 5546ef0

Browse files
committed
Update Java Notes
1 parent c754072 commit 5546ef0

File tree

3 files changed

+76
-121
lines changed

3 files changed

+76
-121
lines changed

Java.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1307,7 +1307,7 @@ class Animal{
13071307

13081308
#### 方法访问
13091309

1310-
子类继承了父类就得到了父类的方法,可以直接调用,受权限修饰符的限制,也可以重写方法
1310+
子类继承了父类就得到了父类的方法,**可以直接调用**,受权限修饰符的限制,也可以重写方法
13111311

13121312
**方法重写**:子类重写一个与父类申明一样的方法来**覆盖**父类的该方法
13131313

Prog.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3034,7 +3034,7 @@ CAS算法:有3个操作数(内存值V, 旧的预期值A,要修改的值B
30343034

30353035
CAS 必须借助 volatile 才能读取到共享变量的最新值来实现**比较并交换**的效果
30363036

3037-
分析getAndUpdate方法
3037+
分析 getAndUpdate 方法
30383038

30393039
* getAndUpdate:
30403040

@@ -3080,7 +3080,7 @@ CAS算法:有3个操作数(内存值V, 旧的预期值A,要修改的值B
30803080

30813081
#### 原子引用
30823082

3083-
原子引用:Object进行原子操作,提供一种读和写都是原子性的对象引用变量
3083+
原子引用:Object 进行原子操作,提供一种读和写都是原子性的对象引用变量
30843084

30853085
原子引用类:AtomicReferenceAtomicStampedReferenceAtomicMarkableReference
30863086

@@ -3090,7 +3090,7 @@ AtomicReference类:
30903090

30913091
* 常用API
30923092

3093-
`public final boolean compareAndSet(V expectedValue, V newValue)`:CAS操作
3093+
`public final boolean compareAndSet(V expectedValue, V newValue)`:CAS 操作
30943094
`public final void set(V newValue)`:将值设置为 newValue
30953095
`public final V get()`:返回当前值
30963096

SSM.md

Lines changed: 72 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -8004,6 +8004,8 @@ AbstractAutowireCapableBeanFactory.createBeanInstance(beanName, RootBeanDefiniti
80048004
80058005
* 判断类的访问权限是不是 public,不是进入下一个判断,是否允许访问类的 non-public 的构造方法,不允许则报错
80068006
8007+
* `Supplier<?> instanceSupplier = mbd.getInstanceSupplier()`:获取创建实例的函数,可以自定义,没有进入下面的逻辑
8008+
80078009
* `if (mbd.getFactoryMethodName() != null)`:**判断 bean 是否设置了 factory-method 属性**
80088010
80098011
<bean class="" factory-method="">,设置了该属性进入 factory-method 方法创建实例
@@ -8017,13 +8019,13 @@ AbstractAutowireCapableBeanFactory.createBeanInstance(beanName, RootBeanDefiniti
80178019
* method 为 null 则 resolved 和 autowireNecessary 都为默认值 false
80188020
* `autowireNecessary = mbd.constructorArgumentsResolved`:构造方法有参数,设置为 true
80198021
8020-
* bd 对应的构造信息解析完成:
8022+
* **bd 对应的构造信息解析完成,可以直接反射调用构造方法了**
80218023
80228024
* `return autowireConstructor(beanName, mbd, null, null)`:**有参构造**,根据参数匹配最优的构造器创建实例
80238025
80248026
* `return instantiateBean(beanName, mbd)`:**无参构造方法通过反射创建实例**
80258027
8026-
* `ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName)`:**AutowiredAnnotation 逻辑**
8028+
* `ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName)`:@Autowired 注解对应的后置处理器**AutowiredAnnotationBeanPostProcessor 逻辑**
80278029
80288030
* 配置了 lookup 的相关逻辑
80298031
@@ -8080,7 +8082,7 @@ AbstractAutowireCapableBeanFactory.createBeanInstance(beanName, RootBeanDefiniti
80808082
80818083
`!ObjectUtils.isEmpty(args)`:getBean 时,指定了参数 arg
80828084
8083-
* `autowireConstructor(beanName, mbd, ctors, args)`:**选择最优的构造器进行创建实例**(非常复杂,可以放弃深究
8085+
* `return autowireConstructor(beanName, mbd, ctors, args)`:**选择最优的构造器进行创建实例**(复杂,不建议研究
80848086
80858087
* `beanFactory.initBeanWrapper(bw)`:向 BeanWrapper 中注册转换器,向工厂中注册属性编辑器
80868088
@@ -8157,13 +8159,19 @@ AbstractAutowireCapableBeanFactory.createBeanInstance(beanName, RootBeanDefiniti
81578159
81588160
* ` bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse))`:匹配成功调用 instantiate 创建出实例对象,设置到 BeanWrapper 中去
81598161
8160-
* `SimpleInstantiationStrategy.instantiate()`:**真正用来实例化的函数**(无论如何都会走到这一步)
8162+
* `return instantiateBean(beanName, mbd)`:默认走到这里
81618163
8162-
* `if (!bd.hasMethodOverrides())`:没有方法重写覆盖
8164+
* `SimpleInstantiationStrategy.instantiate()`:**真正用来实例化的函数**(无论如何都会走到这一步)
81638165
8164-
`BeanUtils.instantiateClass(constructorToUse)`:底层调用 java.lang.reflect.Constructor.newInstance() 实例化
8166+
* `if (!bd.hasMethodOverrides())`:没有方法重写覆盖
81658167
8166-
* `instantiateWithMethodInjection(bd, beanName, owner)`:有方法重写采用 CGLIB 实例化
8168+
`BeanUtils.instantiateClass(constructorToUse)`:调用 `java.lang.reflect.Constructor.newInstance()` 实例化
8169+
8170+
* `instantiateWithMethodInjection(bd, beanName, owner)`:有方法重写采用 CGLIB 实例化
8171+
8172+
* `BeanWrapper bw = new BeanWrapperImpl(beanInstance)`:包装成 BeanWrapper 类型的对象
8173+
8174+
* `return bw`:返回实例
81678175
81688176
81698177
@@ -9760,10 +9768,39 @@ SpringMVC 对接收的数据进行自动类型转换,该工作通过 Converter
97609768
97619769
##### 自定义
97629770
9763-
* 自定义类型转换器,实现 Converter 接口,并制定转换前与转换后的类型
9771+
自定义类型转换器,实现 Converter 接口或者直接容器中注入:
9772+
9773+
* 方式一:
9774+
9775+
```java
9776+
public class WebConfig implements WebMvcConfigurer {
9777+
@Bean
9778+
public WebMvcConfigurer webMvcConfigurer() {
9779+
return new WebMvcConfigurer() {
9780+
@Override
9781+
public void addFormatters(FormatterRegistry registry) {
9782+
registry.addConverter(new Converter<String, Date>() {
9783+
@Override
9784+
public Pet convert(String source) {
9785+
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
9786+
Date date = null;
9787+
//类型转换器无法预计使用过程中出现的异常,因此必须在类型转换器内部捕获,
9788+
//不允许抛出,框架无法预计此类异常如何处理
9789+
try {
9790+
date = df.parse(source);
9791+
} catch (ParseException e) {
9792+
e.printStackTrace();
9793+
}
9794+
return date;
9795+
}
9796+
});
9797+
}
9798+
}
9799+
}
9800+
9801+
* 方式二:
97649802
97659803
```java
9766-
//自定义类型转换器,实现Converter接口,接口中指定的泛型即为最终作用的条件
97679804
//本例中的泛型填写的是String,Date,最终出现字符串转日期时,该类型转换器生效
97689805
public class MyDateConverter implements Converter<String, Date> {
97699806
//重写接口的抽象方法,参数由泛型决定
@@ -9782,7 +9819,7 @@ SpringMVC 对接收的数据进行自动类型转换,该工作通过 Converter
97829819
}
97839820
```
97849821
9785-
* 配置 resources / spring-mvc.xml,注册自定义转换器,将功能加入到 SpringMVC 转换服务 ConverterService 中
9822+
配置 resources / spring-mvc.xml,注册自定义转换器,将功能加入到 SpringMVC 转换服务 ConverterService 中
97869823
97879824
```xml
97889825
<!--1.将自定义Converter注册为Bean,受SpringMVC管理-->
@@ -9900,9 +9937,10 @@ SpringMVC 对接收的数据进行自动类型转换,该工作通过 Converter
99009937

99019938

99029939

9903-
#### 带数据跳转
9940+
#### 数据跳转
9941+
9942+
ModelAndView 是 SpringMVC 提供的一个对象,该对象可以用作控制器方法的返回值(Model 同),实现携带数据跳转
99049943

9905-
ModelAndView 是 SpringMVC 提供的一个对象,该对象可以用作控制器方法的返回值(Model 同)
99069944
作用:
99079945

99089946
+ 设置数据,向请求域对象中存储数据
@@ -9989,13 +10027,13 @@ ModelAndView 是 SpringMVC 提供的一个对象,该对象可以用作控制
998910027

999010028

999110029

9992-
#### JSON数据
10030+
#### JSON
999310031

999410032
注解:@ResponseBody
999510033

999610034
作用:将 Controller 的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到 Response 的 body 区。如果返回值是字符串,那么直接将字符串返回客户端;如果是一个对象,会**将对象转化为 Json**,返回客户端
999710035

9998-
注意:当方法上面没有写 ResponseBody,底层会将方法的返回值封装为 ModelAndView 对象
10036+
注意:当方法上面没有写 ResponseBody,底层会将方法的返回值封装为 ModelAndView 对象
999910037

1000010038
* 使用 HttpServletResponse 对象响应数据
1000110039

@@ -10242,11 +10280,11 @@ public String getMessage(@PathVariable("id") Integer id){
1024210280

1024310281
* @RequestHeader:获取请求头
1024410282
* @RequestParam:获取请求参数(指问号后的参数,url?a=1&b=2)
10245-
* @CookieValue:获取Cookie值
10246-
* @RequestAttribute:获取request域属性
10247-
* @RequestBody:获取请求体[POST]
10283+
* @CookieValue:获取 Cookie 值
10284+
* @RequestAttribute:获取 request 域属性
10285+
* @RequestBody:获取请求体 [POST]
1024810286
* @MatrixVariable:矩阵变量
10249-
* @ModelAttribute
10287+
* @ModelAttribute:自定义类型变量
1025010288

1025110289
```java
1025210290
@RestController
@@ -10355,105 +10393,6 @@ public class WebConfig{
1035510393

1035610394

1035710395

10358-
10359-
10360-
****
10361-
10362-
10363-
10364-
### 原理解析
10365-
10366-
请求进入原生的 HttpServlet 的 doGet() 方法处理,调用子类 FrameworkServlet 的 doGet() 方法,最终调用 DispatcherServlet 的 doService() 方法,为请求设置相关属性后调用 doDispatch()
10367-
10368-
![](https://gitee.com/seazean/images/raw/master/Frame/SpringMVC-请求相应的原理.png)
10369-
10370-
总体流程:
10371-
10372-
* 所有的请求映射都在 HandlerMapping 中,RequestMappingHandlerMapping 处理 @RequestMapping 注解的所有映射规则
10373-
10374-
* 请求进来,遍历所有的 HandlerMapping 看是否有请求信息,匹配成功后返回,匹配失败设置 HTTP 响应码
10375-
* 用户可以自定义的映射处理,也可以给容器中放入自定义 HandlerMapping
10376-
10377-
访问 URL:http://localhost:8080/user(对应 Restful 中配置的映射规则)
10378-
10379-
```java
10380-
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
10381-
HttpServletRequest processedRequest = request;
10382-
HandlerExecutionChain mappedHandler = null;
10383-
boolean multipartRequestParsed = false; //文件上传请求
10384-
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);//异步管理器
10385-
try {
10386-
//文件上传请求
10387-
processedRequest = checkMultipart(request);
10388-
// 找到当前请求使用哪个Handler(Controller的方法)处理
10389-
mappedHandler = getHandler(processedRequest);
10390-
// 没有合适的处理请求的方式 handler 直接返回
10391-
if (mappedHandler == null) {
10392-
noHandlerFound(processedRequest, response);
10393-
return;
10394-
}
10395-
//...
10396-
}
10397-
}
10398-
```
10399-
10400-
* HandlerMapping 处理器映射器,保存了所有 `@RequestMapping` 和 `handler` 的映射规则
10401-
10402-
```java
10403-
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
10404-
if (this.handlerMappings != null) {
10405-
//遍历所有的 HandlerMapping
10406-
for (HandlerMapping mapping : this.handlerMappings) {
10407-
//尝试去每个 HandlerMapping 中匹配当前请求的处理
10408-
HandlerExecutionChain handler = mapping.getHandler(request);
10409-
if (handler != null) {
10410-
return handler;
10411-
}
10412-
}
10413-
}
10414-
return null;
10415-
}
10416-
```
10417-
10418-
![](https://gitee.com/seazean/images/raw/master/Frame/SpringMVC-获取Controller处理器.png)
10419-
10420-
* `mapping.getHandler(request)` 中调用 `Object handler = getHandlerInternal(request)`,该 getHandlerInternal 方法是
10421-
10422-
RequestMappingInfoHandlerMapping 类中的,继续调用 `AbstractHandlerMethodMapping.getHandlerInternal()`
10423-
10424-
* AbstractHandlerMethodMapping.getHandlerInternal():
10425-
10426-
```java
10427-
protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
10428-
// lookupPath = user,地址栏的 uri
10429-
String lookupPath = initLookupPath(request);
10430-
// 防止并发
10431-
this.mappingRegistry.acquireReadLock();
10432-
try {
10433-
//获取当前 HandlerMapping 中的映射规则
10434-
HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
10435-
return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);
10436-
}
10437-
finally {
10438-
this.mappingRegistry.releaseReadLock();
10439-
}
10440-
}
10441-
```
10442-
10443-
* AbstractHandlerMethodMapping.lookupHandlerMethod():
10444-
10445-
* `directPathMatches = this.mappingRegistry.getMappingsByDirectPath(lookupPath)`:获取与 URI 相关的映射规则
10446-
10447-
![](https://gitee.com/seazean/images/raw/master/Frame/SpringMVC-HandlerMapping的映射规则.png)
10448-
10449-
* `addMatchingMappings(directPathMatches, matches, request)`:匹配某个映射规则
10450-
10451-
* `Match bestMatch = matches.get(0)`:匹配完成只剩一个,直接获取返回对应的方法
10452-
10453-
* `if (matches.size() > 1)`:当有多个映射规则符合请求时,报错
10454-
10455-
10456-
1045710396
***
1045810397

1045910398

@@ -11783,6 +11722,22 @@ jsp:
1178311722

1178411723

1178511724

11725+
***
11726+
11727+
11728+
11729+
## 运行原理
11730+
11731+
11732+
11733+
11734+
11735+
11736+
11737+
11738+
11739+
11740+
1178611741

1178711742

1178811743
***

0 commit comments

Comments
 (0)