Spring Framework

​ Spring 是一个开源框架,是为了解决企业应用程序开发复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许您选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架。

Spring—架构图- Louis - OSCHINA

组成 Spring 框架的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现。每个模块的功能如下:

Core Container

由 spring-core, spring-beans, spring-context, springcontext-support, 和 spring-expression (Spring Expression Language) 模块组成。

  • Spring-core和spring-beans提供了 Spring 框架的基本功能,包括控制反转(Inversion of Control,简称IoC)和依赖注入(Dependency Injection简称DI)的特性。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory将应用程序的配置和依赖性规范与实际的应用程序代码分开。

  • spring-context是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。

  • spring-expression主要提供了spring的表达式语言(Expression Language),它是对标准EL的扩展。

AOP and Instrumentation

  • Spring AOP 模块直接将面向方面的编程功能集成到了 Spring 框架中。

  • 单独的spring-aspects模块用来支持与AspectJ的集成。

  • spring-instrument模块提供在特定的应用程序服务器中类仪器支持和类加载器实现。

Messaging

  • Spring Framework 4引入的,主要用来实现基于消息(message)的应用程序开发。

Data Access/Integration

  • 该层包括JDBC, ORM, OXM, JMS, and Transaction等模块,主要实现与持久层(如数据库)的连接及事务的控制,如spring-jdbc、spring-tx、spring-orm、spring-oxm、spring-jms。

  • 从Spring Framework 4.1开始,spring-jms支持与spring-messaging进行集成。

Web

  • Web部分包括spring-web, spring-webmvc, spring-websocket, and springwebmvc-portlet几个模块。

  • spring-web模块提供了基本的面向web的开发特性,如多文件上传功能、通过Servlet监听和基于web的应用程序上下文初始化IoC等。

  • spring-webmvc包括Spring MVC模型及Web应用开发中REST风格的Web Service实现。

  • spring-webmvc-portlet提供了门户导入的组件信息支持,注意ModelAndView在该包和webmvc包都存在,在使用SpringMVC时需要注意,不用引入错了。

Test

  • Spring测试功能模块支持。

  • Spring 框架的功能可以用在任何 J2EE 服务器中,大多数功能也适用于不受管理的环境。Spring 的核心要点是:支持不绑定到特定 J2EE 服务的可重用业务和数据访问对象。毫无疑问,这样的对象可以在不同 J2EE 环境 (Web 或 EJB)、独立应用程序、测试环境之间重用。

IOC 容器的初始化过程

容器的高层视图

Spring 启动时读取应用程序提供的Bean配置信息,并在Spring容器中生成一份相应的Bean配置注册表,然后根据这张注册表实例化Bean,装配号Bean之间的依赖关系,为上层应用提供准备就绪的运行环境。

spring ioc aop | yswape

初始化过程

  • 实际的构造方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
throws BeansException {
//super方法为容器设置好Bean资源加载器
//该方法最终会调用到AbstractApplicationContext的无参构造方法
//这里会默认设置解析路径的模式为Ant-style
super(parent);
//设置Bean定义资源文件的路径
setConfigLocations(configLocations);
if (refresh) {
//调用容器的refresh,载入BeanDefinition的入口
refresh();
}
}
  • refresh()方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
// 初始化属性配置文件、检验必须属性以及监听器
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// 给beanFactory设置序列化id
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 向beanFactory中注册了两个BeanPostProcessor,以及三个和环境相关的bean
// 这两个后置处理器为ApplicationContextAwareProcessor和ApplicationListenerDetector
// 前一个后置处理是为实现了ApplicationContextAware接口的类,回调setApplicationContext()方法,
// 后一个处理器时用来检测ApplicationListener类的,当某个Bean实现了ApplicationListener接口的bean被创建好后,会被加入到监听器列表中
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
// 空方法,由子类实现
postProcessBeanFactory(beanFactory);
// 执行所有的BeanFactoryPostProcessor,包括自定义的,以及spring内置的。默认情况下,容器中只有一个BeanFactoryPostProcessor,即:Spring内置的,ConfigurationClassPostProcessor(这个类很重要)
// 会先执行实现了BeanDefinitionRegistryPostProcessor接口的类,然后执行BeanFactoryPostProcessor的类
// ConfigurationClassPostProcessor类的postProcessorBeanFactory()方法进行了@Configuration类的解析,@ComponentScan的扫描,以及@Import注解的处理
// 经过这一步以后,会将所有交由spring管理的bean所对应的BeanDefinition放入到beanFactory的beanDefinitionMap中
// 同时ConfigurationClassPostProcessor类的postProcessorBeanFactory()方法执行完后,向容器中添加了一个后置处理器————ImportAwareBeanPostProcessor
invokeBeanFactoryPostProcessors(beanFactory);
// 注册所有的BeanPostProcessor,因为在方法里面调用了getBean()方法,所以在这一步,实际上已经将所有的BeanPostProcessor实例化了
// 为什么要在这一步就将BeanPostProcessor实例化呢?因为后面要实例化bean,而BeanPostProcessor是用来干预bean的创建过程的,所以必须在bean实例化之前就实例化所有的BeanPostProcessor(包括开发人员自己定义的)
// 最后再重新注册了ApplicationListenerDetector,这样做的目的是为了将ApplicationListenerDetector放入到后置处理器的最末端
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
// 初始化MessageSource,用来做消息国际化。在一般项目中不会用到消息国际化
initMessageSource();
// Initialize event multicaster for this context.
// 初始化事件广播器,如果容器中存在了名字为applicationEventMulticaster的广播器,则使用该广播器
// 如果没有,则初始化一个SimpleApplicationEventMulticaster
// 事件广播器的用途是,发布事件,并且为所发布的时间找到对应的事件监听器。
initApplicationEventMulticaster();

// Initialize other special beans in specific context subclasses.
// 执行其他的初始化操作,例如和SpringMVC整合时,需要初始化一些其他的bean,但是对于纯spring工程来说,onRefresh方法是一个空方法
onRefresh();

// Check for listener beans and register them.
// 这一步会将自定义的listener的bean名称放入到事件广播器中
// 同时还会将早期的ApplicationEvent发布(对于单独的spring工程来说,在此时不会有任何ApplicationEvent发布,但是和springMVC整合时,springMVC会执行onRefresh()方法,在这里会发布事件)
registerListeners();
// 实例化剩余的非懒加载的单例bean(注意:剩余、非懒加载、单例)
// 为什么说是剩余呢?如果开发人员自定义了BeanPosrProcessor,而BeanPostProcessor在前面已经实例化了,所以在这里不会再实例化,因此这里使用剩余一词
finishBeanFactoryInitialization(beanFactory);
// 结束refresh,主要干了一件事,就是发布一个事件ContextRefreshEvent,通知大家spring容器refresh结束了。
finishRefresh();
}
catch (BeansException ex) {
// 出异常后销毁bean
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// 在bean的实例化过程中,会缓存很多信息,例如bean的注解信息,但是当单例bean实例化完成后,这些缓存信息已经不会再使用了,所以可以释放这些内存资源了
resetCommonCaches();
}
}
}

总结

  1. 初始化容器环境变量和系统属性
  2. 初始化 BeanFactory ,并读取 xml 文件
  3. 设置 BeanFactoryPostProcessor 后置处理器
  4. 调用 BeanFactoryPostProcessor
  5. 注册 BeanPostProcessors
  6. 为上下文初始化 Message 源
  7. 初始化应用消息广播器
  8. 实例化剩余的非懒加载的单例 Bean
  9. 发布一个 ContextRefreshEvent 事件,通知容器 refresh 结束
  10. 释放资源

Spring IoC 容器核心组件

ApplicationContext 和ApplicationContext.XML

ApplicationContext是所有应用上下文的父接口,其也继承了BeanFactory的相关接口,简单来说也是一个Bean工厂,所以ApplicationContext中可以有一些列的Bean操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
String getId();

String getApplicationName();

String getDisplayName();

long getStartupDate();

ApplicationContext getParent();

AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
}

