当前位置:   article > 正文

网易有道面试问题,高频面试题,java面试基础问题_网易面试题

网易面试题

private void populateBean(String beanName, GPBeanDefinition beanDefinition, GPBeanWrapper beanWrapper) {

try {

//ioc.get(beanName) 相当于通过接口的全名拿到接口的实现的实例

field.set(instance,getBean(autowiredBeanName));

} catch (IllegalAccessException e) {

e.printStackTrace();

continue;

}

}

4 循环依赖对AOP创建代理对象的影响


4.1 循环依赖下的代理对象创建过程

我们都知道Spring AOP、事务等都是通过代理对象来实现的,而事务的代理对象是由自动代理创建器来自动完成的。也就是说Spring最终给我们放进容器里面的是一个代理对象,而非原始对象。

这里我们结合循环依赖,再分析一下AOP代理对象的创建过程和最终放进容器内的动作,看如下代码:

@Service

public class MyServiceImpl implements MyService {

@Autowired

private MyService myService;

@Transactional

@Override

public Object hello(Integer id) {

return “service hello”;

}

}

此Service类使用到了事务,所以最终会生成一个JDK动态代理对象Proxy。刚好它又存在自己引用自己的循环依赖的情况。跟进到Spring创建Bean的源码部分,来看doCreateBean()方法:

protected Object doCreateBean( … ){

// 如果允许循环依赖,此处会添加一个ObjectFactory到三级缓存里面,以备创建对象并且提前暴露引用

// 此处Tips:getEarlyBeanReference是后置处理器SmartInstantiationAwareBeanPostProcessor的一个方法,

// 主要是保证自己被循环依赖的时候,即使被别的Bean @Autowire进去的也是代理对象

// AOP自动代理创建器此方法里会创建的代理对象

// Eagerly cache singletons to be able to resolve circular references

// even when triggered by lifecycle interfaces like BeanFactoryAware.

boolean earlySingletonExposure = (mbd.isSingleton() &&

this.allowCircularReferences &&

isSingletonCurrentlyInCreation(beanName));

if (earlySingletonExposure) { // 需要提前暴露(支持循环依赖),注册一个ObjectFactory到三级缓存

addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));

}

// 如果发现自己被循环依赖,会执行上面的getEarlyBeanReference()方法,从而创建一个代理对象从三级缓存转移到二级缓存里

// 注意此时候对象还在二级缓存里,并没有在一级缓存。并且此时可以知道exposedObject仍旧是原始对象 populateBean(beanName, mbd, instanceWrapper);

exposedObject = initializeBean(beanName, exposedObject, mbd);

// 经过这两大步后,exposedObject还是原始对象

// 注意:此处是以事务的AOP为例

// 因为事务的AOP自动代理创建器在getEarlyBeanReference()创建代理后,

// initializeBean() 就不会再重复创建了,二选一,下面会有详细描述)

// 循环依赖校验(非常重要)

if (earlySingletonExposure) {

// 前面讲到因为自己被循环依赖了,所以此时候代理对象还存放在二级缓存中

// 因此,此处getSingleton(),就会把代理对象拿出来

// 然后赋值给exposedObject对象并返回,最终被addSingleton()添加进一级缓存中

// 这样就保证了我们容器里缓存的对象实际上是代理对象,而非原始对象

Object earlySingletonReference = getSingleton(beanName, false);

if (earlySingletonReference != null) {

// 这个判断不可少(因为initializeBean()方法中给exposedObject对象重新赋过值,否则就是是两个不同的对象实例)

if (exposedObject == bean) {

exposedObject = earlySingletonReference;

}

}

}

}

以上代码分析的是代理对象有自己存在循环依赖的情况,Spring用三级缓存很巧妙的进行解决了这个问题。

4.2 非循环依赖下的代理对象创建过程

如果自己并不存在循环依赖的情况,Spring的处理过程就稍微不同,继续跟进源码:

protected Object doCreateBean( … ) {

addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));

// 此处注意,因为没有循环引用,所以上面getEarlyBeanReference()方法不会执行

// 也就是说此时二级缓存里并不会存在

populateBean(beanName, mbd, instanceWrapper);

// 重点在此

//AnnotationAwareAspectJAutoProxyCreator自动代理创建器此处的postProcessAfterInitialization()方法里,会给创建一个代理对象返回

// 所以此部分执行完成后,exposedObject() 容器中缓存的已经是代理对象,不再是原始对象

// 此时二级缓存里依旧无它,更别提一级缓存了

exposedObject = initializeBean(beanName, exposedObject, mbd);

// 循环依赖校验

if (earlySingletonExposure) {

// 前面讲到一级、二级缓存里都没有缓存,然后这里传参数是false,表示不从三级缓存中取值

// 因此,此时earlySingletonReference = null ,并直接返回

// 然后执行addSingleton()方法,由此可知,容器里最终存在的也还是代理对象

Object earlySingletonReference = getSingleton(beanName, false);

if (earlySingletonReference != null) {

if (exposedObject == bean) {

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
img

总结

至此,文章终于到了尾声。总结一下,我们谈论了简历制作过程中需要注意的以下三个部分,并分别给出了一些建议:

  1. 技术能力:先写岗位所需能力,再写加分能力,不要写无关能力;
  2. 项目经历:只写明星项目,描述遵循 STAR 法则;
  3. 简历印象:简历遵循三大原则:清晰,简短,必要,要有的放矢,不要海投;

以及最后为大家准备的福利时间:简历模板+Java面试题+热门技术系列教程视频

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算

能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!**](https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0)

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/818684
推荐阅读
相关标签
  

闽ICP备14008679号