高频面试题springIOC 的生命周期,springAOP的机制实现过程

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,要带着问题去看,我们就是去找什么时候创建的代理,目的明确了,那我们开始找


指定断点停留值
spring源码产生代理对象的过程

1,

进入的第一个方法只看红色标志的一步一步往里看

2,

进入的第二个方法只看红色标志的一步一步往里看重点在这个getBean

3,

进入的第二个方法只看红色标志的一步一步往里看重点在这创建bean

3,

进入的第三个方法只看红色标志的一步一步往里看docreatbean

4,

进入的第四个方法只看红色标志的一步一步往里看代理类就是在这一步里面生成的

5,

进入第5个方法

进入后置处理器初始化方法

这个时候开始获取代理类了

找到了代理类jdk 和cglib,因为我们用的接口所以用的jdk 的代理

这个过程说的时候可以说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,

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容