Java面试题冲刺第八天--Spring框架2

目录
  • 面试题1:聊一下你对AOP的理解吧?
    • 追问1:Advice通知的类型有哪几种?
    • 追问2:在同一个切面(Aspect)中,不同Advice的执行顺序
  • 面试题2:AspectJ AOP 和 Spring AOP 有什么区别?
    • 追问1:了解JDK动态代理和CGLIB动态代理的原理么?他俩有哪些区别?
  • 面试题3:什么是基于Java的Spring注解配置? 给一些注解的例子
  • 总结

面试题1:聊一下你对AOP的理解吧?

AOP(Aspect Oriented Programming),面向切面思想,是Spring的三大核心思想之一(两外两个:IOC-控制反转、DI-依赖注入)。AOP主要应用于处理一些具有横切性质的系统级服务,如日志收集事务管理安全检查(权限校验)缓存对象池管理等

那么AOP是干啥的?在我们的程序中,经常存在一些系统性的需求,比如权限校验、记录日志等,这些代码会散落穿插在各个业务逻辑中,非常冗余且不利于维护。例如下面这个示意图:

有多少业务操作,就要写多少重复的校验和日志记录代码,这显然是无法接受的。当然,用面向对象的思想,我们可以把这些重复的代码抽离出来,写成公共方法,就是下面这样:

这样,代码冗余和可维护性的问题得到了解决,但每个业务方法中依然要依次手动调用这些公共方法,也是略显繁琐。有没有更好的方式呢?有的,那就是AOP,AOP将权限校验、日志记录等非业务代码完全提取出来,与业务代码分离,并寻找节点切入业务代码中:

使用AOP的好处主要是降低模块的耦合度、使系统容易扩展、提高代码复用性

简单地去理解,其实AOP要做三类事:

  • 在哪里切入,也就是权限校验等非业务操作在哪些业务代码中执行。
  • 在什么时候切入,是业务代码执行前还是执行后。
  • 切入后做什么事,比如做权限校验、日志记录等。

因此,AOP的体系可以梳理为下图:

AOP的一些概念:

  • 切入点(Pointcut):决定处理如权限校验、日志记录等在何处切入业务代码中(即织入切面)。切点分为execution方式和annotation方式。前者可以用路径表达式指定哪些类织入切面,后者可以指定被哪些注解修饰的代码织入切面。
  • 通知(Advice):我们也叫它处理(即“切面”对于某个“连接点”所产生的动作),包括处理时机和处理内容。处理内容就是要做什么事,比如校验权限和记录日志。处理时机就是在什么时机执行处理内容,分为前置处理(即业务代码执行前)、后置处理(业务代码执行后)等。
  • 切面(Aspect):即Pointcut和Advice。
  • 连接点(Joint point):是程序执行的一个点。例如,一个方法的执行或者一个异常的处理。在 Spring AOP 中,一个连接点总是代表一个方法执行。
  • 织入(Weaving):就是通过动态代理,在目标对象方法中执行处理内容的过程。
  • 目标对象(Target Object) :被一个或者多个切面所通知的对象。
  • AOP代理(AOP Proxy) 在Spring AOP中有两种代理方式,JDK动态代理和CGLIB代理。

追问1:Advice通知的类型有哪几种?

在AOP术语中,切面的工作被称为通知,实际上是程序执行时要通过SpringAOP框架触发的代码段

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

  • 前置通知(Before):在目标方法被调用之前调用通知功能;
  • 后置通知(After):在目标方法完成之后调用通知,此时不会关心方法的输出是什么;
  • 返回通知(After-returning ):在目标方法成功执行之后调用通知;
  • 异常通知(After-throwing):在目标方法抛出异常后调用通知;
  • 环绕通知(Around):通知包裹了被通知的方法,在被通知的方法调用之前和调用之后执行自定义的行为。

追问2:在同一个切面(Aspect)中,不同Advice的执行顺序

无异常情况下:

/*************不同Advice的执行顺序*****************/
1. around before advice
2. before advice
3. target method (执行代码段)
4. around after advice
5. after advice
/*******************前五个都一样*******************/
6. afterReturning
/*************************************************/

有异常情况下:

/*************不同Advice的执行顺序*****************/
1. around before advice
2. before advice
3. target method (执行代码段)
4. around after advice
5. after advice
/*******************前五个都一样*******************/
6. afterThrowing:异常发生
7. java.lang.RuntimeException: 异常发生
/*************************************************/

