Spring2021面试题总结

Spring面试题总结

一、Spring是什么?

Spring是一个轻量级Java开发框架,目的是为了解决企业级应用开发的业务逻辑层和其他各层的耦合问题。解决企业级应用开发的复杂性,简化Java开发。

二、Spring有哪些模块

1.Spring Core

框架的最基础部分,提供 IoC 容器,对 bean 进行管理,它主要的组件就是BeanFactory, 是工厂模式的实现。

2.Spring Context

继承BeanFactory,提供上下文信息,扩展出JNDI、EJB、电子邮件、国际化等功能。

3.Spring DAO

提供了JDBC的抽象层,还提供了声明性事务管理方法。

4.Spring ORM

提供了JPA、JDO、Hibernate、MyBatis 等ORM映射层。

5.Spring AOP

集成了所有AOP功能。减弱代码的功能耦合,清晰的被分离开。

6.Spring Web

提供了基础的 Web 开发的上下文信息,现有的Web框架,如JSF、Tapestry、Structs等,提供了集成。

7.Spring Web MVC

提供了 Web 应用的 Model-View-Controller 全功能实现。

三、Spring用到哪些设计模式

1.工厂模式:

BeanFactory就是简单工厂模式的体现,用来创建对象的实例;

2.单例模式:

Bean默认采用单例方式,减少了对象的创建,从而减少了内存的消耗。

3.代理模式:

Spring的AOP功能用到了JAVA的动态代理和Cglib动态代理。
区别:
          java动态代理:解决代码重复、混杂、以及代码重复问题。基于接口实现,无法实现非接口方法。
          Cglib动态代理:代理者是被代理者的子类。优点:解决代码重复、混杂,由于是基于继承实现,可实现非接口方法。缺点:需要导包,相对java代理性能较低。

静态代理与动态代理区别在于生成AOP代理对象的时机不同,相对来说AspectJ的静态代理方式具有更好的性能,但是AspectJ需要特定的编译器进行处理,而Spring
AOP则无需特定的编译器处理。

4.模板方法:

用来解决代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate。

5.观察者模式:

定义对象键一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知被制动更新,如Spring中listener的实现–ApplicationListener。

四、简述Spring IOC、DI

控制反转
将对象的创建的权利及对象的生命周期的管理过程交由Spring框架来处理
从此在开发过程中不再需要关注对象的创建和生命周期的管理
在需要时由Spring框架提供
这个由spring框架管理对象创建和生命周期的机制称之为控制反转
在创建对象的过程中Spring可以依据配置对对象的属性进行设置,这个过称之为依赖注入,也即DI

五、DI注入方式

构造器注入和Setter方法注入
用构造器参数实现强制依赖,setter方法实现可选依赖
注解注入

六、Spring的自动装配

根据要设置的javabean属性的名字或类型到spring中自动寻找对应id或类型的bean进行设置,从而省去依次配置的过程,简化了配置。

<!--
    自动装配机制 - autowire:
        byName:
            对于自定义bean类型的属性,根据bean的属性名寻找同名id的bean进行注入
            没不到 - 不进行注入
            找到唯一的 - 注入
            找到多个 - 不可能找到多个,因为不可以存在多个同id的bean
        byType:
            对于自定义bean类型的属性,根据bean属性的类型寻找对应类型的bean进行注入
            没找到 - 不注入
            找到唯一的 - 注入
            找到多个 - 抛出异常 UnsatisfiedDependencyException
        推荐使用byName方式
-->
<bean id="hero" class="cn.com.domain.Hero" autowire="byType">
    <property name="name" value="亚瑟"/>
    <property name="age" value="55"/>
</bean>

七、简述Spring IOC实现原理

在初始化一个Spring容器时,Spring会去解析指定的xml文件,当解析到其中的标签时,会根据该标签中的class属性指定的类的全路径名,通过反射创建该类的对象,并将该对象存入内置的Map中管理。其中键就是该标签的id值,值就是该对象。
之后,当通过getBean方法来从容器中获取对象时,其实就是根据传入的条件在内置的Map中寻找是否有匹配的键值,如果有则将该键值对中保存的对象返回,如果没有匹配到则抛出异常。

