加载中

Java

文章分类

浏览该分类下的所有文章

237 篇文章 20

IDEA 2022.2版本新特性

IDEA 2022.2 引入远程开发模式,后端部署在服务器,前端 thin client 通过 SSH 交互,提升大项目本地体验;全面支持 Spring 6 与 Spring Boot 3 新特性;新增快捷键 ⌃⇧. /⌃⇧, 可全局调节编辑器字体大小;JSON、YAML、properties 中的 http/https 链接可直接点击打开或生成请求;实验性 GraalVM 原生调试器上线;Bean Validation 注解支持引用与折叠;此外还加入 Groovy 集成查询、升级 Kubernetes/Docker、运行当前文件、导入受信任 SSL 证书、HTTP 客户端改进、从 JBR11 切换到 JBR17,以及代码检查、补全和配置文件的增强。

解决SpringBoot打成jar包无法加载resources下文件的问题

SpringBoot 打成 jar 包后,位于 resources 目录的文件(如 application.yml、ip2region.db)在 Linux 环境下无法直接读取。解决思路是通过 Spring 的 **PathMatchingResourcePatternResolver** 将资源以 **Resource** 形式加载,再使用 **Apache Commons‑IO** 的 **FileUtils.copyInputStreamToFile** 将其写入本地文件系统,从而实现文件的可访问。关键代码包括: ```java ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); Resource[] resources = resolver.getResources("ip2region.db"); Resource resource = resources[0]; InputStream is = resource.getInputStream(); File target = new File("ip2region.db"); FileUtils.copyInputStreamToFile(is, target); is.close(); ``` 需在项目中引入 **spring‑core** 与 **commons‑io** 两个依赖。这样即可在 jar 包运行时正确加载 resources 下的文件。

StringUtils部分API的用法与区别

本文介绍了 Apache Commons Lang3 中 `StringUtils` 常用 API 的用法及区别。通过示例代码说明 `isEmpty` 仅判断 null 与空串,空格不算空;`isBlank` 同时把空格视为空值。进一步比较了 `isAnyEmpty`/`isNoneEmpty`(分别判断是否存在任意空值或全部非空)与 `isAnyBlank`/`isNoneBlank`(同理但把空格算作空)。文中列出并简要解释了 `StringUtils` 其它常用方法,如 `trim/strip、equals、startsWith、endsWith、contains、substring、split/join、replace、pad、case 转换 等”,并提供官方 API 链接供查阅。全文通过代码输出展示了各方法的返回逻辑,帮助读者快速掌握空值判断及字符串处理的最佳实践。

过多赠予,无所适从

文章介绍了 Spring 中 @Autowired 注入时出现 “required a single bean, but 2 were found” 的常见错误。通过一个学生管理系统的示例,展示当同一接口有多个实现(如 Oracle 与 Cassandra 数据服务)时,Spring 在自动装配过程中无法确定唯一候选 Bean,导致启动失败。文中解析了 @Autowired 的底层实现流程,说明候选 Bean 的优先级由 @Primary、@Priority 或 Bean 名称匹配决定,并指出默认 required 为 true 时必须唯一。针对问题,提供了三种解决思路:①在其中一个实现上加 @Primary;②使用 @Qualifier 或属性名与 Bean 名称精确匹配;③将依赖改为集合、数组等可接受多 Bean 的类型。最后强调选择方案需符合业务需求,避免随意覆盖实现。

原型 Bean 被固定

案例展示了在 Spring 中把原型 Bean(@Scope(PROTOTYPE))直接 @Autowired 到单例 Controller 时,属性只在首次注入后被固定,导致原型特性失效并报错。分析源码发现 Autowired 只在 Bean 创建时一次性通过反射注入,后续不会重新获取实例。解决办法有两种:① 注入 ApplicationContext,在使用时通过 applicationContext.getBean(ServiceImpl.class) 手动获取新实例;② 在 Controller 中声明 @Lookup 标记的方法,Spring 会生成 CGLIB 子类并在每次调用时从 BeanFactory 取回新的原型 Bean,方法体代码甚至可以为 null。文章还简要说明了 @Lookup 的实现原理及 Spring 反射注入的潜规则,提醒开发者在单例中使用原型时必须采用动态获取方式。

定义的 Bean 缺少隐式依赖

在 Spring 中,标记为 `@Service` 的类会被注册为 Bean。若该类显式声明构造器,Spring 在实例化时会自动根据构造器参数去容器中查找同类型的 Bean 并注入。示例 `ServiceImpl(String serviceName)` 因容器中没有 `String` 类型的 Bean,导致启动时报 “required a bean of type 'java.lang.String' that could not be found”。源码 `AbstractAutowireCapableBeanFactory#createBeanInstance` → `autowireConstructor` → `resolveDependency` 体现了这一流程。解决办法是显式声明相应的 Bean,例如 `@Bean public String serviceName(){ return "MyServiceName"; }`。此外,若同一类存在多个构造器且都可匹配,Spring 将无法确定使用哪一个,进而报错。因此在定义 Bean 时需遵循 Spring 的隐式依赖规则,避免把普通类当作可直接 `new` 的对象使用。