面试题2:AspectJ AOP 和 Spring AOP 有什么区别?

AOP实现的关键在于代理模式,AOP代理主要分为静态代理动态代理

  • 静态代理的代表为AspectJ;
  • 动态代理则以Spring AOP为代表;

Spring AOP和AspectJ有不同的目标。

  • Spring AOP旨在通过Spring IoC提供一个简单的AOP实现,以解决编码人员面临的最常出现的问题。这并不是完整的AOP解决方案,它只能用于Spring容器管理的beans
  • 另一方面,AspectJ是最原始的AOP实现技术,提供了玩这个的AOP解决方案。AspectJ更为健壮,相对于Spring AOP也显得更为复杂。值得注意的是,AspectJ能够被应用于所有的领域对象。

从原理上看:

Spring AOP

  • 基于动态代理来实现,默认如果使用接口的,用JDK提供的动态代理实现,如果是方法则使用CGLIB实现
  • Spring AOP需要依赖IOC容器来管理,并且只能作用于Spring容器,使用纯Java代码实现
  • 在性能上,由于Spring AOP是基于动态代理来实现的,在容器启动时需要生成代理实例,在方法调用上也会增加栈的深度,使得Spring AOP的性能不如AspectJ的那么好

AspectJ

AspectJ属于静态代理(织入),通过修改代码来实现,有如下几个织入的时机:

  1. 编译期织入(Compile-time weaving): 如类 A 使用 AspectJ 添加了一个属性,类 B 引用了它,这个场景就需要编译期的时候就进行织入,否则没法编译类 B。
  2. 编译后织入(Post-compile weaving): 也就是已经生成了 .class 文件,或已经打成 jar 包了,这种情况我们需要增强处理的话,就要用到编译后织入。
  3. 类加载后织入(Load-time weaving): 指的是在加载类的时候进行织入,要实现这个时期的织入,有几种常见的方法。1、自定义类加载器来干这个,这个应该是最容易想到的办法,在被织入类加载到 JVM 前去对它进行加载,这样就可以在加载的时候定义行为了。2、在 JVM 启动的时候指定 AspectJ 提供的 agent:-javaagent:xxx/xxx/aspectjweaver.jar。

AspectJ可以做Spring AOP干不了的事情,它是AOP编程的完全解决方案,Spring AOP则致力于解决企业级开发中最普遍的AOP(方法织入)。而不是成为像AspectJ一样的AOP方案。

因为AspectJ在实际运行之前就完成了织入,所以说它生成的类是没有额外运行时开销的

指标项 Spring AOP AspectJ
使用语言 在纯 Java 中实现 使用 Java 编程语言的扩展实现
是否需要编译 不需要单独的编译过程 除非设置 LTW,否则需要 AspectJ 编译器 (ajc)
织入方式 只能使用运行时织入 运行时织入不可用。支持编译时、编译后和加载时织入
织入能力 功能不强-仅支持方法级编织 更强大 – 可以编织字段、方法、构造函数、静态初始值设定项、最终类/方法等……。
适用范围 只能在由 Spring 容器管理的 bean 上实现 可以在所有域对象上实现
切入点要求 仅支持方法执行切入点 支持所有切入点
代理局限 代理是由目标对象创建的, 并且切面应用在这些代理上 在执行应用程序之前 (在运行时) 前, 各方面直接在代码中进行织入
性能 比 AspectJ 慢很多 更好的性能
复杂度 易于学习和应用 相对于 Spring AOP 来说更复杂

追问1:了解JDK动态代理和CGLIB动态代理的原理么?他俩有哪些区别?

Spring AOP中的动态代理主要有两种方式,JDK动态代理CGLIB动态代理

JDK动态代理:是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用 InvokeHandler 来处理,他有一个限制,就是它只能为接口创建代理实例,那么对于没有通过接口定义业务方法的类,就要用CGLIB动态代理了。 CGLIB(Code Generation Library)动态代理:是一个基于ASM的字节码生成库,它允许我们在运行时对字节码进行修改和动态生成。CGLIB通过继承方式实现代理,在子类中采用方法拦截的技术拦截所有父类方法的调用并顺势织入横切逻辑。

JDK动态代理具体实现原理:

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

JDK动态代理是面向接口的代理模式,如果被代理目标没有接口那么Spring也无能为力,Spring通过Java的反射机制生产被代理接口的新的匿名实现类,重写了其中AOP的增强方法。