八、Spring创建对象的方式

a.通过类的无参构造方法创建对象
	在Spring容器初始化时,通过<bean>上配置的class属性反射得到字节码对象,通过newInstance()创建对象
	Class c = Class .forName("类的全路径名称")
	Object obj = c.newInstance()
	这种方式下spring创建对象,要求类必须有无参的构造,否则无法通过反射创建对象,会抛出异常
b.通过指定构造器创建对象 
	通过配置bean的<constructor-arg>参数,实现控制spring容器通过指定构造器创建对象
c.通过工厂创建对象 
	通过静态工厂创建对象 
		bean标签里配置factory-method="getInstance"
		加载配置文件时发现配置了静态工厂,调用静态工厂类的指定静态方法创建对象
		NetConn conn = NetConnStaticFactory.getInstance();
		将创建出来的对象存入Spring内部Map
		map.put("netConn",conn);
	实例工厂创建对象 
		factory-bean
		factory-method
	Spring工厂创建对象
		Spring内置了工厂接口FactoryBean,也可以通过实现这个接口来开发Spring工厂

九、bean生命周期

单例模式下
	bean在单例模式下,spring容器启动时解析xml发现该bean标签后,直接创建该bean的对象
	存入内部map中保存,此后无论调用多少次getBean()获取该bean都是从map中获取该对象返
	回,一直是一个对象。此对象一直被Spring容器持有,直到容器退出时,随着容器的退出对
	象被移除出容器。
多例模式下
	bean在多例模式下,spring容器启动时解析xml发现该bean标签后,只是将该bean进行管
	理,并不会创建对象,此后每次使用 getBean()获取该bean时,spring都会重新创建该对
	象返回,每次都是一个新的对象。这个对象spring容器并不会持有,什么时候销毁取决于
	用户程序本身。

十、懒加载机制

bean非常多时,spring需要在启动的过程中花费大量的时间来创建bean 花费大量的空间存储bean可以规定指定的bean不在启动时立即创建,而是在后续第一次用到时才创建,从而减轻在启动过程中对时间和内存的消耗
懒加载的配置方式
为指定bean配置懒加载

<bean id="cart" class="cn..beans.Cart" lazy-init="true"></bean>

为全局配置懒加载

<beans ……default-lazy-init="true">

如果同时设定全局和指定bean的懒加载机制,且配置不相同,则对于该bean局部配置覆盖全局配置。

十、Spring常用注解

1.声明bean的注解

@Component("ter")
/**
 * 默认类名首字母小写---teacher
 * 这里可以修改id的名字
 * <bean id="ter" class="cn.com.domain.Teacher"/>
 */
public class Teacher {
}

@Controller 标注控制层组件

@Service 标注业务层组件

@Respostory 标注数据访问组件

@Component 通用注解

2.注入Bean的注解

@Autowired 按类型注入,注入的属性必须提供set方法
@Resource 按名称注入,属于J2EE范畴,不属于Spring框架
配合使用,强制要求按照id寻找bean
配置类的相关注解

3. 配置类的相关注解

@Configuration
注解在类上,声明当前类为配置类,相当于xml中标签

@Bean
注解在方法上,声明当前方法的返回值是一个由Spring管理的Bean,在类spring加载的时 候就会创建该Bean,相当于xml中bean标签中配置的单个bean对象
其他注解

4.其他注解

a.@Scope(value="prototype") 
	配置修饰的类的bean是单例还是多例,如果不配置默认为单例
b.@Lazy 
	配置修饰的类的bean采用懒加载机制
c.@PostConstruct 
	在bean对应的类中 修饰某个方法 将该方法声明为初始化方法,对象创建之后立即执行
d.@PreDestroy 
	在bean对应的类中 修饰某个方法 将该方法声明为销毁的方法,对象销毁之前调用的方法

