前言
在上文 java并发学习之Reentrantlock学习 中,讲解了AQS的子类独占锁Reentrantlock
,本节讲解一下AQS的子类共享锁实现。CountDownLatch
是共享锁的一种实现。
在上文 java并发学习之Reentrantlock学习 中,讲解了AQS的子类独占锁Reentrantlock
,本节讲解一下AQS的子类共享锁实现。CountDownLatch
是共享锁的一种实现。
在上文 AbstractQueuedSyncchronizer学习 中,对AQS进行了相应的学习,知道AQS是Java并发包的一个同步基础机制。该接口有几个常用的子类,本文章主要对其中最常用的子类ReentrantLock
类进行学习,其他子类后续再讲。
1 | //可重入独占锁,实现了Lock接口 |
由类实现可知,该类持有一个Sync
对象,提供所有的同步机制。
在日常编程中,我们经常使用到的锁:ReentrantLock
,CountDownLatch
,ReentrantReadWriteLock
等,他们的内部都一个名为Sync
的静态抽象内部类,该类都实现了同一个名为AbstractQueuedSyncchronizer
的接口。该接口为Java并发包提供的一个同步基础机制。
1 | abstract static class Sync extends AbstractQueuedSynchronizer{ |
AbstractQueuedSynchronizer在JDK1.8中还有如下图所示的众多子类:
为了方便,通常使用AQS代替AbstractQueuedSynchronizer。
JdbcTemplate是spring对jdbc的封装,提供了操作数据库的模板。
类图分析:
javax.sql.DataSource
标准接口之上。DataSource可以看做JDBC的连接工厂。原来有一个字段id,为自增,主键,索引。现在要新增一个字段s_id为自增,主键,索引.同时把原来的主字段改成普通字段,默认值为0.
1 | Alter table xxx change s_id s_id int(10) NOT NULL DEFAULT 0; //去除原来字段的自增属性,不然无法删除这个主键 |
AOP(Aspect-Oriented Programming):面向切面编程。OOP(Object-Oriented Programming)面向对象的编程。其实AOP是对OOP的一种补充。OOP面向的是纵向编程,继承,封装,多态
是其三大特性,而AOP是面向横向编程。在OOP中,模块化的关键是类(class)
,而在AOP中,模块化的关键是切面(aspect)
。
一个连接点总是表示一个方法的执行
。around
, before
, after
等不同类型的通知。在讲解properties文件中${…}替换之前,首先介绍一下BeanFactoryPostProcessor
类。
BeanFactoryPostProcessor
和BeanPostProcessor
,这两个接口,都是spring初始化bean时对外暴露的扩展点
。两个接口名称看起来很相似,但作用及使用场景却不同。
BeanFactoryPostProcessor 接口
源码
1 | public interface BeanFactoryPostProcessor { |
此接口只有一个方法,接受ConfigurableListableBeanFactory
参数。实现该接口,可以在spring的bean创建之前,修改bean的定义属性
。即读取bean的配置元数据,并可以根据需要进行修改(直白点,就是修改bean的BeanDefinition中相应信息)。由Bean加载流程梳理之BeanDefinitions加载 可知,在获取BeanFactory时,即接口中唯一方法的参数,Spring框架会将加载的BeanDefinitions放进BeanFactory,因此该接口中的方法可以获取所有bean的BeanDefinition。然后进行相应修改。
BeanFactoryPostProcessor是在spring容器加载了bean的定义文件之后,在bean实例化之前执行的
。
另一篇 Bean加载流程梳理之BeanDefinitions加载,分析了Spring上下文加载的代码入口及BeanDefinitions加载流程的梳理。在AbstractApplicationContext的refresh方法中,首先获取了ConfigurableListableBeanFactory
类型的beanFactory,然后对beanFactory进行了一系列的设置及其他资源的设置。一切准备就绪后,使用了finishBeanFactoryInitialization
方法完成了对于所有非懒加载的Bean的初始化。
1 | protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { |
功能讲解:
BeanDefinitions加载是发生在容器获取BeanFactory时,具体是在刷新BeanFactory后进行BeanDefinitions的加载。BeanDefinitions成功加载后,可供后续获取bean对象做准备。
Spring的重要特征之一是IOC(Inversion of Control),即:控制反转。IOC技术促进了松耦合。Spring提供了两种IOC容器类型:BeanFactory和ApplicationContext,在类结构上,ApplicationContext是继承自BeanFactory的。下面讲解ApplicationContext容器。
下面有很简单的一段代码可以作为Spring中Bean加载的入口:
1 | ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); |
ClassPathXmlApplicationContext用于加载CLASSPATH下的Spring配置文件。由示例可知,context.getBean("beanName");
即可获取到Bean的实例,那么必然ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
就已经完成了对所有Bean实例的加载,因此可以通过ClassPathXmlApplicationContext作为Bean加载源码入口。
类图: