Spring学习沉淀
基本概念
来自Spring官网的定义:End-to-end support for reactive & servlet based apps on the JVM.
理解:为在JVM上运行的基于reactive和servlet的应用提供一个端到端的支持(应该是封装了一些基于Reactive和Servlet的应用所应具备的基本逻辑,基于spring框架的开发不用感知这些事情)
Reactive && Servlet
Reactive
- 定义:Reactive响应式(反应式)编程 是一种新的编程风格
1)react to events对事件立即反应,事件驱动的自然特性使的反应能够立即加载实施,通过避免对共享资源的争用实现可扩展性。
2)react to failure对失败立即反应,在任何级别都可以建立一个能够实现失败恢复的弹性系统。
3)react to users 对用户立即反应,无论任何负载,值得一样的响应时间。
特点:异步或并发、事件驱动、消息通知采用PUSH机制、非阻塞的IO
更多参考:https://www.jdon.com/reactive.html
http://www.reactive-streams.org/
Servlet
- 定义:Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。
特点:这种编程方式是阻塞的IO、一个请求一个线程
Spring注解总结
装配bean
配置类Config
@Configuration : 标记这个类为一个配置类,这种类用java语法创建对象
@ComponentScan(basePackages = {xxxBean.class , xxxxBean.class}) : 标记在Configuration类上 , 扫描xxxBean.class所在包中带@Component标记的类,不配置时默认会扫描与Config类在同一个包中的类
下被@Component标记的类,并为这些类创建bean
@Bean , 标注在Config类的方法中,告诉Spring这个方法会返回一个对象
@Profile(“环境”) : 表示在该环境中采用这种配置
@Conditional:用在@Bean注解的方法上,给定的条件为true时,会创建这个bean
@PropertySource(“文件路径名”) :声明属性源
Bean
@Component : 标记在普通类中,表明Spring要为这个类创建Bean;
@Component(“id”) = @Named(“id”),给bean定义一个id
@Autowired = @Inject , 注入bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) : 注解在bean上,定义为原型bean,每次注入或者通过Spring应用上下文获取时都会创建一个新的bean实例
测试类
@RunWith(SpringJUnit4ClassRunner.class):标记测试类,在测试开始的时候自动创建Spring应用上下文
@ContextConfiguration(classes = xxx.class)
告诉测试类在哪个Config类中加载配置
@ActiveProfiles(“dev”) : 指定运行测试时要激活那个profile
源码学习
依赖注入和控制反转(spring容器)
spring的整体架构如图,基础是core container(IOC容器),在此之上才有AOP、DATA和WEB后面的繁荣。spring容器最核心的三个jar包是bean,context,core。bean是spring基石,一切结尾bean,context维护了应用的上下文,如果bean是演员,那么context就是舞台,而core则是道具。
应用上下文(ApplicationContext)
ApplicationConext:从类图的继承关系我们看到基础类ApplicationConext继承了资源,消息,事件,环境,工厂五种能力,ApplicationConext只包含了简单的只读属性。
ConfigurableApplicationContext:继承了生命周期管控能力,同时继承ApplicationConext,拓展了context的环境,事件等写的属性。
AbstractApplicationContext:大部分的能力在该类定义实现,该类继承类加载能力接口DefaultResourceLoader和读写context的ConfigurableApplicationContext,ioc容器启动的流程详细解析该类。
BeanFactory
spring的世界一切皆为bean,几个重要的接口和类
AliasRegistry:别名注册表
BeanFactory:工厂
BeanDefinitionRegistry:
DefaultListableBeanFactory这个收敛了所以上层的能力,具体包含核心的BeanDefinitionRegistry和BeanFactory,也就是bean的定义和生产bean的工厂。
Bean创建过程
一个简单的demo:
- 测试启动类Application
package com.alipay;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
/**
- Unit test for simple App.
*/
public class AppTest
{
public static void main(String[] args){
String XMLPath = "springdemo/src/spring-config.xml";
ApplicationContext applicationContext = new FileSystemXmlApplicationContext(XMLPath);
ILogin login = (ILogin) applicationContext.getBean("loginService");
login.loginCheck("boy", "123");
}
}
- spring配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="loginService" class="com.alipay.LoginImpl">
</bean>
</beans>
经过以上几个步骤之后,我们成功的将配置文件里面描述的对象,通过spring的IOC容器创建了出来,而且不需要再使用new的形式来创建对象
IOC容器启动流程
总体流程图:
类继承图:
- 创建上下文对象
这里调用了FileSystemXmlApplicationContext的构造方法,传入xml文件的路径(相对路径),xml的构造方法进行了下面的调用。
public FileSystemXmlApplicationContext(String configLocation) throws BeansException {
this(new String[] {configLocation}, true, null); //this(参数a,参数b,参数c)可以调用另外一个构造函数
}
public FileSystemXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh(); // 核心方法
}
}
- 核心方法refresh解读
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplica