Spring 保姆级带你认识,让你如何轻松应对面试官
1.Spring是什么?作用是什么?
Spring是一个轻量级的JavaEE框架,它主要解决企业应用中的复杂性问题。Spring框架有三个核心部分:IoC容器、AOP和数据访问/集成层。Spring中的IoC容器提供了一种对象创建和对象之间关系管理的机制,以实现松散耦合和可扩展性。AOP提供了一种很好的方式来实现横向关注点的处理,如事务管理,安全检查,缓存等。数据访问/集成层则提供了许多针对不同数据持久化技术的实现,比如JDBC,ORM和NoSQL。
人话: spring是一个轻量级开源免费IOC和AOP的容器框架。IOC:控制反转,AOP:面向切面编程,主要是为了解决企业级应用开发的业务逻辑层和其他各层对象和对象直接的耦合问题,降低开发难度,提高开发效率。更好的继承各种框架如mysql,等只需要通过pom文件导入依赖即可一键继承所需的jar包
2.你对IoC(控制反转 Inversion of Control)是怎么理解的?
IoC是一种设计思想,通过将对象之间的依赖关系交给容器来管理,从而实现松散耦合。在Spring中,IoC容器扮演了一个中心角色,负责创建对象,装配对象之间的依赖关系,并管理它们的整个生命周期。IoC还提供了一些高级功能,如AOP和事件驱动等,可以进一步增强应用程序的可维护性和可扩展性。
人话:ioc就是控制反转最重要的就是最重要的就是容器。容器管理着 Bean 的生命周期,控制着 Bean 的依赖注入。通俗的说就是把new的过程交给容器来创建管理对象的生命周期。如果我想new一个对象使用过DI(依赖注入)@Autowired 自动注入 就可以使用对象。ioc的实现机制是工厂模式加反射
3.什么是AOP(面向切面编程 Aspect Oriented Programming)?
AOP是一种编程范式,它能够在程序运行期间动态地将代码切入到原有代码的流程中,从而实现横向关注点的处理,如日志记录、事务管理和安全检查等。在Spring中,AOP是通过代理模式来实现的,在创建Bean时为Bean生成一个代理对象,代理对象能够拦截指定方法的调用,并在执行前或执行后执行特定操作。
aop通常成为面向切面编程,就是把一些与业务无关的代码进行抽离封装起来,另外就是一些代码中大量重复的代码可以使用aop,达到重复复用的效果大大提高代码的可读性以及代码的健壮性,降低代码的耦合度。aop一般使用在权限认证,日志,事物处理等场景。
(1)切面(Aspect): 在Spring Aop指定就是“切面类” ,切面类会管理着切点、通知。
(2)连接点(Join point): 指定就是被增强的业务方法
(3)通知(Advice): 就是需要增加到业务方法中的公共代码, 通知有很多种类型分别可以在需要增加的业务方法
不同位置进行执行(前置通知、后置通知、异常通知、返回通知、环绕通知)
(4)切点(Pointcut): 由他决定哪些方法需要增强、哪些不需要增强, 结合切点表达式进行实现
(5)目标对象(Target Object): 指定是增强的对象
(6)织入(Weaving) : spring aop用的织入方式:动态代理。 就是为目标对象创建动态代理的过程就叫织入
4.Spring中Bean之间的依赖关系是怎样的?
在Spring中,Bean之间的依赖关系主要通过构造函数注入、Setter方法注入和自动注入来实现。构造函数注入是通过Bean的构造方法注入其他Bean作为参数来实现;Setter方法注入是通过Bean的Setter方法来注入其他Bean;自动注入则是通过IoC容器在Bean创建时自动发现并注入其他Bean,可以通过设置@Autowired或@Resource注解来完成。
人话:在Spring中,Bean之间的依赖关系可以通过构造函数注入和属性注入两种方式来实现。构造函数注入是指当一个Bean需要另一个Bean时,Spring会自动将依赖Bean的引用传递给另一个Bean的构造函数。这样,在创建Bean时就完成了依赖关系的注入。属性注入是指当一个Bean需要另一个Bean时,Spring会自动调用另一个Bean的Setter方法,并将依赖Bean的引用传递给该方法。这样,在创建Bean后再完成依赖关系的注入。
5.Spring框架中的单例模式是怎样实现的?
在Spring中,默认情况下,所有的Bean都是单例的。当IoC容器创建一个Bean时,它会缓存该Bean的实例,并在后续请求中返回相同的实例。这种机制可以提高应用程序的性能并减少内存消耗,但也需要注意线程安全和状态管理等问题。
回答这个问题直接回答完成后接着说,如何保证bean的线程安全最简单的方式就是改变 bean 的作用域,把“singleton”变更为“prototype”,这样请求 bean 相当于 new Bean()了,所以就可以保证线程安全了。其次只有bean是有状态的时候才是线程不安全的,在前面的文章中我有重点说过,有兴趣的可以看看。
6.Spring中的事务管理是如何实现的?
Spring通过AOP在运行时动态地将事务相关的逻辑切入到指定的方法中,从而实现事务管理。通常情况下,Spring使用声明式事务管理来管理事务。开发者可以通过@Transactional注解或XML配置文件来定义事务范围、传播属性以及回滚规则等。
7.Spring的优势是什么?
Spring 框架具有许多优势,其中包括:
轻量级:Spring 框架是轻量级的,不需要依赖过多的第三方库,使得应用程序更加高效。
松耦合:Spring 的依赖注入(DI)和面向接口的编程模型(AOP)等特性,可以帮助实现松耦合,提高代码的灵活性和可维护性。
依赖注入:Spring 框架支持依赖注入,通过配置文件或注解的方式管理对象之间的依赖关系,降低了组件之间的耦合度,提高了代码的可测试性。
面向切面编程:Spring 框架支持面向切面编程(AOP),可以方便地实现日志记录、事务管理、安全控制等横切关注点,提高了代码的模块化程度。
容器化管理:Spring 框架提供了 IoC 容器,可以管理对象的生命周期和配置,简化了对象的创建和管理。
丰富的功能模块:Spring 框架提供了丰富的功能模块,包括数据访问、事务管理、消息队列、安全认证等,能够满足各种企业级应用的开发需求。
宽泛的整合性:Spring 框架对各种开发框架和技术都有很好的整合能力,能够与其他框架(如 Hibernate、MyBatis、Struts、JPA 等)很好地配合使用。
社区支持:Spring 框架拥有庞大的社区支持和活跃的开发者社区,可以获取到丰富的学习资源和问题解决方案。
总的来说,Spring 框架在企业级应用开发中具有很强的实用性和灵活性,能够帮助开发人员快速构建可靠的应用程序。
8.解释一下Spring中的BeanFactory和ApplicationContext有什么区别。
BeanFactory是Spring IoC容器的最基本形式,提供了基本的IoC功能。它是延迟初始化的,即当一个Bean被实际使用时才被创建。ApplicationContext是BeanFactory的子接口,提供了更多的企业级功能,如AOP,事件驱动,国际化等。ApplicationContext也是预初始化的,即在容器启动时就已经创建了所有的Bean。
BeanFactory和ApplicationContext都是Spring框架中用来管理bean的容器,但它们之间有一些区别。
BeanFactory是Spring框架最基本的容器接口,它提供了最基本的IOC容器的功能,负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。它使用延迟加载机制,只有当客户端向容器索取一个bean时,容器才真正实例化该bean。ApplicationContext接口继承自BeanFactory接口,它除了提供了BeanFactory的所有功能外,还额外提供了更多面向企业级应用的功能,比如事件传播、国际化信息、资源加载、应用层特定的上下文等。而且ApplicationContext在启动时就会将所有的bean进行实例化,因此启动时间可能会比较长,但在后续获取bean时会更加快速。简单来说,BeanFactory提供了基本的IOC容器功能,而ApplicationContext在此基础上增加了更多的企业级功能,但相对来说启动时花费的时间更多。
9.Spring中的注解有哪些?
Spring中的常用注解有:
Spring框架中有很多常用的注解,以下是一些常见的注解:
@Component
:用于标识一个类为Spring容器管理的组件,通常与@Autowired
配合使用来进行依赖注入。@Autowired
:用于自动装配Bean,可以在字段、构造函数、Setter方法上使用,Spring会自动寻找匹配的Bean进行注入。@Controller
、@Service
、@Repository
:分别用于标识控制器、服务、数据访问层的Bean,通常用于更细粒度的组件分类。@Configuration
:用于标识配置类,通常与@Bean
一起使用,用于替代传统的XML配置。@RequestMapping
:用于映射HTTP请求到处理方法,可用于类和方法上,指定URL与处理方法的映射关系。@Value
:用于注入属性值,可以用在字段、方法参数、构造函数参数上。@Transactional
:用于标识事务管理相关的方法或类,使其具有事务管理的能力。@Aspect
、@Before
、@After
、@Around
:用于实现切面编程,提供对方法执行前、后、环绕等时机的处理。
这些注解大大简化了Spring应用的开发和配置工作,提高了代码的可读性和可维护性。