在使用Spring的时候,一般来说都会通过这个方式来实例化一个applicationContext

1
2
3
4
5
6
7
8
public class DaoOperationMain {

public static void main(String[] args) {

ApplicationContext appCtx = new ClassPathXmlApplicationContext("applicationContext.xml");

}
}

ApplicationContext应用上下文体系如下:

在实现类ClassPathXmlApplicationContext中其实并没有多少重要的操作,主要是在构造函数中配置Spring配置文件的路径:
具体的applicationContext.xml解析相关的操作都在父类refresh中进行操作。

1
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath*:applicationContext.xml");

BeanFactoryPostProcessor 和 BeanPostProcessor

BeanPostProcessor

BeanPostProcessor接口的作用是在Spring容器完成Bean实例化前后可以添加一些自己的逻辑处理,我们可以定义一个或者多个BeanPostProcessor接口的实现。

BeanPostProcessor接口提供了两个方法:

  1. postProcessBeforeInitialization 可以对Bean在实例化之前添加一些逻辑处理

  2. postProcessAfterInitialization 可以对bean在实例化之后添加一些逻辑处理

1
2
3
4
5
6
7
8
9
10

public interface BeanPostProcessor {

//可以对Bean在实例化之前添加一些逻辑处理
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;

//可以对bean在实例化之后添加一些逻辑处理
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;

}

简单示例MyBeanPostProcessor:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class MyBeanPostProcessor implements BeanPostProcessor {

//Bean 实例化之前进行的处理
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("对象" + beanName + "开始实例化");
return bean;
}

//Bean 实例化之后进行的处理
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("对象" + beanName + "实例化完成");
return bean;
}
}

在applicationContext.xml中添加配置

1
<bean class="com.spring.test.di.MyBeanPostProcessor"/>

BeanPostProcessor保存到Spring容器

这样MyBeanPostProcessor就会添加到Spring的容器中,在Spring容器中会将所有实现BeanPostProcessor的bean保存起来,具体实现在AbstractApplicationContext的registerBeanPostProcessors中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
//获取所有实现BeanPostProcessor的实现类
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);


int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
List<String> orderedPostProcessorNames = new ArrayList<String>();
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
for (String ppName : postProcessorNames) {
if (isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
//保存所有的BeanPostProcessor
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}

OrderComparator.sort(priorityOrderedPostProcessors);
//注册所有的BeanPostProcessor
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
OrderComparator.sort(orderedPostProcessors);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);

List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

OrderComparator.sort(internalPostProcessors);
registerBeanPostProcessors(beanFactory, internalPostProcessors);

beanFactory.addBeanPostProcessor(new ApplicationListenerDetector());
}
1
2
3
4
5
6
7
8
//在容器中添加BeanPostProcessor
private void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {

for (BeanPostProcessor postProcessor : postProcessors) {
beanFactory.addBeanPostProcessor(postProcessor);
}
}

执行所有的BeanPostProcessor

在Spring容器在初始化Bean前后都会执行所有的BeanPostProcessor的实现类提供的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {

Object result = existingBean;
//getBeanPostProcessors()获取所有的BeanPostProcessor的实现类
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
//执行BeanPostProcessor实现类的方法
result = beanProcessor.postProcessAfterInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}

BeanFactoryPostProcessor

和BeanPostProcessor原理一致,Spring提供了对BeanFactory进行操作的处理器BeanFactoryProcessor,简单来说就是获取容器BeanFactory,这样就可以在真正初始化bean之前对bean做一些处理操作。
BeanFactoryPostProcessor接口源码:

1
2
3
4
5
6
7

public interface BeanFactoryPostProcessor {

//获取beanFactory,这样在真正使用容器之前可以对一些bean做一些初始化操作
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}

简单示例:

1
2
3
4
5
6
7
8
9
10
11
12
13

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor{

@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
//获取BeanDefinition
GenericBeanDefinition rootBeanDefinition = (GenericBeanDefinition) beanFactory.getBeanDefinition("transaction");
//将bean设置出延迟初始化
rootBeanDefinition.setLazyInit(true);
System.err.println(rootBeanDefinition.getInitMethodName());
}

}

示例的功能是在bean初始化之前修改bean的属性配置。
接下来我们介绍一下BeanFactoryPostProcessor的初始化和调用机制。
(1)BeanFactoryPostProcessor和普通的bean一样注册到spring容器中。
(2)获取所有的BeanFactoryPostProcessor类型的类并初始化,添加到列表中
(3)在列表中循环执行所有的BeanFactoryPostProcessor实现类。

起始执行点在AbstractApplicationContext中,invokeBeanFactoryPostProcessors(beanFactory)执行是在初始化Bean实体方法finishBeanFactoryInitialization(beanFactory)之前,这样就可以在初始化bean之前可以对一些bean做一些额外的处理操作。

1
invokeBeanFactoryPostProcessors(beanFactory);

执行BeanFactoryPostProcessor所有的实现类

1
2
3
4
5
6
7
8
9
10
11
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
//执行BeanFactoryPostProcessor所有的实现类
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}

PostProcessorRegistrationDelegate类的invokeBeanFactoryPostProcessors方法中如下操作

获取所有BeanFactoryPostProcessor的子类

1
2
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

从Spring的容器中获取所有的BeanFactoryPostProcessor实现类,添加到priorityOrderedPostProcessors 中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
List<String> orderedPostProcessorNames = new ArrayList<String>();
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//从Spring的容器中获取所有的BeanFactoryPostProcessor实现类,添加到priorityOrderedPostProcessors 中
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}

执行所有的BeanFactoryPostProcessor的实现类

1
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

遍历执行所有的BeanFactoryPostProcessor的实现类

1
2
3
4
5
6
7
private static void invokeBeanFactoryPostProcessors(
Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {

for (BeanFactoryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanFactory(beanFactory);
}
}

BeanFactory 和 FactoryBean

Spring中有两种类型的Bean:一种是普通的JavaBean;另一种就是工厂Bean(FactoryBean),这两种Bean都受Spring的IoC容器管理,但它们之间却有一些区别。

FactoryBean

FactoryBean跟普通Bean不同,它是实现了FactoryBean接口的Bean,通过BeanFactory类的getBean方法直接获取到的并不是该FactoryBean的实例,而是该FactoryBean中方法getObject返回的对象。但我们可以通过其它途径获取到该FactoryBean的实例,方法就是在通过getBean方法获取实例时在参数name前面加上“&”符号即可。

FactoryBean接口提供的方法如下:

1
2
3
4
5
6
7
8
9

public interface FactoryBean<T> {
//获取FactoryBean初始化的Bean实例
T getObject() throws Exception;
//获取Bean实例的类型
Class<?> getObjectType();
//判断是否是单例模式
boolean isSingleton();
}

创建一个示例:MyFactoryBean

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

public class MyFactoryBean implements FactoryBean<Date>,BeanNameAware {
private String name;
@Override
public Date getObject() throws Exception {
return new Date();
}
@Override
public Class<?> getObjectType() {
return Date.class;
}
@Override
public boolean isSingleton() {
return false;
}
public void sayName() {
System.out.println("My name is " + this.name);
}
@Override
public void setBeanName(String name) {
this.name = name;
}
}

在Spring的配置文件ApplicationContext.xml中注入MyFactoryBean

1
<bean id ="myFactoryBean" class="com.xxxx.MyFactoryBean"></bean>

测试代码:

1
2
3
4
5
6
7
8
9
10
11
12

public class MainFactoryBean {

@SuppressWarnings("resource")
public static void main(String [] args){
ApplicationContext appCtx = new ClassPathXmlApplicationContext("applicationContext.xml");
Date now = (Date) appCtx.getBean("myFactoryBean");
System.out.println(now);
MyFactoryBean factoryBean = (MyFactoryBean) appCtx.getBean("&myFactoryBean");
factoryBean.sayName();
}
}

运行结果:通过myFactoryBean名称获取到的Bean是Date对象实例,通过&myFactoryBean获取到的是MyFactoryBean对象实例。

实现原理:

我们来看一下执行Date now = (Date) appCtx.getBean(“myFactoryBean”); 时会做的处理操作。

AbstractBeanFactory中会进行一系列的操作。

getBean获取bean

1
2
3
4
5

@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}