十一、Spring的AOP理解

面向切面,用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块,这个模块被命名为“切面”(Aspect)。
减少系统中的重复代码,降低了模块间的耦合度,提高系统的可维护性。可用于权限认证、日志、事务处理等。
AOP实现的关键在于代理模式,AOP代理主要分为静态代理和动态代理。静态代理的代表为AspectJ;动态代理JAVA动态代理和Cglib动态代理。

          (1)AspectJ是静态代理,AOP框架会在编译阶段生成AOP代理类,并将AspectJ(切面)织入到Java字节码中,运行的时候就是增强之后的AOP对象。
          (2)SpringAOP动态代理,所谓的动态代理就是说AOP框架不会去修改字节码,而是每次运行时在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。

十二、Spring的AOP理解

Spring aop中的基本概念

连接点(Joinpoint): 层与层之间方法的调用过程称之为连接点
切入点(Pointcut):需要增强的连接点
连接点+切入点表达式:切面(Aspect) 配置切面
通知(Advice):在spring底层的代理拦截下切入点后,将切入点交给切面类,切面类中就要有处理这些切入点的方法,这些方法就称之为通知
目标对象(Target Object):切面所通知的对象,被代理对象 织入 把功能逻辑加入到原有的业务逻辑

十二、五大通知类型

a.前置通知

	在目标方法执行之前执行执行的通知
	前置通知方法,可以没有参数,也可以额外接收一个JoinPoint,Spring会自动将该对象传入,代表当前的连接点,通过该对象可以获取目标对象 和 目标方法相关的信息
	如果接收JoinPoint,必须保证其为方法的第一个参数

b.环绕通知

	在目标方法执行之前和之后都可以执行额外代码的通知
	在环绕通知中必须显式的调用目标方法,否则目标方法不会执行
	在环绕通知中接收一个ProceedingJoinPoint类型的参数,是JoinPoint的子类
	环绕通知需要返回返回值,否则真正调用者将拿不到返回值,只能得到一个null

c.后置通知

	在目标方成功执行之后执行的通知
	在后置通知中也可以选择性的接收一个JoinPoint来获取连接点的额外信息,但是这个参数必须处在参数列表的第一个,非必须
	在后置通知中,还可以通过配置获取目标方法的返回值

d.异常通知

	在目标方法抛出异常时执行的通知
	可以配置传入JoinPoint获取目标对象和目标方法相关信息
	但必须处在参数列表第一位
	另外,还可以配置参数,让异常通知接收到目标方法抛出的异常对象

e.最终通知

	是在目标方法执行之后执行的通知
	和后置通知不同之处在于,后置通知是在方法正常返回后执行的通知,如果方法没有正常返-例如抛出异常,则后置通知不会执行
	而最终通知无论如何都会在目标方法调用过后执行,即使目标方法没有正常的执行完成
	后置通知可以通过配置得到返回值,而最终通知无法得到

五大通知类型执行顺序

	i.在目标方法没有抛出异常的情况下
		前置通知、环绕前通知的调用目标方法之前的代码,他们的顺序取决于配置顺序
		以目标方法为节点
			前置,环绕前在目标方法前执行
			后置,环绕后在目标方法之后执行
	ii.在目标方法抛出异常的情况下
	iii.如果存在多个切面

五大通知的常见使用场景

	前置通知
		记录日志(方法将被调用)
	环绕通知
		控制事务 权限控制
	后置通知
		记录日志(方法已经成功调用)
	异常通知
		异常处理 控制事务
	最终通知
		记录日志(方法已经调用,但不一定成功)

十三、SpringAOP原理

Spring自动为目标对象生成代理对象,默认情况下,如果目标对象实现过接口,则采用java的动态代理机制,如果目标对象没有实现过接口,则采用cglib动态代理。
可以在spring中进行配置,要求无论目标对象是否实现过接口,都强制使用cglib动态代理。

  • 9
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值