1,springIOC的实现过程
1,资源定位,找到对应的(xml)的位置
2,将资源信息加载到BeanDefines的子类中,并不创建bean实例。
3,注册BeanDefines到BeanFactory,这时候也可能还不创建Bean实例。
4,将将Beandefines子类对象放入map ,判断是否为懒加载,如果非懒加载,则创建单例bean,并将所需要的对象进行依赖注入,若是懒加载,则在完成第三步的时候就进行实例话并进行依赖注入。
AOP 有两种
1,springAop
2,AspectJ
1,SpringAOP 创建过程说明
说明:spring aop依赖于springioc容器,在spring初始化的时候会创建bean的对象,下面这个refresh()spring的初始化方法想必大家都不陌生,spring 初始化的所有过程都在这个方法里面,几乎95%的面试题都在这里面
public void refresh()throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();//一些参数的初始化,非必要不需要重点看,就是启动时间那些东西的设置
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();//这个就是定位资源文件位置,将资源信息取出放入BeanDefines 的实现类里面,同时生成工厂BeanFactory,存放所有的spring信息
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);//这个也没必要看,就是往工厂里面设置一些必要的信息包括环境信息等
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);//bean工厂的后置处理器创建,后置处理器一般都是增强的功能,面试的时候如果说你可以对spring源码进行改动增常,一般都是通过后置处理器去修改传入的参数,也就是类实现了后置处理器的接口,然后重新设置变量
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);//此时进行了初始化bean,创建了bean,并出现了代理类,也就是在这个方法中生成了bean对象,然后判断如果有aop的增强则生成对象的代理类,放入singleObjets,singleObjects对象是currentHashmap类型的。
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);//bean的信息注册
// Initialize message source for this context.
initMessageSource();//初始化语言国际话等,非主要
// Initialize event multicaster for this context.
initApplicationEventMulticaster();//广播信息,非主要
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();//注册监听器
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);//这个方法很重要之前一步将bean放入singleObjets中,并没有对对象进行实例化,此时,判断是否为单例和懒加载的,若是则进行实例化,原型实例化是在getbean方法的时候。
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
源码也看了个整体,那么怎么给面试官说呢 ?
先给出一个动态代理的例子,基于接口的也就是jdk的动态代理
重点就是说 这个源码里的一切行动,在做源码调试的时候大家一定要懂得调试技巧,要不然你调试一个方法没走完就不想看了。这里假设你代理的对象为userServiceImpl,spring在进行debug的时候会对自己内部其他的类也进行一系列操作,需要打断点的时候制定beanname,要带着问题去看,我们就是去找什么时候创建的代理,目的明确了,那我们开始找
1,
2,
3,
3,
4,
5,
这个过程说的时候可以说springioc在初始化的时候首先创建目标targetobject,然后在后置处理器初始化的时候判断是否增常bean(aop),如果配置aop的功能,那么调用proxyfactory获取jdk 或者cglib的动态代理类,这个就是代理类的生成过程,最后放入singleObjects 中,以currenthashmap的形式,然后进行实例化,关键是要说出singleObjects这个对象,储存的是我们的beanDefines的实现类对象。后面都是从这里面取的。
2,Aspectj(spirng5.4开始支持的)
后补说明
spring刚开始是借助Aspectj的语法风格,
aop是什么?
答:与oop对比,面向切面,传说中的oop开发中的代码逻辑是自上而下的,而这些过程会产生一些横切问题,这些核切性的问题和我们的业务逻辑关系不大,这些横切行问题不会影响主逻辑,但是会影响到代码的各个部分,难以维护,aop是处理一切横切性问题,aop的变成思想就是把这些问题和主业务逻辑分开,达到与主业务逻辑解偶的目的,使代码的重用性和开发效率更高,
aop的应用场景?
1,日记记录
2,权限验证
3,效率检查
4,事物验证
对于aop的相关概念:
1,aspect:join point,Pointcut,Advice所在的逻辑
2,join point(连接点):就是横切中的一个方法
3,,Pointcut:链接点的的集合
4,Advice:增强的过程叫织入以及增强逻辑出现的位置
5,targetobject:目标对象
2,proxyobject:代理对象
在spring 初始化的时候就产生了代理对象,在doGetBean()方法中的
Object sharedInstance = getSingleton(beanName);
完成了代理对象的获取。
singletonObjects 是一个currentHashmap,这里里面存入了我们所有的spring 的单例bean,