doGetBean中获取bean实例

1
2
3
4
5
6
7
8
9

protected <T> T doGetBean(
final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
.........//省略部分代码
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
.........//省略部分代码
return (T) bean;
}

getObjectForBeanInstance中会选择bean实例是普通的Bean还是FactoryBean,同时通过判断name中是否有&来选择判断是或者FactoryBean还是其getObject方法中获取的bean

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
.........//省略部分代码
//判断bean类型是否是FactoryBean,或者name是否是以&开头,如果是则直接返回
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
//如果是则从getObjectFromFactoryBean中获取
if (object == null) {
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}

getObjectFromFactoryBean接下来会执行FactoryBean的getObject方法获取bean了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
.........//省略部分代码
Object object = doGetObjectFromFactoryBean(factory, beanName);
.........//省略部分代码
return object;
}

private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
throws BeanCreationException {
Object object;
.........//省略部分代码
//调用Factory的getObject方法
object = factory.getObject();
.........//省略部分代码
return object;
}

总结:Spring对FactoryBean的实现机制是当你获取一个Bean时,如果获取的Bean的类型是FactoryBean,并且其name中并没有&则调用bean的getObject方法获取FactoryBean实现类中提供bean,否则就是直接返回普通的bean类型。

BeanFactory

BeanFactory及其子类是Spring IOC容器中最重要的一个类,BeanFactory由类名可以看出其是一个Bean工厂类,其实它确实是一个Bean工厂类,完成Bean的初始化操作。Bean的初始化操作还是一个比较麻烦的操作,首先根据spring注入配置将bean初始化为单例或者原型,其次需要根据Bean的属性配置来完成Bean参数的注入配置,还有要解决单例模式下Bean的循环依赖的问题,原型模式下bean的循环依赖会直接报错。

BeanFactory接口及其实现类:

BeanFactory接口继承关系:

BeanFactory 是Spring bean容器的根接口.提供获取bean,是否包含bean,是否单例与原型,获取bean类型,bean 别名的api.

  • AutowireCapableBeanFactory 添加集成其他框架功能.如果集成WebWork则可以使用Spring对Actions等进行管理.

  • HierarchicalBeanFactory 提供父容器的访问功能

  • ConfigurableBeanFactory 如名,提供factory的配置功能,眼花缭乱好多api

  • ConfigurableListableBeanFactory 集大成者,提供解析,修改bean定义,并与初始化单例.

  • ListableBeanFactory 提供容器内bean实例的枚举功能.这边不会考虑父容器内的实例.

BeanFactory提供的接口如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public interface BeanFactory {

String FACTORY_BEAN_PREFIX = "&";

//根据名称获取bean
Object getBean(String name) throws BeansException;

//根据名称及类型获取类
<T> T getBean(String name, Class<T> requiredType) throws BeansException;

//根据类型获取类
<T> T getBean(Class<T> requiredType) throws BeansException;

Object getBean(String name, Object... args) throws BeansException;

<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;

boolean containsBean(String name);

//单例判断
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
//原型判断
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
//类型判断
boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;

boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;

Class<?> getType(String name) throws NoSuchBeanDefinitionException;

String[] getAliases(String name);

}

BeanDefinition 和 BeanDefinitionHolder

BeanDefinition

BeanDefinition描述了一个bean实例,拥有属性值、构造参数值和具体实现的其他信息,其是一个bean的元数据,xml中配置的bean元素会被解析成BeanDefinition对象。

BeanDefinition的接口的结构类图:

  • ChildBeanDefinition

    ​ 可以让子Bean定义拥有从父母哪里继承配置的能力。相应的,子Bean定义有一个固定的依赖–他们的父bean定义。

    ​ 一个子bean定义将继承父母的构造参数值、属性值和方法覆盖并且可以选择的增加新的值。 如果初始化方法、销毁方法或者静态工厂方法已经指定了,那么将覆盖父bean定义中的相关配置。 子bean定义保留的配置将是:依赖、自动装配模式、依赖检查、单例和延迟加载。

==注意: 自从Spring 2.5之后, 编程的方式注册bean定义的优选方法是使用 GenericBeanDefinition类, 允许使用GenericBeanDefinition.setParentName方法动态的定义父依赖。 在大多数场景下可以 有效的取代ChildBeanDefinition类。==

  • GenericBeanDefinition

    ​ GenericBeanDefinition是一个定义标准的bean定义的一站式服务。

    ​ 像任何Bean定义,它允许指定一个类、可选的构造参数值和属性值。 除此之外可以通过配置”parentName”属性来灵活地指定从一个父Bean定义中派生。
    ​ 通常来说,使用GenericBeanDefinition类为了注册一个用户可见的bean定义(后置处理器可能会操作它, 甚至可能重新配置父母的名字)。如果父/子关系是预设的建议使用RootBeanDefinition / ChildBeanDefinition。

  • RootBeanDefinition

    ​ RootBeanDefinition描述了Spring BeanFactory运行时合并后的特定Bean定义。

    ​ 它可能来源于多个原始Bean定义(继承自其他的bean定义,通常被注册为GenericBeanDefinitions)。RootBeanDefinition从本质上将是运行时统一的Bean定义视图。
    ​ 在配置阶段,RootBeanDefinition也可能用于注册独立的bean定义。然而,自从Spring2.5依赖,编程地注册bean定义建议使用 GenericBeanDefinition类。GenericBeanDefinition在允许动态定义父依赖而不是硬编码作为RootBeanDefinition方面有优势。

在抽象类AbstractBeanDefinition中添加了更多和bean属性设置相关的处理操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
@SuppressWarnings("serial")
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
implements BeanDefinition, Cloneable {
public static final String SCOPE_DEFAULT = "";
public static final int AUTOWIRE_NO = AutowireCapableBeanFactory.AUTOWIRE_NO;
public static final int AUTOWIRE_BY_NAME = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME;
public static final int AUTOWIRE_BY_TYPE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE;
public static final int AUTOWIRE_CONSTRUCTOR = AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR;
@Deprecated
public static final int AUTOWIRE_AUTODETECT = AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT;
public static final int DEPENDENCY_CHECK_NONE = 0;
public static final int DEPENDENCY_CHECK_OBJECTS = 1;
public static final int DEPENDENCY_CHECK_SIMPLE = 2;
public static final int DEPENDENCY_CHECK_ALL = 3;
public static final String INFER_METHOD = "(inferred)";
private volatile Object beanClass;
private String scope = SCOPE_DEFAULT;
private boolean abstractFlag = false;
private boolean lazyInit = false;
private int autowireMode = AUTOWIRE_NO;
private int dependencyCheck = DEPENDENCY_CHECK_NONE;
private String[] dependsOn;
private boolean autowireCandidate = true;
private boolean primary = false;
private final Map<String, AutowireCandidateQualifier> qualifiers =
new LinkedHashMap<String, AutowireCandidateQualifier>(0);
private boolean nonPublicAccessAllowed = true;
private boolean lenientConstructorResolution = true;
private ConstructorArgumentValues constructorArgumentValues;
private MutablePropertyValues propertyValues;
private MethodOverrides methodOverrides = new MethodOverrides();
private String factoryBeanName;
private String factoryMethodName;
private String initMethodName;
private String destroyMethodName;
private boolean enforceInitMethod = true;
private boolean enforceDestroyMethod = true;
private boolean synthetic = false;
private int role = BeanDefinition.ROLE_APPLICATION;
private String description;
private Resource resource;

.........//属性处理代码
}

