去阿里面试,由于简历上写了读过 spring 的源码,所以面试官就问到了:看你读过 spring 的源码,可以介绍一下他的流程么?
肚子好像很多,但是脑子关于spring相关概念,很好混乱,回答的……
那怎办呢?何不试一下,找一下springboot那些约定俗成的Java类命名规范,来辅助自己更好的理解与记忆springboot的源代码
spring框架类命名
IXXX,XXXXImpl:
IXXX一般是接口类,以I开头,表示Interface,XXXXImpl是针对接口的具体实现,表示implement。
Spring 实现接口,多实现时动态加载符合要求的实现类。
项目中经常存在根据模型的某个字段值走不同的处理逻辑,此时我们遵循开闭原则会将处理逻辑抽象成某个接口;调用的时候根据具体传值判断调用哪一个实现类,以往我们可能会使用 策略模式+工厂模式 实现。这篇文章将使用注解+动态代理取代。
如:策略模式+工厂模式实现
以付款为例 支付宝付款、微信付款、银行卡付款。。
1、模型准备
@Data
@AllArgsConstructor
@NoArgsConstructor
public class PayModel {
/**
* 付款方式 (支付宝付款、微信付款、银行卡付款)
* 省略枚举 alipay、wechat、bankcard
*/
private String payType;
/**
* 付款金额
*/
private BigDecimal paymentAmt;
}
2、接口定义
public interface PayService {
/**
* 付款
*/
Boolean pay(PayModel payModel);
}
3、提供接口实现类
@Service("alipay")
public class AliPayServiceImpl implements PayService {
@Override
public Boolean pay(PayModel payModel) {
System.out.println("支付方式:" + payModel.getPayType() + "---------------" + "支付金额:" + payModel.getPaymentAmt());
System.out.println("支付处理逻辑。。。。。");
return Boolean.TRUE;
}
}
@Service("bankcard")
public class BankCardPayServiceImpl implements PayService {
@Override
public Boolean pay(PayModel payModel) {
System.out.println("支付方式:" + payModel.getPayType() + "---------------" + "支付金额:" + payModel.getPaymentAmt());
System.out.println("支付处理逻辑。。。。。");
return Boolean.TRUE;
}
}
@Service("wechat")
public class WechatPayServiceImpl implements PayService {
@Override
public Boolean pay(PayModel payModel) {
System.out.println("支付方式:" + payModel.getPayType() + "---------------" + "支付金额:" + payModel.getPaymentAmt());
System.out.println("支付处理逻辑。。。。。");
return Boolean.TRUE;
}
}
为了取巧 我们定义实现类时 将bena的唯一标识置为 alipay、wechat、bankcard
4、提供工厂
@Component
public class PayFactory {
@Autowired
//此时map中的key 即是 alipay、wechat、bankcard
private Map<String, PayService> payServiceMap;
public PayService getPayService(String type){
PayService payService = payServiceMap.get(type);
if(payService == null) {throw new NullPointerException("未找到类型为【"+type+"】的支付方式实现类");}
return payService;
}
}
5、控制层 + postman调用
@RestController
@RequestMapping("/dy")
public class PayController {
@Autowired
private PayFactory payFactory;
@PostMapping("/pay")
public Boolean pay(@RequestBody PayModel payModel){
PayService payService = payFactory.getPayService(payModel.getPayType());
return payService.pay(payModel);
}
}
Bootstrap,Starter:
一般作为程序启动器使用,或者作为启动器的基类。通俗来说,可以认为是main函数的入口。
starter启动器,可以通过启动器集成其他的技术,比如说: web, mybatis, redis等等.可以提供对应技术的开发和运行环境.
比如: pom中引入spring-boot-starter-web, 就可以进行web开发.
Initializer:
初始化启动。
Spring Initializer 是一个用于创建和初始化 Spring 项目的Web界面或命令行工具。
它提供了一个简单易用的界面,让开发人员可以快速生成和配置基于 Spring 的项目结构,并且可以选择添加额外的依赖、配置文件和其他项目设置。
使用 Spring Initializer,您可以指定项目的基本信息(如项目名称、包名等),选择所需的 Spring Boot 版本和语言(如 Java、Kotlin、Groovy),添加所需的依赖(如 Web、数据库访问、安全等),并自动生成一个可用的 Spring 项目的初始代码结构。
Spring Initializer 支持多种方式创建项目,包括:
在浏览器中访问 https://start.spring.io/,填写相关配置信息后,点击生成项目。
使用 Spring Tool Suite(STS)或 IntelliJ IDEA 等集成开发环境的 Spring Initializer 插件。
通过命令行工具(如 curl 或 HTTPie)发送 HTTP 请求来生成项目文件。
通过 Spring Initializer 创建的项目已经为您配置好了一些基本的 Spring Boot 设置,如自动配置、依赖管理、应用程序入口类等。
您可以根据需要进一步修改和定制项目,以满足特定的开发需求。
Processor:
某一类功能的处理器,用来表示某个处理过程,是一系列代码片段的集合。
Processor是spring Bean生命周期关键触发时机
根据上图可知,实际bean对象涉及生命周期的主要是一个构造器和两个后置处理器(BeanFactoryPostProcessor和BeanPostProcessor)。
BeanPostProcessor与BeanFactoryPostProcessor的初始化、调用的不同时机,正是由于它们的作用不同导致作用域不同决定的。
BeanPostProcessor是针对Bean级别的处理,可以针对某个具体的Bean;而BeanFactoryPostProcessor针对整个Bean的工厂(BeanFactory)