- 博客(331)
- 收藏
- 关注
原创 @Configuration org.springframework.beans.factory.parsing.BeanDefinitionParsingException
通过源码我们找到了答案,在开发使用中我们要避免出现这种情况,最好不要在@Configuration 中重载Bean.Spring 5版本。
2025-03-18 21:18:54
199
原创 Exception in thread “main“ java.lang.ClassCastException: com.sun.proxy.$Proxy0 cannot be cast to问题记录
让我们来看一下源码,当我们的类继续了接口会默认使用JDK动态代理,这个时候我们用子类类接收对象就会产生这个强转错误。那如果我就想用上面的写法怎么办呢?其实也是有办法的我们使用CGLIB的代理就好了,因为CGLIB的代理是基于类继承的,所以不会有上面的问题。当我们执行main函数的时候,会出现异常。
2025-03-12 21:39:26
181
原创 @ModelAttribute-使用
比如上述方法就会将Version对象放入视图模型中,控制器的每个方法在执行的时候视图模型就有了Version对象。首先为什么在控制器的方法之前执行是因为调用控制器方法之前会初始化Model invokeModelAttributeMethods,之后才会调用控制器的方法。当不写注解的时候默认是@ModelAttribute注解,会将提交的表单数据绑定到对象中,对象的属性和表单提交的变量一一对应。主要用于将 HTTP 请求的数据绑定到控制器方法的参数或添加属性到模型中,以便在视图层使用。
2025-03-05 19:39:36
141
转载 设计模式之美-接口VS抽象类
我们知道,继承关系是一种 is-a 的关系,那抽象类既然属于类,也表示一种 is-a 的关系。相对于抽象类的 is-a 关系来说,接口表示一种 has-a 关系,表示具有某些功能。从类的继承层次上来看,抽象类是一种自下而上的设计思路,先有子类的代码重复,然后再抽象成上层的父类(也就是抽象类)。如果我们要表示一种 is-a 的关系,并且是为了解决代码复用的问题,我们就用抽象类;如果我们要表示一种 has-a 关系,并且是为了解决抽象而非代码复用的问题,那我们就可以使用接口。
2025-02-09 09:50:37
28
转载 设计模式之美-面向对象
面向对象编程的英文缩写是 OOP,全称是 Object Oriented Programming。对应地,面向对象编程语言的英文缩写是 OOPL,全称是 Object Oriented Programming Language。面向对象编程中有两个非常重要、非常基础的概念,那就是类(class)和对象(object)。面向对象编程是一种编程范式或编程风格。它以类或对象作为组织代码的基本单元,并将封装、抽象、继承、多态四个特性,作为代码设计和实现的基石。
2025-02-09 09:43:50
37
转载 设计模式之美-如何提高代码质量?
除此之外,代码的易维护性还跟项目代码量的多少、业务的复杂程度、利用到的技术的复杂程度、文档是否全面、团队成员的开发水平等诸多因素有关。代码的可扩展性表示,我们在不修改或少量修改原有代码的情况下,通过扩展的方式添加新的功能代码。说直白点就是,代码预留了一些功能扩展点,你可以把新功能代码,直接插到扩展点上,而不需要因为要添加一个功能而大动干戈,改动大量的原始代码。当我们添加一个新的功能代码的时候,原有的代码已经预留好了扩展点,我们不需要修改原有的代码,只要在扩展点上添加新的代码即可。
2025-02-07 16:19:35
33
原创 图解HTTP-WEB服务器
网关是转发其它服务器通信数据的服务器,接收从客户端发送过来的请求时,他就想自己拥有资源服务器一样对请求进行处理。和我们网络中的网络有所区别,网络组件中的网关是连接局域网和外面的网络。代理是一种有转发功能的应用程序,它扮演了服务器和客户端中间人的校色,接收由客户端发送请求并转发给服务器,同时也接受服务器返回的响应并转发给客户端。因此在发送HTTP请求时,必须在Host首部内完全指定主机名或域名的URL。隧道是在相隔甚远的客户端和服务器两者之间进行中转,并保持双方通信连接的应用程序。
2024-12-21 13:50:01
237
原创 图解HTTP-HTTP协议
PUT方法用来传输文件。由于PUT方法自身不带验证机制,任何人都可以上传文件,存在安全性问题,因此一般的WEB网站不使用该方法。HTTP 是无状态协议,它不对之前发生过的请求和响应的状态进行管理。虽然GET方法也可以传输实体的主体,但是一般不用GET方法传输,而是用POST方法。HEAD和GET方法一样,只是不返回报文主体部分,用于确认URI的有效性及资源更新的日期和时间。TRACE 方法是让WEB 服务端将之前的请求通信返回给客户端的方法。向请求URI指定的资源发送请求报文时,采用成为方法的命令。
2024-12-18 22:39:40
1090
原创 图解HTTP-基础概念(HTTP,TPC/IP, DNS,URL)
IP间的通信依赖MAC地址,在网络上通信的双方在同一局域网内的情况是很少的。ARP是一种以解析地址的协议,根据通信的IP地址可以反查出对应的MAC地址。比如如何探测到通信目标,由那一边先发起通信,使用哪种语言进行通信、怎么结束通信等规则都要提前规定,不同的硬件、操作系统之间的通信所有的一切都需要一种规则。也就是TCP/IP是在IP协议通信过程中,使用到的协议族的统称。通常使用的网络是在TCP/IP协议族的基础上运作的。若在握手过程中某个阶段莫名中断,TCP协议会再次以相同的顺序发送相同的数据包。
2024-12-14 10:37:34
1095
原创 AOP-代理实现
如果目标对象是一个具体的类,并且没有实现任何接口,那么就无法直接使用Java动态代理。在这种情况下,需要使用其他技术,如CGLIB,它可以为目标类创建子类来实现动态代理。方法重写:对于每个接口的方法,代理类都会生成一个方法实现,这些方法内部会调用 InvocationHandler.invoke 方法。方法调用:当代理对象的方法被调用时,实际上会调用 InvocationHandler.invoke 方法,从而实现方法的拦截和增强。类定义:生成一个新的类,这个类实现了传入的所有接口。
2024-09-26 15:57:08
547
原创 AOP-基础概念
AOP 的概念Aspect-Oriented Programming (AOP):面向切面编程,是一种编程范式,用于分离横切关注点(cross-cutting concerns),即将那些分散在多个模块中的公共行为(如日志记录、事务管理、安全控制等)集中管理和实现。AspectJ 的定义AspectJ 是一种流行的 AOP 框架,它扩展了 Java 语言,提供了专门的语法来定义切面(aspect)。AspectJ 可以在编译时或运行时对程序进行切面的编织(weaving)。
2024-09-20 15:56:43
471
原创 Java-测试-Mockito 入门篇
这样也确实是单元测试,只不过这个只是其中的一方面。如果你的某个方法并不依赖于Spring容器,也需要启动整个Spirng环境吗?启动这个环境可能是比较耗时间的。本文对Mockito框架做一个初步探索,找找写单测的感觉。
2024-09-19 20:42:26
1147
原创 Spring-循环依赖
接下来就是调用了addSington,里面如果判断是新创建的Sington做了这样几件事情:1)移除将当前Bean放到singtonObjects中 2)将singtonFactories中的singleFactory移除。这就解决了循环依赖,我的理解是通过Map存储早期的Bean,然后注入的也是早期的Bean,等到它依赖的Bean完成注入的时候,注入的早期的Bean的引用也会发生变化,类似于一个延迟加载。然后回到了ClassRoom,这个时候Student的Bean已经进行了创建,进行注入即可。
2024-09-07 17:28:08
1459
1
原创 Spring-@Bean的处理流程
这两个的区别是static直接调用方法所以它的加载不依赖于Configration的Bean实例,普通实例方法依赖于Configration这个配置类,也就是Configration这个类先要变为Bean然后进行普通方法@Bean的处理。这里还需要注意ConfigurationClassPostProcessor的优先级是优先里面最低的(也就是要优先处理,但是处理的优先尽量靠后)。2 静态@Bean也就是标注在static方法上的 实例@Bean标注在普通方法上的。
2024-09-07 10:41:36
615
原创 MyBatis-MappedStatement什么时候生成?QueryWrapper如何做到动态生成了SQL?
可以很清晰的看到QueryWrapper这个参数给我们内置了名称ew。那么怎么根据我们QueryWrapper里面的条件生成SQL的?前面我们提到继承BaseMapper的MappedStatement注册,这里面其实又根据不同的CommandType生成了不同的动态SQL语句。后面就是把真正的值填进去执行查询操作了。
2024-09-05 17:01:36
784
原创 MyBatis-SQL-语句执行流程
如下图所示,如果MethodCache里面存在方法,则判断这个方法是否为default方法,如果不是默认,会被当前的Mapper继承,如果是default方法则创建PlainMethodInvoker对象进行执行。确实是的,我看个配置默认是true,而官网说true是开启二级缓存,可能不太一样。我们可以看到查询以后就被缓存了,这里的缓存是可以配置的有两种方式。以查询列为例子会转到SqlSesson,这里真正的类名是SqlSessionTemplate,它也实现了SqlSesson接口。
2024-09-02 22:09:11
750
原创 Mybatis-Mapper扫描 与 代理
然后我们又可以看到MapperScannerConfigurer实现了BeanDefinitionRegistryPostProcessor接口,往上就是BeanFactoryPostProcessor,在IOC刷新的时候FactoryPostProcessor会被调用,所以核心工作都是MapperScannerConfigurer来完成。那如果我们没有写@MapperScan呢?Scanner在做扫描的时候最终调用的是父类的方法,并且我们可以看到,MapperScan配置的包路径在这里出现。
2024-09-02 14:36:02
1027
原创 源码阅读-SpirngBoot Mybatis 自动配置
ObjectProvider为我们提供了拓展,我们可以自定义一些插件或者类型转换器,同时也可以定义一些Customizer用来配置SqlSessionFactoryBean,MybatisPlusProperties等。可以看到我们在MybatisPlusAutoConfiguration就能拿到这个TypeHandler,这是为我们保留的拓展点,方便我们进行自定义拓展,我们也要从中学习这种设计。SqlSessionFactory做的事情非常的多,我们慢慢来看。
2024-08-31 17:25:57
477
原创 SpringBoot-启动流程
我们平时使用注解驱动比较多,我们来看看看这个AnnotatedBeanDefinitionReader做了什么事情?我们可以很清晰的看到在这里执行了真正的调用,这样一来,我们的BeanDefinition就会被加载。好了这些重点逻辑看完了,下面就是我们比较熟悉的Spirng Context刷新了。
2024-08-30 15:53:46
548
原创 FeignClient-调用流程
好我们继续看拦截器以后的逻辑,可以看到通过Client调用了execute方法,Client的类型是LoadBalancerFeignClient。那么为什么会是LoadBalancerFeignClient类型呢,是因为在创建对象的时候就是LoadBalancerFeignClient。首先请求会被FeignInvocationHandler 进行拦截,然后dispatch找到应的方法进行调用。这块就非常的关键了ILoadBalancer,这个ILoadBalancer哪里来的呢?那么拦截器从那里来呢?
2024-08-30 09:47:43
463
原创 源码阅读-FeignClient如何创建代理对象?
这里是为每个FeignClinet创建了一个AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();我们可以看到有一个FeignClientFactoryBean非常关键说明我们创建对象是FeignClientFactoryBean来创建的,这里写的是函数是编程引用了创建对象的方法,那么怎么和IOC容器创建对象的时候进行打通的呢?2 如果为空则扫描标注有FeignClient的类,进行注册。
2024-08-29 16:22:19
371
原创 Spring-AOP-API设计与实现
在 Spring AOP 中,它主要指代的是应用程序中的某个特定点,在这个点上可以应用切面(Aspect)的逻辑。IntroductionAdvisor提供了动态设置范围的能力,比如我们实现了两个接口,但是我们只想其中的一个接口被代理,或者我们希望拓展一个接口(当然这个接口最好是被我们的目标对象所实现)这个类下面的子类通常是工厂类,这个类存储了Advices 和 Advisors ,TragetSource等 但是没有实现创建代理对象的方法,创建对象的方法是被子类实现。
2024-08-27 09:58:03
936
转载 Spring-类型转换
这里进行注册时候后名称必须为conversionService。我们会发现,我们写的值会被转换为Properties对象。3 Spring拓展PropertyEditor。5 自定义PropertyEditor拓展。6 PropertyEditor 设计缺陷。4 Spring内建实现。
2024-08-22 17:13:06
71
转载 Spring-数据绑定
Spring BeanDefinition 到Bean实例创建。Spirng Web 参数绑定(WebDataBinder)Spring 数据绑定(DataBinder)
2024-08-22 17:11:27
59
转载 Effective-Java-Chapter11-并发
当多个线程共享可变数据时,每个读取或写入数据的线程都必须执行同步。在缺乏同步的情况下,不能保证一个线程的更改对另一个线程可见。同步共享可变数据失败的代价是活性失败和安全失败。这些工具只是对调度器的提示。线程优先级可以少量地用于提高已经工作的程序的服务质量,但绝不应该用于「修复」几乎不能工作的程序。作为规则,你应该在同步区域内做尽可能少的工作。更一般地说,将你在同步区域内所做的工作量保持在最小(也是降低锁的粒度)。注解什么是外来方法:通常指的是在一个线程或同步区域中调用另一个线程或不同同步区域的方法。
2024-08-21 17:54:33
100
原创 RestTemplate-源码阅读
我们可以看到有两种回调函数,都是RestTemplate的内部类。我们来看看,其实一眼就能看到,核心的逻辑都是委托给ClientHttpRequestFactory来实现的。这个工工厂提供了我们自定义拦截器进行处理的能力,这里可以进行一些自定义的拓展。至于如何选择Converters是通过下面这个方法,canWrite 是发送请求的时候些Body,canRead是调用结束以后读取Body。我们可以看到其实没有什么本质的区别,只是在创建CallBack的时候会有一点区别。2 核心API用来进行数据提取。
2024-08-21 13:27:19
1071
原创 CompletableFuture-应用
可以看到CompletableFuture实现了CompletionStage 和Future的两个接口。CompletionStage提供了任务之间的衔接能力,而Future则是经常用于阻塞获取结果。CompletableFuture 的内部使用了基于 ForkJoinPool 的线程池,这种线程池可以高效地调度和执行任务。CompletableFuture 的非阻塞特性得益于其对任务完成的监听机制。当任务完成时,它会遍历所有注册的回调函数,并在合适的线程中执行这些回调。
2024-08-20 22:17:35
563
原创 Effective-Java-Chapter10-异常
通过抛出一个 checked 的异常,你可以强制调用者在 catch 子句中处理异常,或者将其传播出去。只有当在失败的情况下,提供的信息不充分时,你才应该抛出一个 checked 异常。如果一个方法声明抛出受检异常,则调用该方法的代码必须要么捕获这个异常,要么在其方法签名中声明抛出此异常。定义:运行时异常是在运行时发生的异常,编译器不会强制要求处理这些异常。没啥好说的,意思就是可以使用定义好的标准异常,当然我们也可以自定义标准异常。高层应该捕获低层异常,并确保抛出的异常可以用高层抽象解释。
2024-08-20 17:53:17
985
原创 Effective-Java-Chapter9-通用程序设计
书中这个例子,是一个接口,但是具体的实例却是由反射进行创建的,并且类的名称是通过参数类确定了,这就是反射结合接口的最佳实践。同时这个实践是我们不确定类型的时候,也就是说如果我们确定了类型,最好是使用接口直接引用,因为反射有自己的缺陷。我们可以看到第二个while循环引用了上面的变量I但是我们实际上的期望是引用i2所以不符合预期,产生bug,如果我们使用传统的for,我们引用不到i这个变量。第二,基本类型只有全功能值,而每个包装类型除了对应的基本类型的所有功能值外,还有一个非功能值,即 null。
2024-08-20 16:58:10
1061
原创 Effective-Java-Chapter8-方法
与返回基本数据类型相比,返回包含包装类的 Optional 类型的代价高得惊人,因为 Optional 类型有两个装箱级别,而不是零。这句话显而易见,我们使用Optional是为了避免空指针的问题,但是直接返回空那还需要Optional 做什么呢。你应该简单的返回一个空的 List,而不是一个空的 Optional。这个准则告诉我们如果我们对象中的数据是不可变的,那我们我们一定要保证它一定不可变,不能破坏它。这样外面的怎么操作都是在副本上操作,绝对不会影响到我们真正的数据,保证了数据的安全性。
2024-08-20 15:25:29
624
原创 Effective-Java-Chapter7-λ表达式和流
Collection 接口是 Iterable 的一个子类型,它有一个流方法,因此它提供了迭代和流两种访问方式。流范式中最重要的部分是将计算构造为一系列转换,其中每个阶段的结果都尽可能地接近上一阶段结果的纯函数。纯函数的结果只依赖于它的输入:它不依赖于任何可变状态,也不更新任何状态。流管道的计算是惰性的:直到调用 Terminal 操作时才开始计算,并且对完成 Terminal 操作不需要的数据元素永远不会计算。如果你并行的每个流没有依赖关系就可以使用,也就是说每个流的结果是相互独立的,是不具有状态的。
2024-08-19 10:25:12
908
原创 Effective-Java-Chapter6
你可能听过一个说法:标记接口已经过时,更好的方式是标记注解(Item-39)。这个言论是错误的。与标记注解相比,标记接口有两个优点。首先,标记接口定义的类型由标记类的实例实现;标记注解不会。标记接口类型的存在允许你在编译时捕获错误,如果你使用标记注解,则在运行时才能捕获这些错误。例如序列化是个标记接口,这样如果流在写对象的时候,可以判断这个是否实现了Serializable,这个是在编译的时候就能做到的。对比:使用标记注解的情况。
2024-08-17 11:10:36
746
原创 Effective-Java-Chapter5-泛型
因为这样存在类型安全,假如第一步中的创建是合法的,那么由于前面提到的sub[] 和 super[]存在父子关系,所以第三步是合法的,那么在第四步我们这个操作完全没毛病吧,反正是一个对象类型的数组都可以存,但是使用的时候这就报错了ClassCastException。我们不能确定具体是什么类型,但可以确定它一定是Number的一个子类。这样是不是更通用了,答案是如果你还是像上面那样使用,编译通不过,问题就在于你传入的是List《String》,但是往里面添加的元素却是Object类型,类型是不匹配的。
2024-08-13 13:36:15
1090
转载 REST-API 服务端设计技巧
原文:https://github.com/mercyblitz/java-training-camp/tree/main/stage-1/src/biz-project。
2024-08-10 20:19:09
63
原创 模块工程构建技巧-看完没有收获你来砍我哈哈哈
dubbo 也引用了Spring FrameWork,如果我们将Dubbo放在前面看到了木有,用的就是2.7.8里面的依赖。pom 的继承也是单继承,那如果这个时候我们父工程比如继承了apache,但是我们又想继承Spring Boot怎么办呢?我们可以使用 Maven 的optional 为true这个选项。我们可以采用BOM的方式,这样的话不是继承而是聚合模块,效果和Parent是一样的。好首先咋们把这个配置放到这里,那么这个插件有什么用呢?看到了木有,我们只需要修改一个地方,所有的版本都统一了。
2024-08-07 23:32:39
850
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人