BeanDefinition源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {


String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
int ROLE_APPLICATION = 0;
int ROLE_SUPPORT = 1;
int ROLE_INFRASTRUCTURE = 2;
String getParentName();
void setParentName(String parentName);
String getBeanClassName();
void setBeanClassName(String beanClassName);
String getFactoryBeanName();
void setFactoryBeanName(String factoryBeanName);
String getFactoryMethodName();
void setFactoryMethodName(String factoryMethodName);
String getScope();
void setScope(String scope);
boolean isLazyInit();
void setLazyInit(boolean lazyInit);
String[] getDependsOn();
void setDependsOn(String... dependsOn);
boolean isAutowireCandidate();
void setAutowireCandidate(boolean autowireCandidate);
boolean isPrimary();
void setPrimary(boolean primary);
ConstructorArgumentValues getConstructorArgumentValues();
MutablePropertyValues getPropertyValues();
boolean isSingleton();
boolean isPrototype();
boolean isAbstract();
int getRole();
String getDescription();
String getResourceDescription();
BeanDefinition getOriginatingBeanDefinition();

}

BeanDefinitionHolder

BeanDefinitionHolder 就是一个 BeanDefinition 的持有者,其定义了一下变量,并对以下变量提供 get 和 set 操作。

1
2
3
4
5
private final BeanDefinition beanDefinition;

private final String beanName;

private final String[] aliases;

BeanDefinitionHolder 的源码中都是有关这几个变量的 get 和 set 操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
public class BeanDefinitionHolder implements BeanMetadataElement {

private final BeanDefinition beanDefinition;

private final String beanName;

private final String[] aliases;



public BeanDefinitionHolder(BeanDefinition beanDefinition, String beanName) {
this(beanDefinition, beanName, null);
}


public BeanDefinitionHolder(BeanDefinition beanDefinition, String beanName, String[] aliases) {
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
Assert.notNull(beanName, "Bean name must not be null");
this.beanDefinition = beanDefinition;
this.beanName = beanName;
this.aliases = aliases;
}


public BeanDefinitionHolder(BeanDefinitionHolder beanDefinitionHolder) {
Assert.notNull(beanDefinitionHolder, "BeanDefinitionHolder must not be null");
this.beanDefinition = beanDefinitionHolder.getBeanDefinition();
this.beanName = beanDefinitionHolder.getBeanName();
this.aliases = beanDefinitionHolder.getAliases();
}



public BeanDefinition getBeanDefinition() {
return this.beanDefinition;
}

public String getBeanName() {
return this.beanName;
}


public String[] getAliases() {
return this.aliases;
}


@Override
public Object getSource() {
return this.beanDefinition.getSource();
}


public boolean matchesName(String candidateName) {
return (candidateName != null && (candidateName.equals(this.beanName) ||
candidateName.equals(BeanFactoryUtils.transformedBeanName(this.beanName)) ||
ObjectUtils.containsElement(this.aliases, candidateName)));
}



public String getShortDescription() {
StringBuilder sb = new StringBuilder();
sb.append("Bean definition with name '").append(this.beanName).append("'");
if (this.aliases != null) {
sb.append(" and aliases [").append(StringUtils.arrayToCommaDelimitedString(this.aliases)).append("]");
}
return sb.toString();
}


public String getLongDescription() {
StringBuilder sb = new StringBuilder(getShortDescription());
sb.append(": ").append(this.beanDefinition);
return sb.toString();
}


@Override
public String toString() {
return getLongDescription();
}


@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof BeanDefinitionHolder)) {
return false;
}
BeanDefinitionHolder otherHolder = (BeanDefinitionHolder) other;
return this.beanDefinition.equals(otherHolder.beanDefinition) &&
this.beanName.equals(otherHolder.beanName) &&
ObjectUtils.nullSafeEquals(this.aliases, otherHolder.aliases);
}

@Override
public int hashCode() {
int hashCode = this.beanDefinition.hashCode();
hashCode = 29 * hashCode + this.beanName.hashCode();
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.aliases);
return hashCode;
}

}

Spring Bean 生命周期及循环引用

Bean 对象初始化

即使我们在不了解Spring对bean的初始化机制,我们也可以根据Java语言的特性猜测到其很有可能是通过反射机制来完成Bean的初始化操作,接下来我们一步一步的剖析Spring对Bean的初始化操作。

首先Spring会通过调用 getBean(String name)来获取Bean,在获取bean的过程中完成的Bean的初始化操作。

AbstractBeanFactory类中:

1
2
3
4
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}

在doGetBean方法中会判断bean的类型单例、原型,如果是单例则需要判断是否已经初始化bean并添加到缓存中,如果是原型bean则需要重新初始化bean,由于Spring对beanName提供了别名机制,所有需要通过beanName获取最终的bean名称。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
@SuppressWarnings("unchecked")
protected <T> T doGetBean(
final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {

//查找name是否有别名,获取最终的beanName
final String beanName = transformedBeanName(name);
Object bean;

//如果bean是单例模式,首先尝试从缓存中获取
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
//会判断bean是否是FactoryBean,如果不是直接返回sharedInstance,否则调用sharedInstance.getObject()方法返回bean
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}

else {
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
//判断容器是否有父容器,如果有则首先尝试从父容器中获取
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}

if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}

try {
//根据beanName获取bean的元数据
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);

// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
getBean(dep);
}
}

// bean是单例
if (mbd.isSingleton()) {
//获取bean,首先会暴露一个ObjectFactory,通过调用getObject来调用createBean(beanName, mbd, args)获取bean
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
try {
//
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
}
});
//会判断bean是否是FactoryBean,如果不是直接返回sharedInstance,否则调用sharedInstance.getObject()方法返回bean
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
//bean是原型
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
//初始化bean
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
//bean是其他模式
else {
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
//省略代码..........
return (T) bean;
}

接下来我们看看在createBean(String beanName, RootBeanDefinition mbd, Object[] args)中进行的处理操作,在createBean中会通过BeanDefinition中获取类名resolvedClass(反射机制重要的一个参数),并且会调用resolveBeforeInstantiation在bean初始的过程中做一些预处理(简单来说就是BeanPostProcessor的实现类所做的处理操作)。

AbstractAutowireCapableBeanFactory:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;

//获取类名,通过反射机制来实例化类
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
//设置类名
mbdToUse.setBeanClass(resolvedClass);
}

// Prepare method overrides.
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}

try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
//如果bean想要在初始化后使用之前做一些预处理操作
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
//初始化bean
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}

doCreateBean中完成的处理操作就比较多了,简单来说调用了几个方法完成了bean的初始化操作:
createBeanInstance完成通过构造函数初始化bean的操作;

addSingletonFactory完成将初始化的bean提前暴露出去,这样就解决了单例bean非构造函数的循环引用问题;

populateBean完成bean的属性注入操作,通过set方法或者注解注入属性;

initializeBean完成了bean注入时设置的init-method方法的执行,同时在执行init-method之前会调用applyBeanPostProcessorsBeforeInitialization完成bean使用前的处理操作,调用applyBeanPostProcessorsAfterInitialization完成bean初始化后的操作;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
//初始化bean实例
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}

//将初始化的bean提前暴露出去,暴露一个ObjectFactory,这也是Spring解决单例bean非构造函数依赖的解决方法
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}

// Initialize the bean instance.
Object exposedObject = bean;
try {
//初始化bean的各种注入或者setXX参数
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
//调用注入类的init-method方法
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}

//
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}

return exposedObject;
}

createBeanInstance中会通过bean的构造函数或者默认构造函数来完成bean的初始化工作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {

//省略代码.............

if (resolved) {
if (autowireNecessary) {
//通过构造函数初始化
return autowireConstructor(beanName, mbd, null, null);
}
else {
//使用默认构造函数初始化
return instantiateBean(beanName, mbd);
}
}

// Need to determine the constructor...
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}

// No special handling: simply use no-arg constructor.
return instantiateBean(beanName, mbd);
}

instantiateBean中会调用bean初始策略InstantiationStrategy的实现类完成bean的初始化操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
return getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
}, getAccessControlContext());
}
else {
//调用bean初始化策InstantiationStrategy略初始化bean
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}

调用InstantiationStrategy的instantiate方法完成初始化操作。

SimpleInstantiationStrategy(InstantiationStrategy实现类)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

