Spring主要概念
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技术。