Spring面试

Spring面试(整理中)

IOC 容器

1什么是IOC容器,以及IOC容器的创建过程?

IOC通过控制反转的方式【通过依赖注入的方式】,创建并管理bean【初始化,装配,销毁】,使得代码的耦合度降低

IOC容器的创建分为两个步骤: 1️⃣ 加载元数据注册BeanDifinition 2️⃣ 遍历BeanDifinition ,创建Bean

元数据BeanDifinition : 包含需要创建bean所有配置信息,包括构造函数参数、属性值和特定于容器的信息,例如初始化方法、静态工厂方法名称等 相当于工厂的模具,IOC工厂将会根据Beandifinition来创建不同的对象服务于程序员

2 Bean创建详细的过程
3 IOC 实现的机制

简单工厂模式+反射

4 IOC和DI的区别

IOC ,控制反转,反转创建对象的权利,降低耦合度,是一种设计理念。是通过DI【依赖注入】的方式实现的

5 IOC加载的过程

IOC 加载的时候涉及到Bean的四种形态:概念态,定义态,纯净态,成熟态
1️⃣ IOC加载的开始是从Spring上下文的创建开始,根据不同的Spring上下文,注解 AnnotationConfigApplicationContext,XML:ClassPathXmlApplicationContext,java配置类:中包含了注册bean的相关信息,当前属于Bean的概念态。 2️⃣初始化Spring上下文后,会根据bean的元数据,调用BeanFactory的后置处理器方法将其注册为BeanDifinition,成为Bean的定义态。多个BeanDifinition存入BeanDifinitionMap中,便于后续Bean的生产 3️⃣ 遍历扫描BeanDifinitionMap,判断是否满足成产条件【是否单例Bean,是否懒加载,是否为抽象】,满足时调用getBean方法,通过反射或工厂Bean的形式,实例化Bean对象,此时为Bean的纯净态 4️⃣ DI,属性注入,或完成BeanFactory的后置处理器方法,为Bean增加附加功能,称为完整的Bean,放入单例池中

6 SpringIOC的拓展点,什么时候调用

Bean

1 JavaBean和SpringBean的区别

JavaBean:由程序员自己实例化的对象称为JavaBean
SpringBean: 交由SpringIOC容器管理的对象称为Spring对象

2 配置JavaBean的方式

1:基于XML配置
2:基于注解@Component(@Controller @Service @Repostory)
3:JavaConfig @Bean
基于注解与基于JavaConfig的区别:基于注解时底层是通过反射构造函数生成对象,控制权限交给了Spring框架,基于Java配置类则是 将方法返回的对象称为一个Bean,可由程序员定义Bean的信息

3 SpringBean的作用域

AOP

1 什么是AOP?与OOP的关系?

AOP【面向切面编程】,将那些与业务无关,但对多个对象产生影响的公共行为和逻辑,如权限认证,日志,事务等,抽取并封装成为一个可重用的模块,这个模块被成为切面【Aspect】。可以降低模块间的耦合度,同时提高系统的可维护性能。
与OOP都属于设计思想,OOP关注的类,从上至下 , AOP关注点是切面,从左至右

2 AOP概念介绍

AOP

  • 连接点:可以被增强的方法
  • 切入点:实际被增强的方法
  • 通知:需要增强的逻辑,根据通知的执行的顺序不同可分为不同的通知
  • 切面:切入点和通知的整合。
3 通知的类型

前通知:在连接点之前运行的通知,但没有能力阻止执行流继续到连接点(除非它抛出异常)。

返回后通知:在连接点正常完成后运行的通知(例如,如果方法返回而没有抛出异常)。

抛出通知后:如果方法通过抛出异常退出,则运行通知。

After (finally) 通知:不管连接点退出的方式(正常或异常返回)都将运行的通知。

环绕通知:环绕连接点的通知,环绕通知可以在方法调用前后执行自定义行为。它还负责选择是继续连接点还是通过返回自己的返回值或抛出异常来缩短建议的方法执行。

4 AOP 实现的机制

JDK动态代理或CGLIB动态代理