@Override
public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
if (bd.getMethodOverrides().isEmpty()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
final Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor<?>>() {
@Override
public Constructor<?> run() throws Exception {
return clazz.getDeclaredConstructor((Class[]) null);
}
});
}
else {
constructorToUse = clazz.getDeclaredConstructor((Class[]) null);
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Throwable ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
//最终在BeanUtils中完成bean的初始化操作
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// Must generate CGLIB subclass.
return instantiateWithMethodInjection(bd, beanName, owner);
}
}

最终我们发现bean的初始化操作是在BeanUtils中完成的,通过反射机制完成Bean的初始化操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
Assert.notNull(ctor, "Constructor must not be null");
try {
ReflectionUtils.makeAccessible(ctor);
//通过反射机制初始化bean
return ctor.newInstance(args);
}
catch (InstantiationException ex) {
throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
}
catch (IllegalAccessException ex) {
throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
}
catch (IllegalArgumentException ex) {
throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
}
catch (InvocationTargetException ex) {
throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
}
}

Bean对象变量初始化

​ 对于Spring对属性值注入的方式,即使我们没有看Spring的实现方式可能也会猜到,对于通过set方法注入的变量值简单来说调用类的xx.xx.setXx(args ..)就完成了变量值的注入操作,对于通过注解@Autowired注入的对象,可以通过Java提供的反射机制通过获取Field对象来获取变量值,通过调用Field.set(Object obj, Object value)方法来完成变量的初始化工作,实际上Spring就是通过Java最基本的反射机制来完成变量值注入的(对于Java反射机制的了解参考Java反射机制)。

  首先在AbstractAutowireCapableBeanFactory的populateBean方法中首先会获取所有要注入的变量值设置,包括在xml中配置的property属性,通过@Autowired注释的变量以及提供了setXxx方法的变量值都会被收集为MutablePropertyValues对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
//获取要设置的属性值
PropertyValues pvs = mbd.getPropertyValues();

if (bw == null) {
if (!pvs.isEmpty()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
return;
}
}
boolean continueWithPropertyPopulation = true;

if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}

if (!continueWithPropertyPopulation) {
return;
}

if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

//通过名称来注入bean
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}

//通过类型来注入bean
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}

pvs = newPvs;
}

boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);

if (hasInstAwareBpps || needsDepCheck) {
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
//对MutablePropertyValues注入属性
applyPropertyValues(beanName, mbd, bw, pvs);
}

applyPropertyValues方法中要开始尝试对属性值做注入处理,但是在注入处理之前做一些预处理操作,简单来说对参数值做了深拷贝处理(具体问什么这么做还不知),接下来是调用BeanWrapper.setPropertyValues方法做参数值注入处理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
if (pvs == null || pvs.isEmpty()) {
return;
}

MutablePropertyValues mpvs = null;
List<PropertyValue> original;

if (System.getSecurityManager() != null) {
if (bw instanceof BeanWrapperImpl) {
((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
}
}

if (pvs instanceof MutablePropertyValues) {
mpvs = (MutablePropertyValues) pvs;
if (mpvs.isConverted()) {
// Shortcut: use the pre-converted values as-is.
try {
bw.setPropertyValues(mpvs);
return;
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
original = mpvs.getPropertyValueList();
}
else {
original = Arrays.asList(pvs.getPropertyValues());
}

TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

// Create a deep copy, resolving any references for values.
List<PropertyValue> deepCopy = new ArrayList<PropertyValue>(original.size());
boolean resolveNecessary = false;
for (PropertyValue pv : original) {
if (pv.isConverted()) {
deepCopy.add(pv);
}
else {
String propertyName = pv.getName();
Object originalValue = pv.getValue();
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
Object convertedValue = resolvedValue;
boolean convertible = bw.isWritableProperty(propertyName) &&
!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
if (convertible) {
convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
}
// Possibly store converted value in merged bean definition,
// in order to avoid re-conversion for every created bean instance.
if (resolvedValue == originalValue) {
if (convertible) {
pv.setConvertedValue(convertedValue);
}
deepCopy.add(pv);
}
else if (convertible && originalValue instanceof TypedStringValue &&
!((TypedStringValue) originalValue).isDynamic() &&
!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
pv.setConvertedValue(convertedValue);
deepCopy.add(pv);
}
else {
resolveNecessary = true;
deepCopy.add(new PropertyValue(pv, convertedValue));
}
}
}
if (mpvs != null && !resolveNecessary) {
mpvs.setConverted();
}

// Set our (possibly massaged) deep copy.
try {
//调用BeanWrapper的方法做参数值注入处理
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}

在BeanWrapper的setPropertyValues中会循环对每次属性值做注入处理操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Override
public void setPropertyValues(PropertyValues pvs) throws BeansException {
setPropertyValues(pvs, false, false);
}

@Override
public void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid)
throws BeansException {

List<PropertyAccessException> propertyAccessExceptions = null;
List<PropertyValue> propertyValues = (pvs instanceof MutablePropertyValues ?
((MutablePropertyValues) pvs).getPropertyValueList() : Arrays.asList(pvs.getPropertyValues()));
for (PropertyValue pv : propertyValues) {
try {
//给属性注入操作
setPropertyValue(pv);
}

}

}

注入的操作分两种,一种是对有setXxx方法的注入则直接调用BeanPropertyHandler的setValue方法通过反射调用Method.invoke实现注入操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
@Override
public void setValue(final Object object, Object valueToApply) throws Exception {
//通过使用setXxx方法进行注入
final Method writeMethod = (this.pd instanceof GenericTypeAwarePropertyDescriptor ?
((GenericTypeAwarePropertyDescriptor) this.pd).getWriteMethodForActualAccess() :
this.pd.getWriteMethod());
if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers()) && !writeMethod.isAccessible()) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
writeMethod.setAccessible(true);
return null;
}
});
}
else {
writeMethod.setAccessible(true);
}
}
final Object value = valueToApply;
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
@Override
public Object run() throws Exception {
writeMethod.invoke(object, value);
return null;
}
}, acc);
}
catch (PrivilegedActionException ex) {
throw ex.getException();
}
}
else {
writeMethod.invoke(getWrappedInstance(), value);
}
}
}

}

对于没有setXxx方法简单来说通过注解方法注释的属性则通过FieldPropertyHandler直接给属性赋值。

1
2
3
4
5
6
7
8
9
10
11
12
@Override
public void setValue(Object object, Object value) throws Exception {
try {
ReflectionUtils.makeAccessible(this.field);
//操作属性值进行注入
this.field.set(object, value);
}
catch (IllegalAccessException ex) {
throw new InvalidPropertyException(getWrappedClass(), this.field.getName(),
"Field is not accessible", ex);
}
}

总结:简单来说Spring对属性值的注入方法还是比较简单的,通过Java提供的反射机制,对于有setXxx方法的变量直接通过反射调用方法注入参数值;对于没有setXxx方法的变量则通过Field方法,直接对变量进行赋值操作。

Bean 的生命周期

img

Bean 对象循环依赖问题

循环依赖就是N个类相互嵌套引用,如果通过new对象的方式产生循环依赖的话会导致程序内存溢出报错,接下来我们了解一下spring是如何解决循环依赖问题。

第一种:prototype 原型 bean 循环依赖

对于原型bean的初始化过程中不论是通过构造器参数循环依赖还是通过setXxx方法产生循环依赖,Spring都会直接报错处理。
AbstractBeanFactory.doGetBean()方法:

1
2
3
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
1
2
3
4
5
protected boolean isPrototypeCurrentlyInCreation(String beanName) {
Object curVal = this.prototypesCurrentlyInCreation.get();
return (curVal != null &&
(curVal.equals(beanName) || (curVal instanceof Set && ((Set<?>) curVal).contains(beanName))));
}

在获取bean之前如果这个原型bean正在被创建则直接抛出异常。原型bean在创建之前会进行标记这个beanName正在被创建,等创建结束之后会删除标记