CGLib动态代理:

利用ASM开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。

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

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

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

3、两者对比:

  • JDK动态代理是面向接口的。
  • CGLib动态代理是通过字节码底层继承要代理类来实现(对指定的类生成一个子类,覆盖其中的方法),因此如果被代理类被final关键字所修饰,会失败。

面试题3:什么是基于Java的Spring注解配置? 给一些注解的例子

基于Java的配置,允许你在少量的Java注解的帮助下进行大部分Spring配置,而非通过XML文件。当然,也不不建议啥都用注解配置,毕竟如果修改就要动class文件很麻烦。因此建议:不会修改、极少修改的用注解,会修改的用xml配置,如AOP的配置我就用XML,因为这个需要改的场景比较多。

@Configuration 注解为例,它用来标记类可以当做一个bean的定义,被Spring IOC容器使用。另一个是通过@Bean注解,它表示此方法将要返回一个对象,作为一个bean注册进Spring应用上下文。

@Configuration
public class StudentConfig {
    @Bean
    public StudentBean myStudent() {
        return new StudentBean();
    }

怎样开启注解装配呢?

注解装配在默认情况下是不开启的,为了使用注解装配,我们必须在Spring配置文件中配置 <context:annotation-config/>元素。

一些常见的注解:

1、@Component:

这将 java 类标记为 bean。它是任何 Spring 管理组件的通用构造型。spring 的组件扫描机制现在可以将其拾取并将其拉入应用程序环境中。

2、@Controller:

这将一个类标记为 Spring Web MVC 控制器。标有它的 Bean 会自动导入到 IoC 容器中。

3、@Service:

此注解是组件注解的特化。它不会对 @Component 注解提供任何其他行为。我们可以在服务层类中使用 @Service 而不是 @Component,因为它以更好的方式指定了意图。

4、@Repository:

这个注解是具有类似用途和功能的 @Component 注解的特化。它为 DAO 提供了额外的好处。它将 DAO 导入 IoC 容器,并使未经检查的异常有资格转换为 Spring DataAccessException。

5、@Required :

这个注解表明bean的属性必须在配置的时候设置,通过一个bean定义的显式的属性值或通过自动装配,若@Required注解的bean属性未被设置,容器将抛出BeanInitializationException

示例:

public class Employee {
    private String name;
    @Required
    public void setName(String name){
        this.name=name;
    }
    public string getName(){
        return name;
    }
}

6、@Autowired :

@Autowired默认是按照类型装配注入的,默认情况下它要求依赖对象必须存在(可以设置它required属性为false)。@Autowired 注解提供了更细粒度的控制,包括在何处以及如何完成自动装配。它的用法和@Required一样,修饰setter方法、构造器、属性或者具有任意名称和/或多个参数的PN方法。

public class Employee {
    private String name;
    @Autowired
    public void setName(String name) {
        this.name=name;
    }
    public string getName(){
        return name;
    }

@Autowired和@Resource的区别

@Autowired可用于:构造函数、成员变量、Setter方法

@Autowired和@Resource之间的区别

@Autowired:默认是按照类型装配注入的,默认情况下它要求依赖对象必须存在(可以设置它required属性为false)。

@Resource:默认是按照名称来装配注入的,只有当找不到与名称匹配的bean才会按照类型来装配注入。

7、@Qualifier :

当创建多个相同类型的 bean 并希望仅使用属性装配其中一个 bean 时,可以使用@Qualifier 注解和 @Autowired 通过指定应该装配哪个确切的 bean 来消除歧义。

8、@RequestMapping :

@RequestMapping 注解用于将特定 HTTP 请求方法映射到将处理相应请求的控制器中的特定类/方法。此注释可应用于两个级别:

  • 类级别:映射请求的URL
  • 方法级别:映射 URL 以及 HTTP 请求方法

总结

本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注我们的更对内容!

(0)

相关推荐

  • Java框架搭建之Maven、Mybatis、Spring MVC整合搭建(图文)

    本文主要介绍了Java框架搭建之Maven.Mybatis.Spring MVC整合搭建(图文),分享给大家,具体如下: SSM(Spring+SpringMVC+Mybatis),目前较为主流的企业级架构方案.标准的MVC设计模式,将整个系统划分为显示层.Controller层.Service层.Dao层四层,使用SpringMVC负责请求的转发和视图管理,Spring实现业务对象管理, MyBatis作为数据对象持久化引擎. 框架详情 Spring 是一个轻量级的Java开发框架,它是为了解