5 JDK动态代理或CGLIB动态代理的区别
  1. JDK动态代理
    只提供接口的代理,会在运行时,生成动态代理类,实现接口中所有方法增强代码。调用时用代理类进行增强,然后通过反射的方式调用目标方法
  2. CGLIB动态代理
    没有实现接口,底层通过ASM在运行时动态的生成目标类的一个子类,同时生成多个其他相关的类【为提高cglib动态代理调用的效率】。重写父类的所有子类进行增强。调用代理类时,通过调用父类的方法进行方法的增强
    因为CGLIB是通过继承父类的方式实现动态代理,意味着父类标记了final的方法无法增强实现逻辑
6JavaConfig如何开启AOP?

配置上标注 @EnableAspectJAutoProxy,可以基于注解模式来使用AOP

7 AOP內部調用失效的原因?如何解决?

在同一个类中 ,调用使用注解方式的AOP功能的方法,目标方法的注解则会失效,即无法实现预期的功能控制,例如事务、权限等。

失效的原因:
AOP实际上是通过代理的对象来实现方法,而非实际的目标对象或者操作实例对象。 但是在类内部的方法中,调用同一个类中定义的方法,则调用的是当前的对象,而不是代理对象,则注解失效,AOP功能失效
解决方法:
重新获得代理对象,通过代理对象来调用方法

  1. 暴露当前代理对象到本地线程,从AopContext 获取本地线程中存储的代理对象 ,AopContenxt.Current
  2. 开启方式为@EnableAspectJAutoProxy(exposeProxy = true)
8 AOP是在哪里创建的动态代理?

1:Bean初始化时,通过BeanPostProcesser.postProcessAfterInitialization()方法,创建动态代理类

//创建动态代理的实现类:AbstractAutoProxyCreator
//关键方法
	@Override
	public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
		if (bean != null) {
			Object cacheKey = getCacheKey(bean.getClass(), beanName);
			if (this.earlyProxyReferences.remove(cacheKey) != bean) {
			   
				return wrapIfNecessary(bean, beanName, cacheKey);
			}
		}
		return bean;
	}

    /**
	 * 有需求时,创建动态代理
	 * @param bean 原生bean
	 * @param beanName bean名称
	 * @param cacheKey 元数据的缓存可以
	 * @return a proxy wrapping the bean, or the raw bean instance as-is
	 */
	protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
		if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
			return bean;
		}
		if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
			return bean;
		}
		if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
			this.advisedBeans.put(cacheKey, Boolean.FALSE);
			return bean;
		}

		// 根据当前bean找到匹配的advice
		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
		if (specificInterceptors != DO_NOT_PROXY) {
			this.advisedBeans.put(cacheKey, Boolean.TRUE);
			//创建代理对象
			Object proxy = createProxy(
					bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
	        //存入缓存				
			this.proxyTypes.put(cacheKey, proxy.getClass());
			//返回代理对象
			return proxy;
		}

		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	}

在这里插入代码片

Spring 事务

事务的四大特性:(ACID)
  • 原子性: 一个事务应该被视为单个操作单元表示的操作的任一整个序列是成功的或不成功的。
  • 一致性: 这代表了数据库的参照完整性,在桌等唯一主键的一致性
  • 隔离性: 可能有很多事务处理相同的数据集的同时,每个事务都应由他人隔离,以防止数据损坏。
  • 持久性: 一旦事务完成,本次事务的结果必须作出永久性的,不能从数据库中删除因系统故障。
Spring事务支持的方式

1:申明式事务 【基于注解形式,XML配置的形式实现】

2:编程式事务 【硬编码形式实现】

Spring事务的传播行为

SpringMVC

1 什么是MVC
  • M Model 模型层,JavaBean,包含业务bean和实体类
  • V View 视图层 ,作用是与用户进行交互,展示数据,包含Html,jsp等页面
  • C Controller 控制层 ,工程中的servlet ,用于接收请求,响应数据

流程:用户通过视图层发送请求到服务器,在服务器中请求被Controller接收,Controller调用响应的Model层处理请求,将结果返回到Controller,再根据处理的结果找到响应的View视图,渲染数据后最终响应个浏览器

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值