1
2
3
4
5
6
7
8
9
10
try {
//创建原型bean之前添加标记
beforePrototypeCreation(beanName);
//创建原型bean
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
//创建原型bean之后删除标记
afterPrototypeCreation(beanName);
}

==总结:Spring不支持原型bean的循环依赖。==

第二种:单例bean 构造器参数循环依赖

对于单例bean通过构造器参数进行循环依赖时,Spring也是通过抛出异常进行处理的,接下来我们分析一下其是如何实现。假设这里有两个类ClassA 和 ClassB,两个类通过构造器进行循环依赖。

  1. Spring创建ClassA时首先会调用beforeSingletonCreation(beanName),判断单例bean是否正在被创建,如果正在被创建则报错,如果没有被创建则做标记
1
2
3
4
5
6
protected void beforeSingletonCreation(String beanName) {
//singletonsCurrentlyInCreation是一个集合,不可重复,add返回true则表明没有创建,返回false则说明bean在创建
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}

此时刚开始创建ClassA,因此不会报异常错误,当初始化ClassA的构造器时需要用到ClassB的实例。

  1. Spring从容器中无法获取ClassB的实例,接下来Spring按照步骤1创建ClassB的实例,在构造ClassB的构造函数时需要用到ClassA的实例。
  2. Spring还是首先尝试从容器中获取ClassA的实例,由于第1步还没有执行结束,此时还没有ClassA实例,Spring容器认为就需要初始化ClassA了,重复第1步,但是ClassA一开始就已经进行了第1步,并且做标记bean正在创建,当再次进入第一步时就会抛出异常错误。

==总结:Spring在创建构造器循环依赖时其实就是循环初始化操作 A-> B -> A 当A要被初始化第二次时就直接抛出异常。==

第三种:单例bean通过setXxx或者@Autowired进行循环依赖

Spring通过setXxx或者@Autowired方法解决循环依赖其实是通过提前暴露一个ObjectFactory对象来完成的,简单来说ClassA在调用构造器完成对象初始化之后,在调用ClassA的setClassB方法之前就把ClassA实例化的对象通过ObjectFactory提前暴露到Spring容器中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
//将初始化后的对象提前已ObjectFactory对象注入到容器中
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}

总结:

  1. Spring容器初始化ClassA通过构造器初始化对象后提前暴露到Spring容器。
  2. ClassA调用setClassB方法,Spring首先尝试从容器中获取ClassB,此时ClassB不存在Spring容器中。
  3. Spring容器初始化ClassB,同时也会将ClassB提前暴露到Spring容器中
  4. ClassB调用setClassA方法,Spring从容器中获取ClassA ,因为第一步中已经提前暴露了ClassA,因此可以获取到ClassA实例
  5. ClassA通过spring容器获取到ClassB,完成了对象初始化操作。
  6. 这样ClassA和ClassB都完成了对象初始化操作,解决了循环依赖问题。

Spring AOP 面向切面

代理模式

  1. 静态代理

最简单的解决方案就是使用静态代理模式了,代理类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class GreetingProxy implements Greeting {
private GreetingImpl greetingImpl;
public GreetingProxy(GreetingImpl greetingImpl) {
this.greetingImpl = greetingImpl;
}
@Override
public void sayHello(String name) {
before();
greetingImpl.sayHello(name);
after();
}
private void before() {
System.out.println("Before");
}
private void after() {
System.out.println("After");
}
}

就用这个 GreetingProxy 去代理 GreetingImpl,下面看看客户端如何来调用:

1
2
3
4
5
6
7
8

public class Client {

public static void main(String[] args) {
Greeting greetingProxy = new GreetingProxy(new GreetingImpl());
greetingProxy.sayHello("Jack");
}
}
  1. 动态代理

    1. JDK动态代理
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    public class JDKDynamicProxy implements InvocationHandler {

    private Object target;

    public JDKDynamicProxy(Object target) {
    this.target = target;
    }

    @SuppressWarnings("unchecked")
    public <T> T getProxy() {
    return (T) Proxy.newProxyInstance(
    target.getClass().getClassLoader(),
    target.getClass().getInterfaces(),
    this
    );
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    before();
    Object result = method.invoke(target, args);
    after();
    return result;
    }

    private void before() {
    System.out.println("Before");
    }

    private void after() {
    System.out.println("After");
    }
    }

    客户端调用:

    1
    2
    3
    4
    5
    6
    7
    8

    public class Client {

    public static void main(String[] args) {
    Greeting greeting = new JDKDynamicProxy(new GreetingImpl()).getProxy();
    greeting.sayHello("Jack");
    }
    }

    ==JDK 给我们提供的动态代理只能代理接口,而不能代理没有接口的类==

    1. cglib动态代理
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    public class CGLibDynamicProxy implements MethodInterceptor {

    private static CGLibDynamicProxy instance = new CGLibDynamicProxy();

    private CGLibDynamicProxy() {
    }

    public static CGLibDynamicProxy getInstance() {
    return instance;
    }

    @SuppressWarnings("unchecked")
    public <T> T getProxy(Class<T> cls) {
    return (T) Enhancer.create(cls, this);
    }

    @Override
    public Object intercept(Object target, Method method, Object[] args, MethodProxy proxy) throws Throwable {
    before();
    Object result = proxy.invokeSuper(target, args);
    after();
    return result;
    }

    private void before() {
    System.out.println("Before");
    }

    private void after() {
    System.out.println("After");
    }
    }

    客户端调用:

    1
    2
    3
    4
    5
    6
    7
    8

    public class Client {

    public static void main(String[] args) {
    Greeting greeting = CGLibDynamicProxy.getInstance().getProxy(GreetingImpl.class);
    greeting.sayHello("Jack");
    }
    }

AOP 代理工厂 AopProxyFactory

Spring AOP提供了Aop代理类的工厂类AopProxyFactory,其作用就是创建AopProxy类。

1
2
3
4
5
6
7
//Aop工厂,创建AOP
public interface AopProxyFactory {

//创建AOP
AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException;

}

AopProxyFactory会创建两种代理类:

  1. jdk提供接口实现的JdkDynamicAopProxy

  2. cglib提供接口实现的ObjenesisCglibAopProxy

​ 在Spring配置文件中配置<aop:aspectj-autoproxy proxy-target-class=”true”/>时会默认创建ObjenesisCglibAopProxy,如果没有配置的话就需要根据被代理类是否有接口来选择判断了,如果被代理类由接口则选择使用JdkDynamicAopProxy,否则使用ObjenesisCglibAopProxy,这样选择的原因是由于jdk和cglib实现代理的机制不同来决定的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@SuppressWarnings("serial")
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {

//Spring提供了两种代理类创建方式jdk动态代理和cglib动态代理
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
//AopProxy创建是根据目标类是否有接口
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}

private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
Class<?>[] ifcs = config.getProxiedInterfaces();
return (ifcs.length == 0 || (ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0])));
}

}

AOP 代理 AopProxy

AopProxy是Spring Aop提供的代理类,简单来说通过其实现类可以获取到代理类。

AopProxy接口提供的方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public interface AopProxy {

/**
* Create a new proxy object.
* <p>Uses the AopProxy's default class loader (if necessary for proxy creation):
* usually, the thread context class loader.
* @return the new proxy object (never {@code null})
* @see Thread#getContextClassLoader()
*/
//获取一个代理对象
Object getProxy();

/**
* Create a new proxy object.
* <p>Uses the given class loader (if necessary for proxy creation).
* {@code null} will simply be passed down and thus lead to the low-level
* proxy facility's default, which is usually different from the default chosen
* by the AopProxy implementation's {@link #getProxy()} method.
* @param classLoader the class loader to create the proxy with
* (or {@code null} for the low-level proxy facility's default)
* @return the new proxy object (never {@code null})
*/
//根据类加载器获取代理对象
Object getProxy(ClassLoader classLoader);

}

AopProxy有两个实现类JdkDynamicAopProxy和CglibAopProxy,简单来说这两个代理类的功能就是生成目标代理类

Advice 通知

