java面试必备--框架篇--Spring(一)

        相信很多同行小伙伴会因为许多原因想跳槽,不论是干得不开心还是想跳槽涨薪,在如此内卷的行业,我们都面临着“面试造火箭,上班拧螺丝”的局面,鉴于当前形势博主呕心沥血整理的干货满满的造火箭的技巧来了,本博主花费2个月时间,整理归纳java全生态知识体系常见面试题!总字数高达百万! 干货满满,每天更新,关注我,不迷路,用强大的归纳总结,全新全细致的讲解来留住各位猿友的关注,希望能够帮助各位猿友在应付面试笔试上!当然如有归纳总结错误之处请各位指出修正!如有侵权请联系博主QQ1062141499!

---------------------------------------------------------------------------------------------------------------------------------

目录

1 谈谈你对Spring的理解

2 为什么要使用spring框架?

3 什么是IOC?

4 什么是AOP?

5 AOP使用场景

6 Advice通知类型介绍

8 AspectJ,SpringAOP,cglib,动态代理究竟有啥区别

9  理解Spring么,它的AOP实现是基于什么原理,bean的初始化过程是哪些?在beanFactory初始化前、运行中、初始化后想做些事情。该怎么做?

10 AOP与OOP的区别

11  面向切面的基本原理

12 Spring AOP和AspectJ区别

13 Spring有哪些主要模块?

14 Spring常用的注入方式有哪些?

15 spring中的bean是线程安全的吗?


1 谈谈你对Spring的理解

     Spring是一个开源框架,为简化企业级应用开发而生。Spring可以是使简单的JavaBean实现以前只有EJB才能实现的功能。Spring是一个IOC和AOP容器框架。

Spring容器的主要核心是:

      控制反转(IOC),传统的java开发模式中,当需要一个对象时,我们会自己使用new或者getInstance等直接或者间接调用构造方法创建一个对象。而在spring开发模式中,spring容器使用了工厂模式为我们创建了所需要的对象,不需要我们自己创建了,直接调用spring提供的对象就可以了,这是控制反转的思想。

      依赖注入(DI),spring使用javaBean对象的set方法或者带参数的构造方法为我们在创建所需对象时将其属性自动设置所需要的值的过程,就是依赖注入的思想。

      面向切面编程(AOP),在面向对象编程(oop)思想中,我们将事物纵向抽成一个个的对象。而在面向切面编程中,我们将一个个的对象某些类似的方面横向抽成一个切面,对这个切面进行一些如权限控制、事物管理,记录日志等公用操作处理的过程就是面向切面编程的思想。AOP底层是动态代理,如果是接口采用JDK动态代理,如果是类采用CGLIB方式实现动态代理。

2 为什么要使用spring框架?

     spring 是一个开源的轻量级 JavaBean 容器框架。使用 JavaBean 代替 EJB ,并提供了丰富的企业应用功能,降低应用开发的复杂性。

  1. 轻量:非入侵性的、所依赖的东西少、资源占用少、部署简单,不同功能选择不同的 jar 组合
  2. 容器:工厂模式实现对 JavaBean 进行管理,通过控制反转(IOC)将应用程序的配置和依赖性与应用代码分开
  3. 松耦合:通过 xml 配置或注解即可完成 bean 的依赖注入
  4. AOP:通过 xml 配置 或注解即可加入面向切面编程的能力,完成切面功能,如:日志,事务...的统一处理
  5. 方便集成:通过配置和简单的对象注入即可集成其他框架,如 Mybatis、Hibernate、Shiro...
  6. 丰富的功能:JDBC 层抽象、事务管理、MVC、Java Mail、任务调度、JMX、JMS、JNDI、EJB、动态语言、远程访问、Web Service...

3 什么是IOC?

      IOC,Inversion of Control(控制反转)。

      是一种设计思想,在Java开发中,将你设计好的对象交给容器控制,而不是显示地用代码进行对象的创建。把创建和查找依赖对象的控制权交给 IOC 容器,由 IOC 容器进行注入、组合对象。这样对象与对象之间是松耦合、便于测试、功能可复用(减少对象的创建和内存消耗),使得程序的整个体系结构可维护性、灵活性、扩展性变高。

