概述
1、Spring 诞生于 2003 年,是对早期 J2EE 规范复杂性的响应,使创建 Java 企业应用程序变得非常简单
2、除了Java语言,还支持 Groovy 和 Kotlin 作为 JVM 上开发的替代语言
3、从 Spring Framework 6.0 开始, Spring 需要 Java 17+ 的支持
核心技术
- Spring 框架的核心是容器模块,主要包括【依赖注入】和【配置模型】
- Spring 框架除自身之外还延伸了其它子项目,如Spring mvc,Spring Boot,Spring Cloud等等
Ioc容器(控制反转)
IOC容器是Spring框架的核心,又被称为DI(依赖注入)
将原本需要由开发者自行创建Bean的工作交由容器来完成,通过容器来实现Bean的管理
1、IoC容器的基础包:【org.springframework.beans】 和 【org.springframework.context】
2、【BeanFactory】接口是实现 IoC 容器相关功能的顶级接口,默认Bean采用的是延迟加载机制
3、【ApplicationContext】接口继承【BeanFactory】接口,默认Bean采用的是实时加载,并且新增了其它功能(事件传播、电子邮件、国际化等等
自定义Bean并纳入Ioc容器
- 不建议使用基于 xml 方式来配置元数据,更推荐使用基于 JAVA 代码的方式来配置元数据
- FactoryBean和@Configuration的功能类似,个人比较推荐@Configuration来实现自定义Bean并纳入容器
FactoryBean
@Component
public class DemoFactoryBean implements FactoryBean<Demo> {
// 该方法返回该 FactoryBean 生产的对象。我们需要实现该方法以给出自己对象实例化逻辑
@Override
public Demo getObject() throws Exception {
Demo demo = new Demo();
demo.setDesc("DemoFactoryBean");
return demo;
}
// 返回 FactoryBean 生产的对象类型。如果预先无法确定,则返回null
@Override
public Class<?> getObjectType() { return Demo.class; }
// FactoryBean 生产的对象是否要以singleton(单例)形式存于容器中
@Override
public boolean isSingleton() { return true; }
}
@Controller
@RequestMapping("demo")
public class DemoController {
@Resource
private DemoFactoryBean demoFactoryBean;
}
@Configuration和@Bean
@Configuration
public class Demo{
public Demo() {
System.out.println("第1步:容器初始化");
}
@Bean(value = "demo", initMethod = "myInit", destroyMethod = "myDestroy")
// singleton 首次创建,多次从缓存中取
// prototype每调用一次创建一个新的实例
// request 每一个请求创建一个新的实例
// session 同一个session共享同一个实例
@Scope("singleton")
public Demo getDemo() {
System.out.println("第1.1步:初始化容器中的bean");
Demo demo = new Demo();
demo.setDesc("测试Bean的生命周期");
return demo;
}
}
AOP
-
面向对象编程(OOP)是通过调用方法来实现某些功能,而无需关注方法实现细节
-
AOP是对OOP的补充,将通用功能封装成独立的模块,在合适的时机将这些模块横向切入到应用中的指定位置,在不更改原有代码结构的基础上对代码的功能进行增强
-
配置案例:
通过@Aspect注解开启AOP功能
通过@Pointcut注解定义切点
通过通知类型来实现具体的业务逻辑
环绕通知(@Around)(前置和后置):在方法调用之前和之后,执行通知
前置通知(@Before):方法执行之前,执行通知
返回通知(@AfterReturning):方法执行成功之后,执行通知
异常通知(@AfterThrowing):方法执行异常之后,执行通知
后置通知(@After):方法执行之后,不考虑其结果,执行通知
- 使用环绕通知注意事项:
目标方法发生异常时,会触发执行异常通知和全局异常捕获,此时【返回通知】和【环绕通知-后置】不再执行
调用目标方法时用try-catch捕获了异常,但没有重新抛出,则事务切面无法感知异常,误认为方法执行成功,从而提交事务
- 应用场景
记录请求和响应的日志
事件传播(观察者模式)
场景案例:订单入库成功后,需要发送短信通知用户。一般情况都会把短信通知加在订单入库的后边,这样做违反了单一职责(订单保存功能里变不应该杂糅消息通知功能),如果后期需要添加微信消息通知功能,则需要在原有的基础上进行额外添加,这样做又违反了开闭原则(对拓展开放,对修改关闭)。优化方案:通过观察者模式使创建订单和消息通知功能进行分离
@Controller
@RequestMapping("test")
public class TestController {
@Resource
private ApplicationContext applicationContext;
@GetMapping("event")
@ResponseBody
public Object event() throws Exception {
// TODO 创建事件
OrderSaveEvent orderSaveEvent = new OrderSaveEvent(this,"000000","创建成功");
// TODO 发布事件
applicationContext.publishEvent(orderSaveEvent);
return ResponseUtil.success();
}
}
- 自定义订单保存成功事件
public class OrderSaveEvent extends ApplicationEvent {
private String orderNum;
public String getOrderNum() { return orderNum; }
public void setOrderNum(String orderNum) { this.orderNum = orderNum; }
private String desc;
public String getDesc() { return desc; }
public void setDesc(String desc) { this.desc = desc; }
public OrderSaveEvent(Object source, String orderNum, String desc) {
super(source);
this.desc = desc;
this.orderNum = orderNum;
}
}
- 短信通知监听器(接口、无序)
@Component
@Async("asyncTaskExecutor")
public class OrderSmsListener implements ApplicationListener<OrderSaveEvent> {
@Override
public void onApplicationEvent(OrderSaveEvent event) {
LoggerUtil.info(MessageFormat.format("短信提示:订单【{0}】{1}",event.getOrderNum(),event.getDesc()));
}
}
- 微信通知监听器(注解、无序)
@Component
@Async("asyncTaskExecutor")
public class OrderSmsListener {
@EventListener
public void sms(OrderSaveEvent event) {
LoggerUtil.info(MessageFormat.format("微信提示:订单【{0}】{1}",event.getOrderNum(),event.getDesc()));
}
}
相关框架
SpringMVC
SpringMvc是Spring框架中的一部分,基于JAVA实现MVC的WEB框架,其核心就是通过前端控制器(DispatcherServlet)将请求分发到不同的控制器(早期通过继承HttpServlet类实现该功能,Spring2.5开始通过@Controller实现)
-
启动原理
应用启动时会读取(webapp/WEB-INF/web.xml)文件来加载Spring容器(applicationContext.xml)和Servlet容器(dispatcher-servlet.xml) -
applicationContext.xml(Spring容器)
扫描相关类并纳入IOC容器(@Component、@Service、@Repository等等)
配置数据库连接池和事务
自定义Bean -
dispatcher-servlet.xml(Servlet容器)
扫描相关类并纳入IOC容器(@RestController、@Controller)
配置静态资源解析器、视图解析器、文件上传解析器
配置拦截器
SpringBoot
SpringBoot是Spring框架中的一部分,相比于SpringMvc更加灵活,开箱即用:
1、内置多种Web容器
2、提供Actuator监控模块对系统的运行环境进行监控
3、提供众多starter依赖项(在pom中引入相关starter依赖即可根据SpringBoot主版本号自动加载与之对应的Jar包)
- 复合注解
【自动扫描Bean】@ComponentScan,自动扫描DemoApplication启动类同级目录中符合条件的组件的Bean纳入IOC容器
【自动配置Bean】@EnableAutoConfiguration,将DemoApplication启动类同级目录中符合自动配置条件(被@Configuration修饰的类)的Bean纳入IOC容器
【基于JavaConfig创建Bean】@SpringBootConfiguration继承@Configuration,将当前类标记为配置类并纳入IOC容器
- 启动参数配置
java -jar demo.jar --spring.profiles.active=test
在默认 application.properties 或 application.yml 基础上追加项目中的 application-test.properties 或 application-test.yaml
----
java -jar demo.jar --spring.config.additional-location=./application-test.yml
在默认 application.properties 或 application.yml 基础上追加本地硬盘上的 application-test.yml