Advice通知,所谓通知指的就是指拦截到连接点之后要执行的代码,通知分为前置、后置、异常、最终、环绕通知五类

  1. BeforeAdvice、AfterAdvice:SpringAOP自定义的通知,用于拦截的方法之前或者之后,继承了AOP联盟的通知接口Advice。

  2. MethodBeforeAdvice、AfterReturningAdvice:仍然是SpringAOP自己的接口设计

    • MethodBeforeAdvice:继承了BeforeAdvice,但是BeforeAdvice只有这一个子类,即目前的SpringAOP只能实现对方法的拦截,不能实现对字段的拦截这种更精细的拦截,而Aspectj本身是支持这种拦截的。

      引入了接口方法: void before(Method method, Object[] args, Object target) throws Throwable;即在调用target的method方法之前我们可以做一些事情。

    • AfterReturningAdvice:继承了AfterAdvice,引入了接口方法: void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable;必然比上面的

      before方法多了一个返回值Object returnValue,使得我们可以对返回值进行操作和修改。

  3. AspectJMethodBeforeAdvice、AspectJAfterReturningAdvice、AspectJAfterThrowingAdvice、AspectJAfterAdvice、AspectJAroundAdvice:上面的接口设计好了,就需要来实现它,这几个类都是借助于Aspectj来完成上述的功能。

    • 前置通知:AspectJMethodBeforeAdvice

    • 后置通知:AspectJAfterAdvice

    • 异常通知:AspectJAfterThrowingAdvice

    • 最终通知:AspectJAfterReturningAdvice

    • 环绕通知:AspectJAroundAdvice

MethodInterceptor方法拦截器MethodInterceptor这一重要接口,所有的advice都要最终转化成MethodInterceptor,它的invoke接口方法包含了拦截器要执行的内容及执行的顺序。

MethodInterceptor:是AOP联盟定义的接口,引入重要方法Object invoke(MethodInvocation invocation) throws Throwable;MethodInvocation invocation则像由一个个MethodInterceptor组成的链条(后面会进行说明),每次执行MethodInterceptor的invoke方法实现一个拦截,同时要把链条给它,以便继续执行下一个MethodInterceptor。

对于advice构建成MethodInterceptor,分两种情况

  1. advice本身就实现了MethodInterceptor,如AspectJAfterAdvice、AspectJAfterThrowingAdvice、AspectJAroundAdvice。

  2. 那些没有实现MethodInterceptor的advice,如MethodBeforeAdvice、AfterReturningAdvice,则会进一步转换成MethodBeforeAdviceInterceptor、AfterReturningAdviceInterceptor。这一过程又是采用适配器模式,适配器模式还是很常见的,所以要学会然后好好利用,如下面所示:

AdvisorAdapter:Advisor适配器,用来创建MethodInterceptor。

AfterReturningAdviceAdapter用来生成AfterReturningAdviceInterceptor

1
2
3
4
5
@Override
public MethodInterceptor getInterceptor(Advisor advisor) {
AfterReturningAdvice advice = (AfterReturningAdvice) advisor.getAdvice();
return new AfterReturningAdviceInterceptor(advice);
}

MethodBeforeAdviceAdapter用来生成MethodBeforeAdviceInterceptor

1
2
3
4
5
@Override
public MethodInterceptor getInterceptor(Advisor advisor) {
MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();
return new MethodBeforeAdviceInterceptor(advice);
}

ThrowsAdviceAdapter用来生成ThrowsAdviceInterceptor

1
2
3
4
@Override
public MethodInterceptor getInterceptor(Advisor advisor) {
return new ThrowsAdviceInterceptor(advisor.getAdvice());
}

MethodInterceptor是如何实现拦截执行的

每次执行MethodInterceptor的invoke方法实现一个拦截,同时要把链条给它,以便继续执行下一个MethodInterceptor。

  1. AspectJAfterAdvice:在mi.proceed()之后执行
1
2
3
4
5
6
7
8
9
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
try {
return mi.proceed();
}
finally {//最后执行
invokeAdviceMethod(getJoinPointMatch(), null, null);
}
}
  1. AspectJAfterThrowingAdvice:在mi.proceed()之后执行异常
1
2
3
4
5
6
7
8
9
10
11
12
13
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
try {
return mi.proceed();
}
catch (Throwable ex) {
//出现异常后执行
if (shouldInvokeOnThrowing(ex)) {
invokeAdviceMethod(getJoinPointMatch(), null, ex);
}
throw ex;
}
}
  1. MethodBeforeAdviceInterceptor:在mi.proceed()之前执行
1
2
3
4
5
6

@Override
public Object invoke(MethodInvocation mi) throws Throwable {
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );//执行之前运行
return mi.proceed();
}
  1. AfterReturningAdviceInterceptor :在mr.proceed执行获取返回值之后进行执行
1
2
3
4
5
6
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
Object retVal = mi.proceed();//执行之后运行
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
return retVal;
}

Advisor 切面

Advisor接口及其实现类是Advice(通知)和PointCut(切入点)的一个组合体,按照aop的定义其就是一个Aspect切面。

Advisor及其实现类:

在接口Advisor中定义了获取Advice通知的方法

1
2
3
4
5
public interface Advisor {
//获取通知
Advice getAdvice();
boolean isPerInstance();
}

在PointcutAdvisor中定义了获取PointCut的方法

1
2
3
4
5
6
7

public interface PointcutAdvisor extends Advisor {

//获取切入点
Pointcut getPointcut();

}

简单来说Advisor的实现类就是一个包含了Advice(通知)和PointCut(切入点)的数据结构。

我们来分析一下Spring配置文件中配置aop的配置属性。

1
2
3
4
5
6
7
8
9

<aop:config>
<aop:aspect ref="transaction">
<aop:before method="startTransaction" pointcut="execution(* *.save(..))"/>
<aop:after method="commitTransaction" pointcut="execution(* *.save(..))"/>
<aop:after-throwing method="rollbackTransaction" pointcut="execution(* *.save(..))"/>
<aop:after-returning method="commitTransaction" pointcut="execution(* *.save(..))"/>
</aop:aspect>
</aop:config>

其中:

  1. <aop:aspect>代表一个切面Advisor集合

  2. ref=“transaction” 代表了一个通知的集合,里面可能会有多个通知方法

  3. pointcut 代表切入点的匹配表达式

  4. before、after等的method表示每个通知

  5. before加上method加上pointcut就可以作为一个Advisor切面

这样通过pointcut的匹配表达式,可以将Advice横切到目标类的方法中

PointCut 切入点

PointCut切入点简单来说就是用来指明Advice(增强)所作用的地方(一般指方法),PointCut简单来说是一个基于表达式的拦截条件。

PointCut接口及实现类:

PointCut接口提供了两个接口分别对类和方法进行匹配过滤,如果类及方法匹配成功则Advice就可以作用在方法上。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public interface Pointcut {

/**
* Return the ClassFilter for this pointcut.
* @return the ClassFilter (never {@code null})
*/
//通过pointcut表达式对类进行过滤
ClassFilter getClassFilter();

/**
* Return the MethodMatcher for this pointcut.
* @return the MethodMatcher (never {@code null})
*/
//通过pointcut表达式对方法进行过滤
MethodMatcher getMethodMatcher();


/**
* Canonical Pointcut instance that always matches.
*/
//匹配所有的类及方法,默认返回true
Pointcut TRUE = TruePointcut.INSTANCE;

}

在PointCut的子类AspectJExpressionPointcut中提供了两个方法对类和方法进行匹配判断,其最后的过滤的处理操作还是在aspectjweaver(aspectJ类库,AspectJ是一个专门用来实现动态代理(AOP编程)的类库,AspectJ是面向切面编程的框架,Spring使用就是这个类库实现动态代理的)这个jar中完成的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
//对类进行过滤匹配
@Override
public boolean matches(Class<?> targetClass) {
checkReadyToMatch();
try {
try {
return this.pointcutExpression.couldMatchJoinPointsInType(targetClass);
}
catch (ReflectionWorldException ex) {
logger.debug("PointcutExpression matching rejected target class - trying fallback expression", ex);
PointcutExpression fallbackExpression = getFallbackPointcutExpression(targetClass);
if (fallbackExpression != null) {
return fallbackExpression.couldMatchJoinPointsInType(targetClass);
}
}
}
catch (Throwable ex) {
logger.debug("PointcutExpression matching rejected target class", ex);
}
return false;
}