使用 IOC 的好处:

  1. 资源集中管理,实现资源的可配置和易管理
  2. 降低了资源的依赖程度,即松耦合
  3. 便于测试
  4. 功能可复用(减少对象的创建和内存消耗)
  5. 使得程序的整个体系结构可维护性、灵活性、扩展性变高

     DI(Dependency Injection)依赖注入,是 IOC 容器装配、注入对象的一种方式。通过依赖注入机制,简单的配置即可注入需要的资源,完成自身的业务逻辑,不需要关心资源的出处和具体实现。

spring 提供了三种主要的方式来配置 IOC 容器中的 bean

  1. 基于 XML 文件配置
  2. 基于注解配置
  3. 基于注解 + java 代码显式配置

4 什么是AOP?

      AOP:Aspect Oriented Programming,面向切面编程。通过预编译和运行期动态代理实现程序功能的统一维护。在 Spring 框架中,AOP 是一个很重要的功能。

      AOP 利用一种称为横切的技术,剖开对象的封装,并将影响多个类的公共行为封装到一个可重用模块,组成一个切面,即 Aspect 。"切面"就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合度,利于可操作性和可维护性。

实现 AOP 的方式,主要有两大类:

  1. 采用动态代理技术,利用拦截方法的方式,对该方法进行装饰,以取代原有对象行为的执行;
  2. 采用静态织入的方式,引入特定的语法创建"切面",从而使得编译器可以在编译期间织入有关"切面"的代码。

AOP 相关概念切面(Aspect)、连接点(Join point)、通知(Advice)、切点(Pointcut)、引入(Introduction)、目标对象(Target Object)、AOP代理(AOP Proxy)、织入(Weaving)

spring 框架中可以通过 xml 配置和注解去使用 AOP 功能。

AOP的相关概念:

  1. 横切关注点:对哪些方法进行拦截,拦截后怎么处理,这些关注点称之为横切关注点
  2. Aspect(切面):通常是一个类,里面可以定义切入点和通知
  3. JointPoint(连接点):程序执行过程中明确的点,一般是方法的调用。被拦截到的点,因为Spring只支持方法类型的连接点,所以在Spring中连接点指的就是被拦截到的方法,实际上连接点还可以是字段或者构造器
  4. Advice(通知):AOP在特定的切入点上执行的增强处理,有before(前置),after(后置),afterReturning(最终),afterThrowing(异常),around(环绕)
  5. Pointcut(切入点):就是带有通知的连接点,在程序中主要体现为书写切入点表达式
  6. weave(织入):将切面应用到目标对象并导致代理对象创建的过程
  7. introduction(引入):在不修改代码的前提下,引入可以在运行期为类动态地添加一些方法或字段
  8. AOP代理(AOP Proxy):AOP框架创建的对象,代理就是目标对象的加强。Spring中的AOP代理可以使JDK动态代理,也可以是CGLIB代理,前者基于接口,后者基于子类
  9. 目标对象(Target Object): 包含连接点的对象。也被称作被通知或被代理对象。POJO

详细可以参考:

十分钟全面理解Spring AOP - 简书

5 AOP使用场景

  1. Authentication 权限
  2. Caching 缓存
  3. Context passing 内容传递
  4. Error handling 错误处理
  5. Lazy loading 懒加载
  6. Debugging  调试
  7. logging, tracing, profiling and monitoring 记录跟踪 优化 校准
  8. Performance optimization 性能优化
  9. Persistence  持久化
  10. Resource pooling 资源池
  11. Synchronization 同步
  12. Transactions 事务

