Spring主要概念

2023-07-01  本文已影响0人  蓝调_4f2b

1. 核心组件

1.1 Bean对象构建

userService userService = (UserService)context.getBean("userservice");
UserService userServiceimpl = new UserService();

@Autowired
public class UserService() {}

1.1.1 依赖注入链:

(1) UserService.class
(2) 无参构造方法
(3) 生成Bean对象
(4) 通过Autowired注解进行依赖注入
(5) 判断该类象是否实现了BeanNameAware接口、
BeanClassLoaderAware接口、BeanFactoryAware接口;若有,则执行Aware回调
(6) 判断该对象中是否存在某个方法被@PostConstruct注解了,如果存在,Spring会调用当前对象的此方法
(7) 判断该对象是否实现了InitializingBean接口,如果实现了,就表示当前对象必须实现该接口中的afterPropertiesSet()方法;若有,则调用
(8) 判断是否需要执行Aop逻辑;是,则执行Aop逻辑,返回的对象是Aop后的代理对象
(9) 不用执行Aop,则返回Bean对象
(11) 完成创建后,如果是单例Bean,则存入Map<String,
Object>,Map的key为beanName,value为Bean对象;
(12) 原型Bean类型,不存入缓存;

1.1.2 推断构造方法

(1)如果一个类只有一个构造方法,只能用这个构造方法
(2)如果一个类存在多个构造方法,框架不知如何抉择,优先选择无参构造方法
(3)如果某个构造方法上加了@Autowired注解,那就表示程序员告诉Spring就用这个加了注解的方法,那Spring就会用这个加了@Autowired注解构造方法
注:Spring根据入参的类型和入参的名字去Spring中找Bean对象
(1)先根据入参类型找,如果只找到一个,那就直接用来作为入参
(2)如果根据类型找到多个,则再根据入参名字来确定唯一一个
(3)最终如果没有找到,则会报错,无法创建当前Bean对象

1.2 Spring事务

在某个方法上加了@Transactional注解后,就表示该方法在调用时会开启Spring事务,而这个方法所在的类所对应的Bean对象会是该类的代理对象。
Spring事务的代理对象执行某个方法时的步骤:
(1)判断当前执行的方法是否存在@Transactional注解
(2)利用事务管理器,创建一个数据库连接
(3)修改数据库连接的autocommit为false
(4)执行sql
(5)执行完了之后如果没有出现异常,则提交,否则回滚
注:Spring事务是否会失效的判断标准:某个加了@Transactional注解的方法被调用时,要判断到底是不是直接被代理对象调用的(用到了Aop技术),如果是则事务会生效,如果不是则失效。

1.3 尝试手写Bean加载框架

public static Test {
  AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
 UserService user = (UserService) context.getBean(name);
}

// 加载的Bean
@Component
@scope("prototype")
public class UserService() {}

加载步骤:
(1)扫描方式:由类加载方式进行指定文件的加载
(2)针对@Component注解,生成BeanDefine对象(未完全初始化的对象,用于缓存中)
(3)存入BeanDefinitionMap结构中
(4)初始化前,额外判断BeanPostProcessor方法(Aop切片)
(5)将BeanPostProcessor实例化的实例存入BeanPostProcessorList队列中
(6)单例对象创建后存入singletonPool(单例池中)
(7)多例不存入缓存

2. 核心概念解析

2.1 BeanDefinition

表示Bean的定义,存在描述Bean属性的字段

2.1.1 Bean的定义方式

(1)声明式定义Bean
@Component / @Bean

xml文件中配置:<Bean class = "" scope = ""/>
(2)编程式定义

AbstractBeanDefinition beanDefine = BeanDefinitionBuilder.genericBean();
beanDefine.setBeanClass();
beanDefine.setScope();
context.registerBeanDefinition("Bean", beanDefinition);  // 注册bean

2.2 BeanFactory工厂

BeanFactory表示Bean工厂,BeanFactory会负责创建Bean,并且提供获取Bean的API。

2.2.1 实现组件之一:ApplicationContext

相关特性:

public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, 
MessageSource, ApplicationEventPublisher, ResourcePatternResolver {}

(1)支持消息国际化
(2)支持资源加载功能