  • Java SpringMVC框架开发之数据导出Excel文件格式实例详解

    在平时的开发中,我们会经常遇到这样一个需求,要在页面通过一个『导出』按钮把查询出的数据导出到 Excel 表格中.本文即为实现上述需求的一个小实例. 环境配置 jar包 poi.jar jdk 1.6 tomcat 7.0 eclipse 4.4.0 本 Demo 是在 SpringMVC框架中实现. 页面 export.jsp 很简单,就只有一个超链接. <%@ page language="java" contentType="text/html; charset=

  • Spring--国内Java程序员用得最多的框架

    目录 第一节:Spring Framework核心技术底层原理详解 1.Spring 概述 2.核心思想 3.S手写实现 IoC 和 AOP 4.Spring IOC 应用 5. Spring IOC源码深度剖析 6.Spring AOP 应用 7.Spring AOP源码深度剖析 第二节:Spring Boot技术难点源码深入剖析 第一部分:基础应用开发 第二部分:分布式应用开发 第三部分:核心技术源代码分析 第三节:阿里微服务Spring Cloud Alibaba架构实战笔记 第四节:Sp

  • Java安全框架——Shiro的使用详解(附springboot整合Shiro的demo)

    Shiro简介 Apache Shiro是一个强大且易用的Java安全框架,执行身份验证.授权.密码和会话管理 三个核心组件:Subject, SecurityManager 和 Realms Subject代表了当前用户的安全操作 SecurityManager管理所有用户的安全操作,是Shiro框架的核心,Shiro通过SecurityManager来管理内部组件实例,并通过它来提供安全管理的各种服务. Realm充当了Shiro与应用安全数据间的"桥梁"或者"连接器&q

  • JAVA学习之一步步搭建spring框架

    前言 作为一个服务端开发感觉一直挺排斥框架这种东西的,总觉得什么实现逻辑都帮你封装在里面了,你只需要配置这配置那个,出了问题也不知道怎么排查,之前即使写web程序也宁愿使用jetty这样的嵌入式的web server实现,自己写servlet,总感觉从main函数开始都在自己的掌控范围之内,但是这样的方式的确有点原始,也看到各种各样的开源系统使用spring实现web服务,虽然代码总是能够看明白,但是还是不晓得一步步是怎么搭建的,于是抽出一个周末折腾折腾,不搞不知道,原来这玩意能把一个不熟悉的用

  • Java面试题冲刺第八天--Spring框架2

    目录 面试题1:聊一下你对AOP的理解吧? 追问1:Advice通知的类型有哪几种? 追问2:在同一个切面(Aspect)中,不同Advice的执行顺序 面试题2:AspectJ AOP 和 Spring AOP 有什么区别? 追问1:了解JDK动态代理和CGLIB动态代理的原理么?他俩有哪些区别? 面试题3:什么是基于Java的Spring注解配置? 给一些注解的例子 总结 面试题1:聊一下你对AOP的理解吧? AOP(Aspect Oriented Programming),面向切面思想,是

  • Java面试题冲刺第十八天--Spring框架3

    面试题1:Bean 的加载过程是怎样的? 我们知道, Spring 的工作流主要包括以下两个环节: 解析,读 xml 配置,扫描类文件,从配置或者注解中获取 Bean 的定义信息,注册一些扩展功能. 加载,通过解析完的定义信息获取 Bean 实例. 下面是跟踪了 getBean的调用链创建的流程图,为了能够很好地理解 Bean 加载流程,省略一些异常.日志和分支处理和一些特殊条件的判断. 从上面的流程图中,可以看到一个 Bean 加载主要会经历这么几个阶段(标绿内容): 获取 BeanName,

  • Java面试题冲刺第七天--Spring框架1

    目录 面试题1:能简单说一下你对Spring框架的理解么? 追问1:常见的Core组件有哪些? 面试题2:谈谈对Spring IOC的理解 追问1:Spring中的bean的作用域有哪些? 追问2:Spring中的bean生命周期? 追问3: Spring 中的 bean 是线程安全的吗? 面试题3:说一下 SpringMVC 运行流程? 追问1:能介绍一下SpringMVC各组件的作用么? 总结 面试题1:能简单说一下你对Spring框架的理解么? 我们一般说的Spring框架就是Spring

