本帖最后由 二十二道灰 于 2017-9-21 14:58 编辑
SPRING的BEAN的创建
用面向对象的方式理解spring
我们大家从第一天学spring的时候,都被灌输了这么一个理念,spring是一个面向切面的编程框架。但是我学到现在了,我觉得这个spring其实并不是面向切面的这么一个开发手段,我更偏向于叫他是一个面向对象,或者说是面向bean的开发框架。我给大家稍微解释一下我为什么这样想。 file://F:\自己写的笔记\技术演讲\img\5.png?lastModify=1505976452 这是我们第一天学spring的时候我们从spring官网上看到的这么一个图。当时我们什么都不知道,并不知道下边的三个组件在spring中的具体是什么位置,然后我们第一天学了Spring中的bean注入,是对bean的操作。 第二天学习的是ioc和aop,ioc就不用说了,是bean之间的关系,aop呢,是增强。那么增强,我觉得可以用这么一种逻辑来解释。我们都知道aop是动态代理的这么一种方式体现的。分别是jdk的动态代理和cglib的动态代理两种表现形式。这个增强的过程呢,是在整个java代码在运行的时候当他走到我们要增强的地方的时候,不走以前的逻辑,走我们自己增强的逻辑。那么我们是不是可以说这个框架其实还是在操纵bean? 第三天学习的是spring的JDBC模板和事务。我认为哈,jdbc已经不是spring的主要任务了,事务的增强又是aop的一种体现。那么我说了这么多,总结一下,我认为spring这个框架从框架自己的角度看,并不代表大多数哈,这个框架实际上是一个面向对象的框架。 Spring中三大部件的关系: 我们用spring的关键入口时什么?就是bean。使用Spring可以让我们不再new对象,将这个工作交给beanfactory,然后我们在对对象进行操作的时候,spring帮我们映射这个,映射那个(这个操作我认为就是生成代理对象AOP的重要部分),而这个乱七八糟的做什么,就是spring核心包做的事情,而这里也就解释了很多人之前的一个问题,为什么在声明对象的时候一定要用接口去接收。 那么我们做一个比喻,如果我们把一个java程序比作是一场演出的话,那么bean就是这场演出的演员context是承载演出的舞台背景,core就是演出的必要道具。这三个元素是不可分割的。 bean的创建过程 我们都知道Spring是用了工厂模式给我们创建对象,底层是实现getobject接口,那么这三个是如何联系在一起的?接下来我带大家稍微看一点源码来看一下bean的生产过程: 首先我们要带着目的,要看什么的源码,我之前说了,bean是这些程序的入口,并且bean的包下大多都实现了beanfactory这样一个东西,我们先进来看一下,看到的是这是一个总接口,有很多方法,但是当我们打开他的实现类的时候,发现太多了,那么接下来我给大家介绍他下边的三个大接口: HierarchicalBeanFactory:分等级的bean工厂 AutowireCapableBeanFactory:这个接口是装配那些不在xml中的bean。具体的方法我没有去看,但是这个跟我们目前所学的差的有点大,所以我没有深究,如果有兴趣的同学可以看一下。 ListableBeanFactory:表示可列表化的。我们就找这个 在这个下边我们找的第一个抽象类,是abstractApplicationContext。点进去之后,搜索init(初始化)这样一个词语,然后,我们看到了结束工厂初始化这样一行。我们都知道,java在运行的时候是按照我们从上往下的这么一个线性的顺序执行的,那么我们是不是可以说在这一行之前,他一定做了些什么,然后对工厂进行了设置:
public void refresh() throws BeansException, IllegalStateException {
Object arg0 = this.startupShutdownMonitor;
synchronized(this.startupShutdownMonitor) {
this.prepareRefresh();
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
//创建beanfactory
this.prepareBeanFactory(beanFactory);
try {
//注册实现了BeanFactoryPostProcessors的接口类
this.postProcessBeanFactory(beanFactory);
//初始化和执行BeanFactoryPostProcessors
this.invokeBeanFactoryPostProcessors(beanFactory);
//初始化和执行BeanPostProcessors
this.registerBeanPostProcessors(beanFactory);
//初始化MessageSource
this.initMessageSource();
//初始化ApplicationEventMulticaster
this.initApplicationEventMulticaster();
//重新刷新他的子类实现的方法
this.onRefresh();
//监听事件
this.registerListeners();
//beanFactory的初始化
this.finishBeanFactoryInitialization(beanFactory);
//事件
this.finishRefresh();
} catch (BeansException arg8) {
......
} finally {
this.resetCommonCaches();
}
}
}那么当我们看到这里,就大概知道我们要看什么了,点进去那个beanfactory之后,是如下代码:
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
if(beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) {
beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class));
}
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
String[] arg2 = weaverAwareNames;
int arg3 = weaverAwareNames.length;
for(int arg4 = 0; arg4 < arg3; ++arg4) {
String weaverAwareName = arg2[arg4];
this.getBean(weaverAwareName);
}
beanFactory.setTempClassLoader((ClassLoader)null);
beanFactory.freezeConfiguration();
//实例化bean
beanFactory.preInstantiateSingletons();
}preInstantiateSingletons 预处理一个单例 当我们点进去的时候,很不好意思,进了接口,那么第一件事就去找他的下一层,很荣幸,我们又找到了他的方法。因为太长,我就不贴出来了,大家自己去看。 然后我们再来看代码:
public void preInstantiateSingletons() throws BeansException {
if(this.logger.isDebugEnabled()) {
this.logger.debug("Pre-instantiating singletons in " + this);
}
ArrayList beanNames = new ArrayList(this.beanDefinitionNames);
Iterator arg1 = beanNames.iterator();
while(true) {
while(true) {
String beanName;
RootBeanDefinition singletonInstance;
do {
do {
do {
if(!arg1.hasNext()) {
arg1 = beanNames.iterator();
while(arg1.hasNext()) {
beanName = (String)arg1.next();
Object singletonInstance1 = this.getSingleton(beanName);
if(singletonInstance1 instanceof SmartInitializingSingleton) {
SmartInitializingSingleton smartSingleton1 = (SmartInitializingSingleton)singletonInstance1;
if(System.getSecurityManager() != null) {
AccessController.doPrivileged(new 3(this, smartSingleton1), this.getAccessControlContext());
} else {
smartSingleton1.afterSingletonsInstantiated();
}
}
}
return;
}
beanName = (String)arg1.next();
singletonInstance = this.getMergedLocalBeanDefinition(beanName);
} while(singletonInstance.isAbstract());
} while(!singletonInstance.isSingleton());
} while(singletonInstance.isLazyInit());
if(this.isFactoryBean(beanName)) {
FactoryBean smartSingleton = (FactoryBean)this.getBean("&" + beanName);
boolean isEagerInit;
if(System.getSecurityManager() != null && smartSingleton instanceof SmartFactoryBean) {
isEagerInit = ((Boolean)AccessController.doPrivileged(new 2(this, smartSingleton), this.getAccessControlContext())).booleanValue();
} else {
isEagerInit = smartSingleton instanceof SmartFactoryBean && ((SmartFactoryBean)smartSingleton).isEagerInit();
}
if(isEagerInit) {
this.getBean(beanName);
}
} else {
this.getBean(beanName);
}
}
}
}这里有一个特殊的bean,就是FactoryBean,点进去之后,发现他是一个接口: 那么我们知道了,如果是我们平常的时候,如果要产生一个实例对象,只要继承这个接口,然后调用他的getobject方法就行了。 原理我们都听老师讲过,但是自己从源码中找到整个的源码,流程还是很开心的。给大家分享一下,希望大家也能从中学到一些知识。
|