6 Advice通知类型介绍

  1. Before:在目标方法被调用之前做增强处理,@Before只需要指定切入点表达式即可
  2. AfterReturning:在目标方法正常完成后做增强,@AfterReturning除了指定切入点表达式后,还可以指定一个返回值形参名returning,代表目标方法的返回值
  3. AfterThrowing:主要用来处理程序中未处理的异常,@AfterThrowing除了指定切入点表达式后,还可以指定一个throwing的返回值形参名,可以通过该形参名来访问目标方法中所抛出的异常对象
  4. After:在目标方法完成之后做增强,无论目标方法时候成功完成。@After可以指定一个切入点表达式
  5. Around:环绕通知,在目标方法完成前后做增强处理,环绕通知是最重要的通知类型,像事务,日志等都是环绕通知,注意编程中核心是一个ProceedingJoinPoint
  6.  执行顺序

around > before > around > after > afterReturning

示例代码:

@Aspect
@Component
public class TransactionAOP {
    @Pointcut("execution(* com.lee..service.*.*(..))")
    public void pointcut() {
    }
    @Before("pointcut()")
    public void beginTransaction() {
        System.out.println("before beginTransaction");
    }
    @After("pointcut()")
    public void commit() {
        System.out.println("after commit");
    }
    @AfterReturning("pointcut()", returning = "returnObject")
    public void afterReturning(JoinPoint joinPoint, Object returnObject) {
        System.out.println("afterReturning");
    }
    @AfterThrowing("pointcut()")
    public void afterThrowing() {
        System.out.println("afterThrowing afterThrowing  rollback");
    }
    @Around("pointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        try {
            System.out.println("around");
            return joinPoint.proceed();
        } catch (Throwable e) {
            e.printStackTrace();
            throw e;
        } finally {
            System.out.println("around");
        }
    }
}

   

Spring中AOP的两种代理方式(Java动态代理和CGLIB代理)

Java 动态代理。具体有如下四步骤:

  1. 通过实现 InvocationHandler 接口创建自己的调用处理器;
  2. 通过为 Proxy 类指定 ClassLoader 对象和一组 interface 来创建动态代理类;
  3. 通过反射机制获得动态代理类的构造函数,其唯一参数类型是调用处理器接口类型;
  4. 通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数被传入。

GCLIB代理

  cglib(Code Generation Library)是一个强大的,高性能,高质量的Code生成类库。它可以在运行期扩展Java类与实现Java接口。

  cglib封装了asm,可以在运行期动态生成新的class。

  cglib用于AOP,jdk中的proxy必须基于接口,cglib却没有这个限制。

原理区别:

     java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。而cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。

    1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP

    2、如果目标对象实现了接口,可以强制使用CGLIB实现AOP

    3、如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换