  • Java面试题冲刺第九天--MyBatis

    目录 面试题1:你怎么理解ORM框架,常见的ORM框架都有哪些? 正经回答: 追问1:大家都在用Mybatis,Mybatis都有哪些优势? 面试题2:相比较Hibernate与Mybatis,你有哪些看法? 正经回答: 面试题3:Mybatis中的#{}和${}有哪些区别 正经回答: 深入追问: 追问1:什么是sql注入? 追问2:mybatis是如何做到防止sql注入的? 总结 面试题1:你怎么理解ORM框架,常见的ORM框架都有哪些? 正经回答: 对象关系映射(Object Relatio

  • Java面试题冲刺第十四天--PRC框架

    目录 面试题1:说说你对RPC框架的理解? 追问1:RPC框架实现原理是什么样的 1.建立通信 2.服务寻址 3.网络传输 4.服务调用 面试题2:常见的RPC框架有哪些? 面试题3:说说RPC和SOA.SOAP.REST的区别吧 1.REST 2.SOAP 3.SOA 总结 面试题1:说说你对RPC框架的理解?   RPC (Remote Procedure Call)即远程过程调用,是分布式系统常见的一种通信方法.它允许程序调用另一个地址空间(通常是共享网络的另一台机器上)的过程或函数,而不

  • Java面试题冲刺第三天--集合框架篇

    目录 面试题1:对比 Vector.ArrayList.LinkedList 有何区别?适合在什么场景下使用 正经回答: 深入追问: 追问1:多线程场景下就不能使用ArrayList么? 追问2:说一下 HashSet 的实现原理? 追问3:HashSet是如何保证Key不重复的? 面试题2:List 和 Set 有哪些区别? 正经回答: 面试题3:Array 和 ArrayList 有何区别? 正经回答: 总结 面试题1:对比 Vector.ArrayList.LinkedList 有何区别?

  • Java面试题冲刺第十一天--集合框架篇(2)

    目录 面试题1:说一下 HashMap 的实现原理? 正经回答: 深入追问: 追问1:如何实现HashMap的有序? 追问2:那TreeMap怎么实现有序的? 追问3:put方法原理是怎么实现的? 追问4:HashMap扩容机制原理 追问5:HashMap在JDK1.8都做了哪些优化? 追问6:链表红黑树如何互相转换?阈值多少? 面试题2:HashMap是线程安全的吗? 正经回答: 追问1:你是如何解决这个线程不安全问题的? 总结 面试题1:说一下 HashMap 的实现原理? 正经回答: 众所

  • Java面试题冲刺第九天--MyBatis2

    目录 面试题1:说说你对Mybatis的理解? 追问1:说一下MyBatis的工作原理和流程吧. 追问2:列举几个MyBatis的核心组件,说说分别干啥用? 面试题2:(问几个实际使用的问题)Mybatis动态sql是做什么的?都有哪些动态sql? 追问1:Xml映射文件中,除了常见的select|insert|updae|delete标签之外,你还常用哪些标签? 追问2:Mybatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式? 追问3:MyBatis中接口绑定你都用过哪几

  • Java面试题冲刺第十天--MyBatis2

    目录 面试题1:说说你对Mybatis的理解? 追问1:说一下MyBatis的工作原理和流程吧. 追问2:列举几个MyBatis的核心组件,说说分别干啥用? 面试题2:(问几个实际使用的问题)Mybatis动态sql是做什么的?都有哪些动态sql? 追问1:Xml映射文件中,除了常见的select|insert|updae|delete标签之外,你还常用哪些标签? 追问2:Mybatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式? 追问3:MyBatis中接口绑定你都用过哪几

  • Java面试题冲刺第二十三天--算法(2)

    目录 面试题1:你说一下常用的排序算法都有哪些? 追问1:谈一谈你对快排的理解吧 追问2:说一下快排的算法原理 追问3:来吧!给我手敲一个快排 面试题2:来!再给我手撸一个Spring 追问1:哦,咳咳-说一下构成递归的前提条件有啥? 追问2:递归都有哪些优缺点? 追问3:给我手写一个简单的递归算法的实现吧 面试题3: 10亿个数中找出最大的100000个数(top K问题) 总结 面试题1:你说一下常用的排序算法都有哪些? 追问1:谈一谈你对快排的理解吧 快速排序,顾名思义就是一种以效率快为特

随机推荐