1.操作系统中 heap 和 stack 的区别
2.什么是基于注解的切面实现
3.什么是 对象/关系 映射集成模块
4.什么是 Java 的反射机制
5.什么是 ACID,事务,事务隔离界别和传播级别
6.BS与CS的联系与区别
7.Cookie 和 Session的区别
8.fail-fast 与 fail-safe 机制有什么区别
9.get 和 post请求的区别
10.Interface 与 abstract 类的区别
11.IOC的优点是什么
12.IO 和 NIO的区别,NIO优点
13.Java 8 / Java 7 为我们提供了什么新功能
14.什么是竞态条件? 举个例子说明。
15.JRE、JDK、JVM 及 JIT 之间有什么不同
16.MVC的各个部分都有那些技术来实现?如何实现?
17.RPC 通信和 RMI 区别
18.什么是 Web Service(Web服务)
19.JSWDL开发包的介绍。JAXP、JAXM的解释。SOAP、UDDI,WSDL解释。
20.WEB容器主要有哪些功能? 并请列出一些常见的WEB容器名字。
21.一个”.java”源文件中是否可以包含多个类(不是内部类)?有什么限制
22.简单说说你了解的类加载器。是否实现过类加载器
23.解释一下什么叫AOP(面向切面编程)
24.请简述 Servlet 的生命周期及其相关的方法
25.请简述一下 Ajax 的原理及实现步骤
26.简单描述Struts的主要功能
27.什么是 N 层架构
28.什么是CORBA?用途是什么
29.什么是Java虚拟机?为什么Java被称作是“平台无关的编程语言”
30.什么是正则表达式?用途是什么?哪个包使用正则表达式来实现模式匹配
31.什么是懒加载(Lazy Loading)
32.什么是尾递归,为什么需要尾递归
33.什么是控制反转(Inversion of Control)与依赖注入(Dependency Injection)
34.Spirng的AOP的动态代理实现机制,JDK代理和cglib代理的区别
答案:
1. 操作系统中 heap 和 stack 的区别 参考链接
空间分配(操作系统):
栈:由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈;
堆:一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表。
缓存方式:
栈:使用的是一级缓存,他们通常都是被调用时处于存储空间中,调用完毕立即释放;
堆:存放在二级缓存中,生命周期由虚拟机的垃圾回收算法来决定。调用这些对象的速度要相对来得低一些。
数据结构:
栈:一种先进后出的数据结构。
堆:先进先出,可以被看成是一棵树,如:堆排序;
Java中的区别:
1.栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆。
2.在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配。当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作他用。
3.堆内存用来存放由new创建的对象和数组,在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理。在堆中产生了一个数组或对象后,还可以在栈中定义一个特殊的变量,让栈中这个变量的取值等于数组或对象在堆内存中的首地址,栈中的这个变量就成了数组或对象的引用变量。引用变量就相当于是为数组或对象起的一个名称,以后就可以在程序中使用栈中的引用变量来访问堆中的数组或对象。
Java中变量在内存中的分配:
1、类变量(static修饰的变量):在程序加载时系统就为它在堆中开辟了内存,堆中的内存地址存放于栈以便于高速访问。静态变量的生命周期–一直持续到整个”系统”关闭。
2、实例变量:使用new时,系统在堆中开辟并不一定是连续的空间分配给变量(比如说类实例),然后根据零散的堆内存地址,通过哈希算法换算为一长串数字以表征这个变量在堆中的”物理位置”。 当实例变量的引用丢失后,会被GC回收3、局部变量:局部变量,由声明在某方法,或某代码段里(比如for循环),执行到它的时候在栈中开辟内存,当局部变量一但脱离作用域,内存立即释放。
2.什么是基于注解的切面实现
基于@AspectJ的实现
1.需要在IOC容器中将切面声明为Bean实例.当在SpringIOC容器中初始化AspectJ切面之后,Spring IOC容器就会为那些与AspectJ切面相匹配的Bean创建代理.
2.在 AspectJ注解中,切面只是一个带有@Aspect注解的 Java类.
3.通知是标注有某种注解的简单的 Java方法.AspectJ支持5种类型的通知注解:
@Before: 前置通知,方法执行之前
@After: 后置通知,方法执之后
@AfterRunning:返回通知,方法返回结果后
@AfterThrowing:异常通知,方法抛出异常后
@Around: 环绕通知,围绕着方法执行
4.可以利用方法签名编写AspectJ切入点表达式。execution写法。
3. 什么是 对象/关系 映射集成模块
面向对象编程中的 对象(Object) 和关系数据库的 关系(Relation) 的一个映射(Mapping)。
4. 什么是 Java 的反射机制 参考链接1 参考链接2
就是可以在程序运行的时候动态装载类,查看类的信息,生成对象,或操作生成对象
java.lang.Class、java.lang.reflect.Constructor Field、Method、Modifier(修饰符)
5.什么是 ACID,事务,事务隔离级别和传播级别 参考链接
事务相关知识,还有3类数据读取和2类数据更新问题,隔离级别
1)原子性(Atomic):事务中各项操作,要么全做要么全不做,任何一项操作的失败都会导致整个事务的失败;
2)一致性(Consistent):事务结束后系统状态是一致的;
3)隔离性(Isolated):并发执行的事务彼此无法看到对方的中间状态;
4)持久性(Durable):事务完成后所做的改动都会被持久化,即使发生灾难性的失败。通过日志和同步备份可以在故障发生后重建数据。
脏读(Dirty Read):A事务读取B事务尚未提交的数据并在此基础上操作,而B事务执行回滚,那么A读取到的数据就是脏数据。
不可重复读(Unrepeatable Read):事务A重新读取前面读取过的数据,发现该数据已经被另一个已提交的事务B修改过了。
幻读(Phantom Read):事务A重新执行一个查询,返回一系列符合查询条件的行,发现其中插入了被事务B提交的行。
第1类丢失更新:事务A撤销时,把已经提交的事务B的更新数据覆盖了。
第2类丢失更新:事务A覆盖事务B已经提交的数据,造成事务B所做的操作丢失。
隔离级别
脏读
不可重复读
幻读
第一类丢失更新
第二类丢失更新
READ UNCOMMITED
允许
允许
允许
不允许
允许
READ COMMITTED
不允许
允许
允许
不允许
允许
REPEATABLE READ
不允许
不允许
允许
不允许
不允许
SERIALIZABLE
不允许
不允许
不允许
不允许
不允许
这里再补充下spring事务的传播行为和隔离级别 参考链接
Propagation : key属性确定代理应该给哪个方法增加事务行为。这样的属性最重要的部份是传播行为。有以下选项可供使用:
PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。
Spring事务的隔离级别
1. ISOLATION_DEFAULT: 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别.
另外四个与JDBC的隔离级别相对应
2. ISOLATION_READ_UNCOMMITTED: 这是事务最低的隔离级别,它充许令外一个事务可以看到这个事务未提交的数据。
这种隔离级别会产生脏读,不可重复读和幻像读。
3. ISOLATION_READ_COMMITTED: 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据
4. ISOLATION_REPEATABLE_READ: 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。
它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。
5. ISOLATION_SERIALIZABLE 这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。
除了防止脏读,不可重复读外,还避免了幻像读。
6. BS与CS的联系与区别 参考链接
Client/Server:服务器通常采用高性能的PC、工作站或小型机,并采用大型数据库系统。客户端需要安装专用的客户端软件。
Brower/Server:客户机上只要安装一个浏览器。用户界面完全通过浏览器实现,一部分事务逻辑在前端实现,但主要事务逻辑在服务器端实现。浏览器通过Web Server同数据库进行数据交互。
1.硬件环境不同: C/S建立在专用网, 局域网。B/S在广域网。
2.对安全要求不同:C/S更高
3.对程序架构不同:C/S更注重流程,系统运行速度较少考虑
4.软件重用不同:B/S更多构件重用
5.系统维护不同:C/S升级难,B/S构件组成可以实现系统的无缝升级
6.处理问题不同:C/S户面固定与操作系统相关. B/S分散地域与操作系统平台关系最小
7.用户接口不同:C/S开发难度高
8.信息流不同:C/S交互低
7. Cookie 和 Session的区别 参考链接
相同点:cookie和session都是用来跟踪浏览器用户身份的会话方式。
不同点:
(1)cookie数据存放在客户的浏览器上,session数据放在服务器上
(2)cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗,如果主要考虑到安全应当使用session
(3)session会在一定时间内保存在服务器上。当访问增多会影响服务器的性能,如果主要考虑到减轻服务器性能方面,应当使用COOKIE
(4)单个cookie在客户端的不能3大于K
(5)所以:登陆信息等重要信息存放为session;其他信息需要保留可以放在cookie中
8.fail-fast 与 fail-safe 机制有什么区别 参考链接
快速失败:当你在迭代一个集合的时候,如果有另一个线程正在修改你正在访问的那个集合时,就会抛出一个ConcurrentModification异常。在java.util包下的都是快速失败。
安全失败:你在迭代的时候会去底层集合做一个拷贝,所以你在修改上层集合的时候是不会受影响的,不会抛出ConcurrentModification异常。在java.util.concurrent包下的全是安全失败的。
9.get 和 post请求的区别 参考链接
HTTP中的GET,POST,PUT,DELETE就对应着对这个资源的查,改,增,删4个操作
1、GET请求,请求的数据会附加在URL之后,以?分割URL和传输数据,多个参数用&连接。URL的编码格式采用的是ASCII编码,而不是uniclde,即是说所有的非ASCII字符都要编码之后再传输。
POST请求:POST请求会把请求的数据放置在HTTP请求包的包体中。上面的item=bandsaw就是实际的传输数据。
GET请求的数据会暴露在地址栏中,而POST请求则不会。
2、传输数据的大小
在HTTP规范中,没有对URL的长度和传输的数据大小进行限制。但是在实际开发过程中,对于GET,特定的浏览器和服务器对URL的长度有限制。因此,在使用GET请求时,传输数据会受到URL长度的限制。
对于POST,由于不是URL传值,理论上是不会受限制的,但是实际上各个服务器会规定对POST提交数据大小进行限制,Apache、IIS都有各自的配置。
3、安全性
POST的安全性比GET的高。这里的安全是指真正的安全,而不同于上面GET提到的安全方法中的安全,上面提到的安全仅仅是不修改服务器的数据。比如,在进行登录操作,通过GET请求,用户名和密码都会暴露再URL上,因为登录页面有可能被浏览器缓存以及其他人查看浏览器的历史记录的原因,此时的用户名和密码就很容易被他人拿到了。除此之外,GET请求提交的数据还可能会造成Cross-site request frogery攻击
10. Interface 与 abstract 类的区别 参考链接
注意Java8中提供接口默认方法和静态方法
(1)抽象层次不同。抽象类是对类抽象,而接口是对行为的抽象。
(2)跨域不同。抽象类所跨域的是具有相似特点的类,而接口却可以跨域不同的类。
(3)设计层次不同。抽象类是自底向上抽象而来的,接口是自顶向下设计出来的。
11. IOC优缺点
优点:控制反转和依赖注入
缺点:占用内存多、使用反射构造对象慢、启动慢
12. IO 和 NIO的区别,NIO优点 参考链接
IO是面向流的,NIO是面向缓冲区的(IO没有被缓存,NIO则能前后移动流中的数据)
IO流是阻塞的,NIO流是不阻塞的(NIO线程只能获得当前数据, )
NIO选择器可使用一个(或几个)单线程管理多个通道(网络连接或文件),但解析数据更复杂。
13.Java 8 / Java 7 为我们提供了什么新功能 参考链接1 参考链接2
java7:
(1)二进制变量的表示,支持将整数类型用二进制来表示,用0b开头。
(2)Switch语句支持string类型
(3)Try-with-resource语句,可Catch多个异常
(4)数字类型的下划线表示long l = 1234_5678_9012_3456L
(5)泛型实例化类型自动推断<>,List<String> s = new ArrayList<>()
(6)NIO2增加了一些新特性,提供更详细属性、Path、Files、File类操作API兼容等优化。其他算法优化。
(7)fork-join(工作窃取算法)、ThreadLocalRandon(并发随机数生成类)、phaser,
(8)jvm增加、HotSpot性能增强
java8:
(1)lambda和函数式编程。方法引用(System.out::print)、Collector收集器、
(2)Stream:类似sql语句查询表,及早返回和惰性函数。Filter过滤、Sort 排序、Map 映射、Match 匹配、Count 计数、Reduce 规约、parallel并行
(2)Lambda 作用域:可访问final局部变量,实例的字段以及静态变量。
(3)函数式接口(@FunctionalInterface,只包含一个抽象方法的接口)、接口默认方法(default),可直接访问接口的默认方法
Function(T->R)、Consumer(T->void)、Supplier(void->T)、Predicate(T->boolean)、BinaryOperator(BiFunction,根据Comparator返回对应min和max值)、 UnaryOperator(T->T)、Comparator(添加了多种默认方法)、Optional(防止NullPointerException异常的辅助类型)
(4)Date API:Clock 时钟、Timezones 时区、LocalTime 本地时间、LocalDate 本地日期、LocalDateTime 本地日期时间
(5)多重注解:@Repeatable同一个类型的注解使用多次
14.什么是竞态条件? 举个例子说明。参考链接
15.JRE、JDK、JVM 及 JIT 之间有什么不同
JVM虚拟机、JRE运行时环境、JDK开发工具箱、JIT即时编译器
JDK包含JRE, JRE是JVM超集,JIT通过有效的把字节码变成机器码来提高JVM的效率
16. MVC的各个部分都有那些技术来实现?如何实现?
Model/View/Controller,参考SpringMVC
17.RPC 通信和 RMI 区别 参考链接
RPC远程过程调用、RMI远程方法调用。
(1)方法调用方式:RPC中通过网络服务协议向远程主机发送请求、RMI通过远程接口调用对应方法,每个远程方法都具有方法签名
(2)适用语言范围:RPC是网络服务协议,与操作系统和语言无关。RMI只用于Java。
(3)结果返回形式:RMI对应JAVA返回对象或基本数据类型。RPC由外部数据表示 (External Data Representation, XDR)等语言
18 and 19. 什么是 Web Service(Web服务), JSWDL开发包的介绍。JAXP、JAXM的解释。SOAP、UDDI,WSDL解释。 参考链接
Web ServiceWeb Service是基于网络的、分布式的模块化组件,它执行特定的任务,遵守具体的技术规范,这些规范使得Web Service能与其他兼容的组件进行互操作。
JAXP(Java API for XML Parsing) 定义了在Java中使用DOM, SAX, XSLT的通用的接口。这样在你的程序中你只要使用这些通用的接口,当你需要改变具体的实现时候也不需要修改代码。
JAXM(Java API for XML Messaging) 是为SOAP通信提供访问方法和传输机制的API。
WSDL是一种 XML 格式,用于将网络服务描述为一组端点,这些端点对包含面向文档信息或面向过程信息的消息进行操作。这种格式首先对操作和消息进行抽象描述,然后将其绑定到具体的网络协议和消息格式上以定义端点。相关的具体端点即组合成为抽象端点(服务)。
SOAP即简单对象访问协议(Simple Object Access Protocol),它是用于交换XML编码信息的轻量级协议。
UDDI 的目的是为电子商务建立标准;UDDI是一套基于Web的、分布式的、为Web Service提供的、信息注册中心的实现标准规范,同时也包含一组使企业能将自身提供的Web Service注册,以使别的企业能够发现的访问协议的实现标准。
20. WEB容器主要有哪些功能? 并请列出一些常见的WEB容器名字。
提供Servlet程序编写API和Servlet程序运行时环境。常见的有 Apache、Tomcat、Jetty、undertow等
21. 一个”.java”源文件中是否可以包含多个类(不是内部类)?有什么限制
可以。但是,在多个类中,有且只有一个public类,且public类的类名必须与*.java的文件名相一致。
22. 简单说说你了解的类加载器。是否实现过类加载器
包含了双亲委派模型的知识。参看《深入理解JAVA虚拟机》 类加载机制 类加载器
(1)BootStrap启动:负责加载$JAVA_HOME中jre/lib/rt.jar里所有的class,由C++实现,不是ClassLoader子类
(2)ExtClassLoader扩展:负责加载java平台中扩展功能的一些jar包,包括$JAVA_HOME中jre/lib/*.jar或-Djava.ext.dirs指定目录下的jar包
(3)AppClassLoader应用程序:负责记载classpath中指定的jar包及目录中class
(4)Custom:自定义
双亲委派:防止内存中出现多份同样的字节码。通过线程上线文加载器或其他环境(如OSGI使用网状结构的类加载器)打破
(1)JDK1.2千不支持
(2)JNDI、JDBC等由启动类加载器加载,但又要调用厂商实现并部署在ClassPath下的而接口提供者(SPI)代码,超过启动类加载器作用范围,由此引入线程上下文加载器,通过java.lang.Thread的setContextClassLoader设置,创建线程时未设置,从父线程继承一个,若应用程序全局都未设置的话,默认是引用应用程序加载器,由此打破双亲委派模型。
(3)动态性:代码热部署、模块热部署等。如OSGI每个程序模块(Bundle)都有一个自己的类加载器,更换Bundle时连同类加载器一起换掉。这时类加载器更进一步发展为更复杂的网状结构。
23.解释一下什么叫AOP(面向切面编程) 参考链接
面向切面编程,处理一些具有横切性质的系统性服务,如事物管理、安全检查、缓存、对象池管理。(1)实现原理:由目标类的代理类实现。动态代理,JDK和GCLIB
(2)Spring对AOP的支持:Spring中AOP代理由Spring的IOC容器负责生成、管理,其依赖关系也由IOC容器负责管理。默认使用JDK动态代理,当需要代理的类不是代理接口的时候,Spring 自动会切换为使用CGLIB代理,也可强制使用 CGLIB。
(3)实现:使用@Aspect、@Pointcut等基于注解的配置来标注切入点和增强处理。使用Spring配置文件来定义切入点和增强点
(4)核心概念:
4.1 横切关注点:对哪些方法进行拦截,拦截后怎么处理,这些关注点称之为横切关注点
4.2 切面(aspect):类是对物体特征的抽象,切面就是对横切关注点的抽象
4.3 连接点(joinpoint):被拦截到的点,因为Spring只支持方法类型的连接点,所以在Spring中连接点指的就是被拦截到的方法,实际上连接点还可以是字段或者构造器
4.4 切入点(pointcut):对连接点进行拦截的定义
4.5 通知(advice):所谓通知指的就是指拦截到连接点之后要执行的代码,通知分为前置、后置、异常、最终、环绕通知五类
4.6 目标对象:代理的目标对象
4.7 织入(weave):将切面应用到目标对象并导致代理对象创建的过程
4.8 引入(introduction):在不修改代码的前提下,引入可以在运行期为类动态地添加一些方法或字段
(5)AOP编程:定义普通业务组件、定义切入点,一个切入点可能横切多个业务组件、定义增强处理,增强处理就是在AOP框架为普通业务组件织入的处理动作。代理对象的方法=增强处理+被代理对象
24.请简述 Servlet 的生命周期及其相关的方法
生命周期:(1)加载和实例化(2)初始化(3)请求处理(4)服务终止
方法:init()只调用一次初始化连接、资源等;service()执行实际任务;doGet();doPost;destroy()只调用一次关闭数据库连接、释放资源等。
25.请简述一下 Ajax 的原理及实现步骤
AJAX即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML)
原理: HTTP协议的异步通信
get请求
1) 创建一个XMLHttpRequest对象
2) 调用该对象的open方法
3) 如果是get请求,设置回调函数onreadystatechange = callback
4) Send
post请求
5) 创建一个XMLHttpRequest对象
6) 调用该对象的open方法
7) 调用setRequestHeader(“Content-Type”, “application/x-www-form-urlencoded”);
8) 设置回调函数onreadystatechange = callback
9) Send
26.简单描述Struts的主要功能 :略
27.什么是 N 层架构什么是 N 层架构
核心是提供可规模化特性,一方面是从服务负载上可规模化,能同时为极大规模的用户同时提供服务;另一方面是服务功能上的可规模化,可形成极大规模的软件群系统,各分系统可以共享信息、服务,形成企业级的信息高速公路。参考链接
三层(早期):表示层、领域层、基础架构层。
四层:表示层、Web服务器层、应用服务器层、数据层
28.什么是CORBA?用途是什么
公共对象请求代理结构(Common Object Request Broker Architecture),由对象管理组织(OMG)标准化。它的组成是接口定义语言(IDL)、语言绑定(binding:也译为联编)和允许应用程序间互操作的协议。
其目的为:用不同的程序设计语言书写在不同的进程中运行,为不同的操作系统开发。
用途:
(1)存取来自现行桌面应用程序的分布信息和资源;
(2)使现有业务数据和系统成为可供利用的网络资源;
(3)为某一特定业务用的定制的功能和能力来增强现行桌面工具和应用程序;
(4)改变和发展基于网络的系统以反映新的拓扑结构或新资源;
29. 什么是Java虚拟机?为什么Java被称作是“平台无关的编程语言”
Java源程序(.java)被编译器编译成字节码文件(.class)。然后字节码文件,将由java虚拟机,解释成机器码(不同平台的机器码不同)。利用机器码操作硬件和操作系统
(1) java虚拟机是执行字节码文件(.class)的虚拟机进程
(2) 因为不同的平台装有不同的JVM,它们能够将相同的.class文件,解释成不同平台所需要的机器码
30.什么是正则表达式?用途是什么?哪个包使用正则表达式来实现模式匹配
正则表达式就是用某种模式去匹配一类字符串的公式,主要用来描述字符串匹配的工具。
(1)验证、查找、替换、提取字符串。
(2)java.util.regex包,主要是Pattern和Matcher。Pattern是一个正则表达式经编译后的表现模式,一个Matcher对象是一个状态机器,它依据Pattern对象做为匹配模式对字符串展开匹配检查
31.什么是懒加载(Lazy Loading)
spring容器启动的是先不把所有的bean都加载到spring的容器中去,而是在当需要用的时候,才把这个对象实例化到容器中。
32.什么是尾递归,为什么需要尾递归
若一个函数在尾位置调用本身(或是一个尾调用本身的其他函数等),则称这种情况为尾递归,是递归的一种特殊情形。而形式上只要是最后一个return语句返回的是一个完整函数,它就是尾递归。这里注意:尾调用不一定是递归调用,但是尾递归一定是尾调用。(斐波那契数列) 参考链接
(1)从前有座山,山上有座庙,庙里有个老和尚,一天老和尚对小和尚讲故事:story() // 尾递归,进入下一个函数不再需要上一个函数的环境了,得出结果以后直接返回。
(2)从前有座山,山上有座庙,庙里有个老和尚,一天老和尚对小和尚讲故事:story(),小和尚听了,找了块豆腐撞死了 // 非尾递归,下一个函数结束以后此函数还有后续,所以必须保存本身的环境以供处理返回值。
33.什么是控制反转(Inversion of Control)与依赖注入(Dependency Injection) 参考链接
依赖注入和控制反转是对同一件事情的不同描述
控制反转(IoC/Inverse Of Control): 调用者不再创建被调用者的实例,由spring框架实现(容器创建)所以称为控制反转。
依赖注入(DI/Dependence injection) : 组件不做定位查询,只提供普通的Java方法让容器去决定依赖关系。容器全权负责的组件的装配,它会把符合依赖关系的对象通过JavaBean属性或者构造函数传递给需要的对象。通过JavaBean属性注射依赖关系的做法称为设值方法注入(Setter Injection);将依赖关系作为构造函数参数传入的做法称为构造器注入(Constructor Injection)
34.Spirng的AOP的动态代理实现机制,JDK代理和cglib代理的区别
Spirng的AOP的动态代理实现机制有两种,分别是:
1)JDK动态代理:
具体实现原理:
1、通过实现InvocationHandlet接口创建自己的调用处理器
2、通过为Proxy类指定ClassLoader对象和一组interface来创建动态代理
3、通过反射机制获取动态代理类的构造函数,其唯一参数类型就是调用处理器接口类型
4、通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数参入
JDK动态代理是面向接口的代理模式,如果被代理目标没有接口那么Spring也无能为力,
Spring通过java的反射机制生产被代理接口的新的匿名实现类,重写了其中AOP的增强方法。
2、CGLib动态代理
CGLib是一个强大、高性能的Code生产类库,可以实现运行期动态扩展java类,Spring在运行期间通过 CGlib继承要被动态代理的类,重写父类的方法,实现AOP面向切面编程呢。
两者对比:
JDK动态代理是面向接口,在创建代理实现类时比CGLib要快,创建代理速度快。
CGLib动态代理是通过字节码底层继承要代理类来实现(如果被代理类被final关键字所修饰,那么抱歉会失败),在创建代理这一块没有JDK动态代理快,但是运行速度比JDK动态代理要快。
使用注意:
如果要被代理的对象是个实现类,那么Spring会使用JDK动态代理来完成操作(Spirng默认采用JDK动态代理实现机制)
如果要被代理的对象不是个实现类那么,Spring会强制使用CGLib来实现动态代理。