如何强制使用CGLIB实现AOP?

       * 添加CGLIB库,SPRING_HOME/cglib/*.jar

       * 在spring配置文件中加入<AOP:aspectj-autoproxy proxy-target-class="true"/>

JDK动态代理和CGLIB字节码生成的区别?

      * JDK动态代理只能对实现了接口的类生成代理,而不能针对类

      * CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法

   因为是继承,所以该类或方法最好不要声明成final,否则无法使用CGLIB

8 AspectJ,SpringAOP,cglib,动态代理究竟有啥区别

      我只想写业务流程代码,不想管日志,权限,事务等业务无关的东西,怎么办?

要是我只写业务代码,想要其他代码的时候有人帮我写就好了。。。于是,代理(代码小蜜)就出现了,代理有好多种实现方式呢:

AspectJ

       首先,这是一种语言,类似于Java语言,与Java无缝兼容,而且像Java自带jvm一样,这种语言也自带编译器acj。

        从上图可以看出,AspectJ在编译期就织入了代码,这个代理我们称之为 静态代理。

SpringAOP

        Spring大行其道,所以AOP这块有了SpringAOP的出现。

        当然,使AspectJ的方式也慢慢的退居到次要选择的地位了。。。

Spring一上来就 王炸,直接在运行时再织入,所以就是 动态代理 了。

  1. Spring AOP借鉴了很多AspectJ的思想,就是在以上这一点与AspectJ不同。
  2. Spring AOP并不是直接完成AOP的功能,其根据代理类是否实现接口有两种实现方式:
  3. Spring AOP属于运行时增强,而AspectJ是编译时增强。Spring AOP基于代理,而AspectJ基于字节码操作。
  4. Spring AOP已经集成了AspectJ,AsectJ应该算的上是Java生态系统中最完整的AOP框架了。AspectJ相比于Spring AOP功能更加强大,但是Spring AOP相对来说更简单,如果我们的切面比较少,那么两者的性能差异不大。但是当切面太多的话,最好选择AspectJ,它比Spring AOP快很多。

cglib

       基于继承,通过目标类的字节码实例化目标类的一个子类来增强,所以不需要目标类实现某个接口就行。

java proxy

      基于反射,代理和目标类实现相同的接口,完成目标类的增强,所以要求目标类必须实现某个接口。

      以上,就是这几个的区别了。

简单即是美。。。

9  理解Spring么,它的AOP实现是基于什么原理,bean的初始化过程是哪些?在beanFactory初始化前、运行中、初始化后想做些事情。该怎么做?

     spring的AOP基于cglib,对代码做混淆。 bean初始化的时候,首先读取XML配置文件,解析完成Bean的组装,由BeanFactory组装生成Bean, 可以指定是单例或者new instance

10 AOP与OOP的区别

      AOP(Aspect Oriented Programming) 面向切面编程,是目前软件开发中的一个热点,是Spring框架内容,利用AOP可以对业务逻辑的各个部分隔离,从而使的业务逻辑各部分的耦合性降低,提高程序的可重用性,提升开发效率,主要功能:日志记录,性能统计,安全控制,事务处理,异常处理等。

     AOP实现原理是java动态代理,但是jdk的动态代理必须实现接口,所以spring的AOP是用cglib这个库实现的,cglib使用里asm这个直接操纵字节码的框架,所以可以做到不使用接口的情况下实现动态代理。

OOP是什么

       OOP面向对象编程,针对业务处理过程的实体及其属性和行为进行抽象封装,以获得更加清晰高效的逻辑单元划分。而AOP则是针对业务处理过程中的切面进行提取,它所面对的是处理过程的某个步骤或阶段,以获得逻辑过程的中各部分之间低耦合的隔离效果。这两种设计思想在目标上有着本质的差异。

举例:

      对于“雇员”这样一个业务实体进行封装,自然是OOP的任务,我们可以建立一个“Employee”类,并将“雇员”相关的属性和行为封装其中。而用AOP 设计思想对“雇员”进行封装则无从谈起。

同样,对于“权限检查”这一动作片段进行划分,则是AOP的目标领域。

OOP面向名词领域,AOP面向动词领域。

       总之AOP可以通过预编译方式和运行期动态代理实现在不修改源码的情况下,给程序动态同意添加功能的一项技术。

11  面向切面的基本原理

什么是面向切面编程

  1. 横切关注点:影响应用多处的功能(安全、事务、日志)
  2. 切面:横切关注点被模块化为特殊的类,这些类称为切面

优点

       每个关注点现在都集中于一处,而不是分散到多处代码中

        服务模块更简洁,服务模块只需关注核心代码。

AOP 术语

1 通知

          定义:切面也需要完成工作。在 AOP 术语中,切面的工作被称为通知。

          工作内容:通知定义了切面是什么以及何时使用。除了描述切面要完成的工作,通知还解决何时执行这个工作。

Spring 切面可应用的 5 种通知类型:

Before——方法调用之前调用通知

After——方法完成之后调用通知,无论方法执行成功与否

After-returning——方法执行成功之后调用通知

After-throwing——方法抛出异常后进行通知

Around——通知包裹了被通知的方法,在被通知的方法调用之前和调用之后执行自定义的行为

2 连接点

         定义:连接点是一个应用执行过程中能够插入一个切面的点。

         连接点可以是调用方法时、抛出异常时、甚至修改字段时、切面代码可以利用这些点插入到应用的正规流程中

程序执行过程中能够应用通知的所有点。

3 切点

        定义:如果通知定义了“什么”和“何时”。那么切点就定义了“何处”。切点会匹配通知所要织入的一个或者多个连接点。通常使用明确的类或者方法来指定这些切点。

作用:定义通知被应用的位置(在哪些连接点)

4 切面

      定义:切面是通知和切点的集合,通知和切点共同定义了切面的全部功能——它是什么,在何时何处完成其功能。

5 引入

      引入允许我们向现有的类中添加方法或属性

 6 织入

        织入是将切面应用到目标对象来创建的代理对象过程。

       切面在指定的连接点被织入到目标对象中,在目标对象的生命周期中有多个点可以织入

        编译期——切面在目标类编译时期被织入,这种方式需要特殊编译器。AspectJ的织入编译器就是以这种方式织入切面。

        类加载期——切面在类加载到JVM ,这种方式需要特殊的类加载器,他可以在目标类被引入应用之前增强该目标类的字节码。AspectJ5 的 LTW 就支持这种织入方式

        运行期——切面在应用运行期间的某个时刻被织入。一般情况下,在织入切面时候,AOP 容器会为目标对象动态的创建代理对象。Spring AOP 就是以这种方式织入切面。

12 Spring AOP和AspectJ区别

      spring确实有自己的AOP。功能已经基本够用了,除非你的要在接口上动态代理或者方法拦截精确到getter和setter。这些都是写奇葩的需求,一般不使用。

      在使用AOP的时候,你是用xml还是注解的方式(@Aspect)?

1)如果使用xml方式,不需要任何额外的jar包。

2)如果使用@Aspect方式,你就可以在类上直接一个@Aspect,然后在xml里加上<AOP:aspectj-autoproxy />。但是这需要额外的jar包( aspectjweaver.jar)。因为spring直接使用AspectJ的注解功能,注意只是使用了它的注解功能而已。并不是核心功能 !!!

       注意到文档上还有一句很有意思的话:文档说到 是选择spring AOP还是使用full aspectJ?

什么是full aspectJ?如果你使用"full aspectJ"。就是说你可以实现基于接口的动态代理,等等强大的功能。而不仅仅是aspectj的 注-解-功-能 !!!

       如果用full AspectJ。比如说Load-Time Weaving的方式 还 需要额外的jar包 spring-instrument.jar

      当然,无论是使用spring AOP还是 aspectj都需要aspectjweaver.jarspring-AOP.jar这两个jar包。

13 Spring有哪些主要模块?

Spring框架的七大模块

  1. Spring Core框架的最基础部分,提供 IOC 容器,对 bean 进行管理。
  2. Spring Context基于 bean,提供上下文信息,扩展出JNDI、EJB、电子邮件、国际化、校验和调度等功能。
  3. Spring DAO提供了JDBC的抽象层,它可消除冗长的JDBC编码和解析数据库厂商特有的错误代码,还提供了声明性事务管理方法。
  4. Spring ORM提供了常用的“对象/关系”映射APIs的集成层。 其中包括JPA、JDO、Hibernate、MyBatis 等。
  5. Spring AOP提供了符合AOP Alliance规范的面向方面的编程实现。
  6. Spring Web提供了基础的 Web 开发的上下文信息,可与其他 web 进行集成。
  7. Spring Web MVC提供了 Web 应用的 Model-View-Controller 全功能实现。

14 Spring常用的注入方式有哪些?

        xml中配置、注解

15 spring中的bean是线程安全的吗?

       spring 中的 bean 默认是单例模式,spring 框架并没有对单例 bean 进行多线程的封装处理。

Spring 不保证 bean 的线程安全。默认 spring 容器中的 bean 是单例的。当单例中存在竞态条件,即有线程安全问题

      所以 spring 管理的 bean 的线程安全跟 bean 的创建作用域和 bean 所在的使用环境是否存在竞态条件有关,spring 并不能保证 bean 的线程安全。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值