//对方法进行过滤匹配
@Override
public boolean matches(Method method, Class<?> targetClass, boolean beanHasIntroductions) {
checkReadyToMatch();
Method targetMethod = AopUtils.getMostSpecificMethod(method, targetClass);
ShadowMatch shadowMatch = getShadowMatch(targetMethod, method);
if (shadowMatch.alwaysMatches()) {
return true;
}
else if (shadowMatch.neverMatches()) {
return false;
}
else {
if (beanHasIntroductions) {
return true;
}
RuntimeTestWalker walker = getRuntimeTestWalker(shadowMatch);
return (!walker.testsSubtypeSensitiveVars() || walker.testTargetInstanceOfResidue(targetClass));
}
}

总结:PointCut接口及其实现类就是根据我们配置的类及方法的过滤规则在调用Advice之前进行过滤,看看是否需要调用Advice。

JoinPoint 连接点

JoinPoint连接点:程序执行过程中明确的点,简单的来说就是Java程序执行过程中的方法。

JoinPoint接口图:

JoinPoint通过抽象实现成为一个个的Method,在执行每个JoinPoint所代表的Method中,会执行对应的Advice。

JoinPoint接口提供的方法

1
2
3
4
5
6
7
8
9
public interface Joinpoint {

//在实现中完成Method及Advice的执行
Object proceed() throws Throwable;

Object getThis();

AccessibleObject getStaticPart();
}

在JoinPoint的实现类ReflectiveMethodInvocation中实现了方法proceed()。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@Override
public Object proceed() throws Throwable {
//interceptorsAndDynamicMethodMatchers所有同志的链表
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
//如果所有的advice都已经进行处理就可以递归执行方法了
return invokeJoinpoint();
}

//每次获取一个advice
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {

InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.

return proceed();
}
}
else {
//在调用的Advice的invoke方法时会递归调用proceed方法
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}

在interceptorsAndDynamicMethodMatchers中包含了需要切入某个方法所有的Advice通知,通过不断的递归调用完成所有的Advice和Method执行顺序的预处理。

1
2
3
4
5
6
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
//执行mi.proceed执行先执行BeforeAdvice
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
return mi.proceed();
}

当链表中所有的Advice通知都被处理执行开始执行invokeJoinpoint方法,来进行对目标方法的执行。

1
2
3
4
5
6
7
8
9
@Override
protected Object invokeJoinpoint() throws Throwable {
if (this.publicMethod) {
return this.methodProxy.invoke(this.target, this.arguments);
}
else {
return super.invokeJoinpoint();
}
}

AspectJ

  1. 基于注解:通过 AspectJ execution 表达式拦截方法

下面以一个最简单的例子,实现之前提到的环绕增强。先定义一个 Aspect 切面类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Aspect
@Component
public class GreetingAspect {

@Around("execution(* aop.demo.GreetingImpl.*(..))")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
before();
Object result = pjp.proceed();
after();
return result;
}

private void before() {
System.out.println("Before");
}

private void after() {
System.out.println("After");
}
}

注意:类上面标注的 @Aspect 注解,这表明该类是一个 Aspect(其实就是 Advisor)。该类无需实现任何的接口,只需定义一个方法(方法叫什么名字都无所谓),只需在方法上标注 @Around 注解,在注解中使用了 AspectJ 切点表达式。方法的参数中包括一个 ProceedingJoinPoint 对象,它在 AOP 中称为 Joinpoint(连接点),可以通过该对象获取方法的任何信息,例如:方法名、参数等。

重点来分析一下这个切点表达式:

execution(* aop.demo.GreetingImpl.*(..))

  • execution():表示拦截方法,括号中可定义需要匹配的规则。
  • 第一个“*”:表示方法的返回值是任意的。
  • 第二个“*”:表示匹配该类中所有的方法。
  • (..):表示方法的参数是任意的。
  1. 基于注解:通过 AspectJ @annotation 表达式拦截方法

为了拦截指定的注解的方法,我们首先需要来自定义一个注解:

1
2
3
4
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Tag {
}

以上定义了一个 @Tag 注解,此注解可标注在方法上,在运行时生效。

只需将前面的 Aspect 类的切点表达式稍作改动:

1
2
3
4
5
6
7
8
9
10
11
@Aspect
@Component
public class GreetingAspect {

@Around("@annotation(aop.demo.Tag)")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
...
}

...
}

这次使用了 @annotation() 表达式,只需在括号内定义需要拦截的注解名称即可。

直接将 @Tag 注解定义在您想要拦截的方法上,就这么简单:

1
2
3
4
5
6
7
8
9
@Component
public class GreetingImpl implements Greeting {

@Tag
@Override
public void sayHello(String name) {
System.out.println("Hello! " + name);
}
}

以上示例中只有一个方法,如果有多个方法,我们只想拦截其中某些时,这种解决方案会更加有价值。

除了 @Around 注解外,其实还有几个相关的注解,稍微归纳一下吧:

  • @Before:前置增强
  • @After:后置增强
  • @Around:环绕增强
  • @AfterThrowing:抛出增强
  • @DeclareParents:引入增强

此外还有一个 @AfterReturning(返回后增强),也可理解为 Finally 增强,相当于 finally 语句,它是在方法结束后执行的,也就说说,它比 @After 还要晚一些。

最后一个 @DeclareParents 竟然就是引入增强!为什么不叫做 @Introduction 呢?我也不知道为什么,但它干的活就是引入增强。

  1. 引入增强

为了实现基于 AspectJ 的引入增强,我们同样需要定义一个 Aspect 类:

1
2
3
4
5
6
7
@Aspect
@Component
public class GreetingAspect {

@DeclareParents(value = "aop.demo.GreetingImpl", defaultImpl = ApologyImpl.class)
private Apology apology;
}

只需要在 Aspect 类中定义一个需要引入增强的接口,它也就是运行时需要动态实现的接口。在这个接口上标注了 @DeclareParents 注解,该注解有两个属性:

  • value:目标类
  • defaultImpl:引入接口的默认实现类

我们只需要对引入的接口提供一个默认实现类即可完成引入增强:

1
2
3
4
5
6
7
public class ApologyImpl implements Apology {

@Override
public void saySorry(String name) {
System.out.println("Sorry! " + name);
}
}

Spring Transaction 事务

核心组件

Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource、TransactionManager和代理机制这三部分,无论哪种配置方式,一般变化的只是代理机制这部分。DataSource、TransactionManager这两部分只是会根据数据访问方式有所变化,比如使用hibernate进行数据访问时,DataSource实际为SessionFactory,TransactionManager的实现为HibernateTransactionManager。

事务管理原理

根据代理机制的不同,总结有五种事务配置方式

  • 每个 Bean 都有一个代理
  • 所有 Bean 共享一个代理基类
  • 使用拦截器
  • 使用 tx 标签配置的拦截器
  • 全注解

事务传播机制

key属性确定代理应该给哪个方法增加事务行为。这样的属性最重要的部份是传播行为。有以下选项可供使用:

  • PROPAGATION_REQUIRED–支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
  • PROPAGATION_SUPPORTS–支持当前事务,如果当前没有事务,就以非事务方式执行。
  • PROPAGATION_MANDATORY–支持当前事务,如果当前没有事务,就抛出异常。
  • PROPAGATION_REQUIRES_NEW–新建事务,如果当前存在事务,把当前事务挂起。
  • PROPAGATION_NOT_SUPPORTED–以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
  • PROPAGATION_NEVER–以非事务方式执行,如果当前存在事务,则抛出异常。

缓存

缓存管理原理

Spring MVC

Spring Event 和 Spring Listener