Resource res = context.getResource(path);

用于扫描、配置文件初始化等
(3)获取运行时环境变量
(4)支持事件发布功能

context.publishEvent("123");

2.2.2 BeanFactory作用

在Spring的源码实现中,当new一个ApplicationContext时,其底层会new一个BeanFactory出来,当使用ApplicationContext的某些方法时,比如getBean(),底层调用的是BeanFactory的
getBean()方法。

2.3 类型转化工具

(1)PropertyEditor
(2)ConversionService
(3)TypeConverter
(4)OrderComparator(处理@order):
OrderComparator是Spring所提供的一种比较器,可以用来根据@Order注解或实现Ordered接口来执行值进行笔记,从而可以进行排序。

@Order(3) 
public class A { 
@Override 
public String toString() { 
return this.getClass().getSimpleName(); 
}
}

2.4 初始化前/后置处理逻辑(BeanPostProcessor)

2.4.1 BeanPostProcess

表示Bean的后置处理器,可以通过实现接口方式定义一个或多个BeanPostProcessor

@Component 
public class MyBeanPostProcessor implements BeanPostProcessor { 
  @Override 
public Object postProcessBeforeInitialization(Object bean, String beanName) {
  // 添加逻辑,在bean初始化前执行该逻辑
}
}

注:一个BeanPostProcessor可以在任意一个Bean的初始化之前以及初始化之后去额外的做一些用户自定义的逻辑

2.4.2 BeanFactoryPostProcessor

BeanFactoryPostProcessor表示Bean工厂的后置处理器,其实和BeanPostProcessor类似,
BeanPostProcessor是干涉Bean的创建过程,BeanFactoryPostProcessor是干涉BeanFactory的创建过程。
注:可以在postProcessBeanFactory()方法中对BeanFactory进行加工。

2.4.3 FactoryBean

我们可以通过BeanPostPorcessor来干涉Spring创建Bean的过程,但是如果我们想一个Bean完完全全由我们来创造,也是可以的,比如通过FactoryBean.

@Component 
public class ZhouyuFactoryBean implements FactoryBean {
  @Override 
public Object getObject() throws Exception { 
  UserService userService = new UserService();
  return userService ;
}
@Override 
public Class<?> getObjectType() { 
  return UserService.class; 
}
}

注:通过上面这段代码,我们自己创造了一个UserService对象,并且它将成为Bean。但是通过这种方式创造出来的UserService的Bean,只会经过初始化后,其他Spring的生命周期步骤是不会经过的,比如依赖注入。

2.5 Spring自带过滤器

2.5.1 ExcludeFilter和IncludeFilter

这两个Filter是Spring扫描过程中用来过滤的。ExcludeFilter表示排除过滤器,IncludeFilter表示包含过滤器。
(1)ExcludeFilter扫描某路径下注解Component注解排除某注解

@ComponentScan(value = "com.zhouyu", excludeFilters = 
{@ComponentScan.Filter( type = FilterType.ASSIGNABLE_TYPE,
  classes = UserService.class)}) 
public class AppConfig { } 

扫描com.zhouyu这个包下面的所有类,但是排除UserService类,也就是就算它上面有@Component注解也不会成为Bean。
(2)IncludeFilterr扫描某路径下注解Component时,即使类没有注解也将其扫描为Bean对象
(3)注:在Spring的扫描逻辑中,默认会添加一个AnnotationTypeFilter给includeFilters,表示默认情况下Spring扫描过程中会认为类上有@Component注解的就是Bean。

2.6 类的元数据(MetadataReader、ClassMetadata、AnnotationMetadata)

在Spring中需要去解析类的信息,比如类名、类中的方法、类上的注解,这些都可以称之为类的元数据,所以Spring中对类的元数据做了抽象,并提供了一些工具类。MetadataReader表示类的元数据读取器,默认实现类为SimpleMetadataReader。
注:为什么要使用ASM技术,Spring启动的时候需要去扫描,如果指定的包路径比较宽泛,那么扫描的类是非常多的,那如果在Spring启动时就把这些类全部加载进JVM了,这样不太好,所以使用了ASM技术。

上一篇 下一篇

猜你喜欢

热点阅读