隐式扫描不到 Bean 的定义

SpringBoot 在入口类上使用 @SpringBootApplication 时,若未显式配置 @ComponentScan,会默认只扫描入口类所在的包及其子包。将 HelloWorldController 移到其他包后,超出默认扫描范围,导致 Bean 未被注册、接口失效。解决办法是在入口类上添加 @ComponentScan(或 @ComponentScans)并指定目标包(如 com.zou.controller),但要注意显式指定会覆盖默认包,需要自行加入所有需要的扫描路径。

Java8新特性之Stream流

Java 8 Stream 是对集合进行函数式操作的抽象,不保存数据、不会修改源集合,采用惰性求值并在终止操作时才计算。根据状态和短路特性,Stream 可分为无状态/有状态、非短路/短路操作。文章介绍了创建流的多种方式(collection、array、Stream.of/iterate/generate、BufferedReader、Pattern 等),以及常用的中间操作(filter、limit、skip、distinct、map、flatMap、sorted、peek)和终止操作,包括匹配/聚合(allMatch、anyMatch、findFirst、count、max、min 等)、规约(reduce)以及收集(collect)及其 Collector 实现(toList、toSet、toMap、joining、counting、summing、averaging、summarizing 等),并示例并行流的行为差异。整体展示了 Stream 在过滤、映射、排序、统计等场景下的简洁高效用法。

全面拥抱Java17!

Java 17是自Java 11后的新LTS版本,本文聚焦语法升级,系统介绍了九大特性并配以代码示例:文本块(多行字符串免转义)、Switch Expression(支持箭头、返回值和yield)、record(简洁不可变数据类)、sealed class(受限继承层次)、instanceof 模式匹配(类型检查与变量声明合一)、Helpful NullPointerExceptions(精确指示空指针来源)、日期周期格式化、紧凑数字格式化以及Stream.toList()简化列表收集。通过这些改进,代码可读性、简洁性和调试效率显著提升。

基于SpringBoot的在线招聘网站

本文介绍了基于SpringBoot、MyBatisPlus、Layui等技术栈实现的在线招聘系统的整体架构与功能。系统分为游客、求职者、HR和管理员四类角色,提供职位浏览、条件检索、在线聊天、简历生成与分享、岗位发布与管理、员工与公司信息维护、聊天记录审查及用户封禁等模块,并通过验证码、敏感词过滤和Redis、Shiro等安全机制保障登录与交互安全。

面试现场【Spring篇】

介绍 Spring 常见面试要点:涉及的设计模式有工厂、代理、单例、模板方法、装饰、观察者、适配器;核心模块包括 Core、Context、Web、MVC、DAO、ORM、AOP。阐述 IOC 与 DI 概念,BeanFactory 与 ApplicationContext 的区别以及 FactoryBean 的作用;@Repository、@Service、@Component、@Controller 的层次区分;DI 的三种注入方式。说明 AOP 原理、通知类型、动态/静态代理、JDK 与 CGLIB 的差异,以及 Spring AOP 与 AspectJ AOP 的区别。概述 Bean 生命周期四阶段和三级缓存解决单例循环依赖的机制。比较 @Autowired 与 @Resource 的注入策略;列出 Spring 事务的隔离级别和传播机制。最后简要说明 SpringBoot 自动装配的实现流程。

遍历HashMap的几种方式及效率对比

文章通过两套含 100 万条记录的 HashMap(键为连续整数和等差整数)分别测试了六种遍历方式:keySet+Iterator、keySet+for、entrySet+Iterator、entrySet+for、values+Iterator、values+for,测量了遍历 key、value、key + value 的耗时。结果显示:① 键值越简单(连续整数)查找越快;② 大数据量时遍历 key + value 采用 entrySet(尤其 for 循环)比 keySet 更高效;③ 只需获取 value 时直接遍历 values 效率最高。由此推荐在实际开发中根据需求选择相应的遍历方式,以获得最佳性能。