1)面向对象的特性有哪些
前端
封装: 封装是指将对象的实现细节隐藏起来,而后经过公共的方法来向外暴露出该对象的功能。使用封装不只仅安全,并且能够简化操做。web
继承: 继承是面向对象实现软件复用的重要手段,当子类继承父类后,子类是一种特殊的父类,可以直接或间接得到父类里的成员。正则表达式
缺点:spring
1.
强耦合,父类变子类也得变编程
2.
破坏了封装性,实现细节对于子类都是透明的。设计模式
多态: 同一个行为具备多个不一样表现形式或形态的能力。数组
条件:缓存
1.
继承安全
2.
重写session
3.
向上转型
好处:能够屏蔽不一样子类对象之间的实现差别。
抽象: 从特定的角度出发,从已经存在的一些事物中抽取咱们所关注的 特性,行为,从而造成一个新的事物的思惟过程。是一种从复杂到简洁的思惟方式。
2)Java中的覆盖和重载
覆盖: 是指子类对父类方法的一种重写。
限制:
1.
只能比父类抛出更少的异常
2.
访问权限不能比父类的小
3.
被覆盖的方法不能是private 的。
重载: 表示同一个类中能够有多个名称相同的方法。
条件:1.
参数类型不一样 2.
参数个数不一样 3.
参数顺序不一样
注意:函数的返回值不一样不能构成重载
3)抽象类和接口的区别
出发角度 | 抽象类 | 接口 |
---|---|---|
默认的实现方法 | 有默认的方法实现 | 所有都是抽象的,不存在方法的实现 |
构造器 | 能够有构造器 | 不能有构造器 |
访问修饰符 | 能够有public、protected和default这些修饰符 | 默认是public,不可使用其余修饰符 |
继承方式 | 能够继承一个类和实现多个接口 | 能够继承一个或多个接口 |
添加新方法 | 能够提供默认的实现,而不须要修改原有的代码 | 添加方法后,必须修改实现该接口类中的方法 |
4)Java 和 C++ 的区别
都是面向对象的语言
Java不提供指针来直接访问内存,比较安全
Java是单继承的,C++能够是多继承的
Java有自动内存管理机制
5)Java 是值传递仍是引用传递
Java内都是值传递
值传递: 是针对基本类型变量,传递的是该变量的一个副本,而改变副本不会改变原有值的改变。
引用传递: 是针对对象型变量,传递的是该对象的引用地址,修改会引发原有对象的改变。
6)JDK、JRE、JVM
JDK: 是 Java开发工具包,是Java开发环境的核心组件,并提供编译、调试和运行一个Java程序所须要的全部工具,能够执行文件和二进制文件,是一个平台特定的软件。
JRE: 是Java 运行时环境,是JVM 的实施实现,提供了运行Java 程序的平台,JRE 包含了 JVM,可是不包含 Java编译器/调试器之类的开发工具。
JVM: 是Java虚拟机,当咱们运行一个程序时,JVM负责将字节码转换为特定机器代码,JVM提供了内存管理/垃圾回收和安全机制等。
7)Integer
第一个和第二个的区别在于 Integer中存在缓存机制,JVM启动初期会缓存 -128~127 这个区间里面的全部数字,所以第一个位 true,第二个为false。第三个为 false 的缘由在于使用了 new 关键字开辟了新空间 , i 和 j 两个对象分别指向堆中的两块内存空间。8)String
状况1: 最多建立一个String 对象,最少不建立String 对象,若是常量池中存在"test",那么str1会直接引用,此时不会建立对象,不然会在常量池中建立 "test" 内存空间,而后再引用。
状况2: 最多建立两个String 对象,至少建立一个String 对象。new 关键字绝对会在堆空间中建立一个新的内存区域,因此至少会建立一个String对象。
9)Java 有没有 goto
goto 是 Java 中的保留字,在目前版本的 Java 中没有使用。10)final 的做用
被 final 修饰的类不可被继承
被 final 修饰的方法不可被重写
被 final 修饰的变量不能够被改变
被final 修饰的方法,JVM会尝试与其关联,调高运行效率
11)final、finally和finalize的区别
final: 能够修饰类、变量和方法。修饰类表示该类不能被继承,修饰方法表示该方法不能被重写,修饰变量表示该变量不可变。
finally: 通常做用在try-catch代码块中,在处理异常的时候,一般咱们将必定要执行的代码方法放在finally代码块中,表示无论是否出现异常,该代码块都会执行,通常用来存放一些关闭资源的代码。
finalize: 是一个属于Object 类的方法,Object是全部类的父类,Java中容许使用finalize()方法在垃圾收集器将对象从内存中清除出去以前作必要的清理工做。
12)Throwable
Throwable 是Java语言中全部错误与异常的超类。包含两个子类:
Error(错误)
程序中没法处理的错误,表示运行应用程序中出现了严重的错误
Exception(异常)
程序自己能够捕获而且能够处理的异常
运行时异常
Java编译器不会检查它,也就是说,当程序中可能出现这类异常时,假若既“没有经过throws声明抛出它”,也“没有用try-catch语句捕获它”,仍是会经过编译。
编译时异常
Java编译器会检查它,若是程序中出现此类异常,要么经过throws进行声明抛出,要么经过try-catch进行捕获处理,不然不能经过编译。
13)常见的运行时异常
NullPointException(空指针异常)
ClassNotCastException(类型转换异常)
IllegalArgumentException(非法参数异常)
IndexOutOfBoundException(下标越界异常)
ArrayStoreException(数组存储空间不够异常)
14)try-catch-finally中哪一个部分能够省略
catch能够省略
“ 集合这方面能够问的实在太多了,这一块可要好好把握住!
1)集合的种类
Map接口和Collection接口是全部集合框架的父接口
Collection:
List接口
ArrayList
LinkedList
Stack
Vector
Set接口
HashSet
TreeSet
LinkedHashSet
Map:
HashMap
TreeMap
Hashtable
ConcurrentHashMap
Properties
2)List 和 Set 的区别
List: 有序(元素存入集合的顺序和取出的顺序是一致的),能够重复,能够插入多个null元素,元素都有索引。
Set: 无序(元素存入集合的顺序和取出的顺序有可能不一致),不能够重复,只容许存入一个null元素(元素的惟一性)
扩展:
HashSet的底层实现
HashSet实现Set接口,其实是一个HashMap 实例支持。
它不保证set 的迭代顺序,特别是它不保证该顺序恒久不变,此类容许使用null元素。
元素都存到HashMap键值对的Key上面,而Value是一个统一的值。
3)Array 和 ArrayList 的区别
数组是固定长度的,集合是可变长度的
数组能够存储基本数据类型也能够引用数据类型,集合只能存储引用数据类型
数组存储的元素必须是用一个数据类型,集合存储的对象能够是不一样数据类型
4)HashMap 和 HashTable的区别
HashMap 继承自 AbstractMap 类;而 Hashtable 继承自Dictionary 类
HashTable 是线程安全的,直接在方法上锁,并发度很低,虽多同时容许一个线程访问。相反HashMap效率比较高,但线程不安全。
HashTable 是不容许键或值为null的,HashMap的键值都能够是null,缘由在于HashTable使用的是安全失败机制(fail-fast),若是键或值为空会直接抛出异常;而HashMap在计算hash值的时候作了特殊处理若是键为空则赋值为0
HashTable初始化的容量为11,HashMap初始化的容量为16。二者的负载因子都是0.75
HashTable的扩容机制是2n+1, HashMap的扩容机制是 2n
扩展:
何为fail-fast
fail-fast 是一种错误检测机制,并发状况下多个线程对集合的结构进行修改是就会触发 fail-fast机制,抛出ConcurrentModificationException异常。
原理: 迭代器在遍历时直接访问集合中的内容,而且在遍历过程当中使用一个 modCount 变量,遍历期间集合若是发生变化就会改变modCount的值,等下一个hasNext()/next()的时候就会比对modCount != expectedModCount 这个判断条件,若是为true则会抛出异常,终止遍历,不然就返回遍历。
5)聊聊HashMap
Java 1.8以前HashMap 是由 数组+链表 组合构成的数据结构。数组的长度是有限的,所以哈希会存在碰撞的状况,那么就会造成链表。若是链表长度过长就会形成查询效率过慢,时间复杂度为O(n)。
Java 1.8 以前采用的是 头插法,就是说新插入的值的时候,原来的值就会日后推一位,让新值放在头部位置,这样作的缘由是由于后插入的值查找的可能性会更大一点,提升查找的效率。可是这样就会形成一个问题,在同一个位置上新元素总会被放在链表的头部位置,若是多线程put的状况下,就会改变数据的引用结构,那么就会形成环形链表,发生死循环!
Java 1.8 以后数据结构就变成了 数组+链表+红黑树。当链表长度超过阈值(8)时,将链表转换为红黑树,这样大大减小了查找时间。
Java 1.8 以后采用的是 尾插法,这样扩容转移后先后链表顺序不变,保持以前节点的引用关系,就不会出现死循环的状况。
6)HashMap扩容是怎样扩容的
当HashMap中的元素个数超过数组大小(数组总大小length,不是数组中个数size)*loadFactor时,就会进行数组扩容,loadFactor的默认值为0.75.HashMap不是无限扩容的,当达到了实现预约的MAXIMUM_CAPACITY,就再也不进行扩容。
7)HashMap 的长度为何都是2的N次幂的大小
不会形成浪费,不随机分布问题。首先算得key得hashcode值,而后跟数组的长度-1作一次“与”运算(&)。若是length不为2的幂,那么length-1的2进制就会变成1110,在h为随机数的状况下,和1110作&操作,尾数永远是0,碰撞的概率大。
提升性能。length为2的幂,那么扩容后元素新的位置就不须要从新计算,只须要看看当前值的hash&(扩容后的容量-1)是1仍是0就行了,是0的话索引没变,是1的话索引变成“原索引+oldCap”
8)HashMap存在线程安全问题,那是怎么处理这种状况的?
使用 Collections.synchronizedMap(new HashMap<>())
HashTable
ConcurrentHashMap
出于线程并发度的考虑,通常会选择ConcurrentHashMap,他的性能和效率都明显高于前二者
9)ConcurrentHashMap
Java 1.8 以前ConcurrentHashMap底层使用的是 数组+链表
由图得知,底层的数据结构是由 Segment 数组,HashEntry组成,和HashMap同样,仍然是数据加链表的形式。HashEntry 和 HashMap 差很少,不一样点是使用了 Volatile 修饰了 Value,在访问数据的时候不用加锁,只能保证了弱一致性。
ConcurrentHashMap 采用了 分段锁 技术,其中 Segment 继承于 ReentrantLock。不会像HashTable 那样直接在方法上加锁,太简单粗暴了…,若是容量大小是16,那个他的并发度就是16,至关于效率提升了16倍。
Java 1.8以后 ConcurrentHashMap 采用的是 Node + CAS + Synchronized 来保证并发安全性的,而且也引入了红黑树。跟HashMap的实现是同样的,当链表长度大于 7 的时候转换为红黑数。
ConcurrentHashMap 进行 put 的步骤:
若是相应位置的Node尚未初始化,则调用CAS插入相应的数据
若是相应位置的Node不为空,则对该节点加synchronized锁,遍历链表更新节点或插入新节点
若是该节点是TreeBin类型的节点,说明是红黑树结构,则经过putTreeVal方法往红黑树中插入节点;若是binCount不为0,说明put操做对数据产生了影响,若是当前链表的个数达到8个,则经过treeifyBin方法转化为红黑树,若是oldVal不为空,说明是一次更新操做,没有对元素个数产生影响,则直接返回旧值
10)迭代器 Iterator
Iterator 接口提供遍历任何 Collection 的接口。咱们能够从一个 Collection 中使用迭代器方法来获取迭代器实例。迭代器取代了 Java 集合框架中的 Enumeration,迭代器容许调用者在迭代过程当中移除元素。11)Iterator 和 ListIterator 的区别
Iterator 能够遍历 Set 和 List 集合,而 ListIterator 只能遍历 List。
Iterator 只能单向遍历,而 ListIterator 能够双向遍历(向前/后遍历)。
ListIterator 实现 Iterator 接口,而后添加了一些额外的功能,好比添加一个元素、替换一个元素、获取前面或后面元素的索引位置。
12)实现数组和 List 之间的转换
数组转 List:使用 Arrays. asList(array)
List 转数组:使用 List 自带的 toArray()
13)ArrayList 和 LinkedList 的区别
ArrayList 底层是动态数组数据结构,LinkedList 底层是双向链表数据结构。
ArrayList 比 LinkedList 在随机访问的时候效率要高,由于 LinkedList 是线性的数据存储方式,因此须要移动指针从前日后依次查找。
在非首尾的增长和删除操做,LinkedList 要比 ArrayList 效率要高,由于 ArrayList 增删操做要影响数组内的其余数据的下标。
LinkedList 比 ArrayList 更占内存,由于 LinkedList 的节点除了存储数据,还存储了两个引用,一个指向前一个元素,一个指向后一个元素。
14)ArrayList 和 Vector的区别
Vector 使用了 Synchronized 来实现线程同步,是线程安全的,而 ArrayList 是非线程安全的。
ArrayList 在性能方面要优于 Vector。
ArrayList 和 Vector 都会根据实际的须要动态的调整容量,只不过在 Vector 扩容每次会增长 1 倍,而 ArrayList 只会增长 50%。
15)hashCode()与equals()的相关规定
两个对象相等,那么他们的hashCode也必定是相同的
两个对象相等,那么equals方法返回的是true
两个对象有相同的hashCode值,那他们也不必定相等
若是重写了equals,那么它们的hashCode方法也必须被重写
16)极高并发下HashTable和ConcurrentHashMap哪一个性能更好,为何
HashTable使用一把锁处理并发问题,当有多个线程访问时,须要多个线程竞争一把锁,致使阻塞
ConcurrentHashMap则使用分段,至关于把一个HashMap分红多个,而后每一个部分分配一把锁,这样就能够支持多线程访问
17)HashMap在高并发下若是没有处理线程安全会有怎样的安全隐患
多线程put时可能会致使get无限循环,具体表现为CPU使用率100%
多线程put时可能致使元素丢失
18)BlockingQueue是什么
BlockingQueue是JUC包下的,是一个阻塞队列,在进行检索或移除一个元素的时候,它会等待队列变为非空;当在添加一个元素时,它会等待队列中的可用空间。BlockingQueue接口是Java集合框架的一部分,主要用于实现生产者-消费者模式。咱们不须要担忧等待生产者有可用的空间,或消费者有可用的对象,由于它都在BlockingQueue的实现类中被处理了。Java提供了集中BlockingQueue的实现,好比ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue、SynchronousQueue等。
19)ArrayList在循环过程当中删除,会不会出问题,为何。
会出现问题。由于删除是利用复制和移动的方式,若是集合的值为{"11","22","22"},要删除22的话结果为{"11","22"},第三个22就会前移,这样能循环过程当中,就访问不到第三个22。
解决:
反向删除
利用迭代器删除(多线程会报错)
1)什么是Spring
是Java企业级应用的开源开发框架
简化Java企业级应用开发,提升开发效率
基于POJO为基础的编程模型促进良好的编程习惯
2)Spring的优缺点
优势:
轻量级: Spring从大小和透明度来讲都是轻量级的
控制反转(IOC): Spring经过控制反转实现了松散耦合,对象给出它们的依赖,而不是经过建立或查找依赖的对象
面向切面(AOP): 支持面向切面的编程,实现应用业务逻辑和系统服务相分开
容器: Spring包含和管理应用中对象的生命周期和配置
声明式事务管理: 只须要经过配置就能够对事务进行管理,无需手动编程
缺点:
Spring 依赖反射,会影响性能
使用门槛升高,入门Spring须要较长的时间
3)Spring的核心模块
Spring core
Spring context
Spring bean
Spring orm
Spring aop
Spring web
Spring jdbc
Spring test
4)什么是Spring配置文件
Spring配置文件是XML 文件。该文件主要包含类信息,它描述了这些类是如何配置以及相互引入的。可是XML配置文件冗长且更加干净,若是没有正确规划和编写,那么在大项目中管理会变得很是困难。
5)Spring框架中用到的设计模式
工厂模式: BeanFactory 就是简单工厂模式的体现,用来建立对象的示例
单例模式: Bean默认为单例模式
代理模式: Spring的AOP功能用到了JDK的动态代理和CGLIB字节码生成技术
模板方法: 用来解决代码重复问题。好比RestTemplate,JmsTemplate,JpaTemplate
观察者模式: 当一个对象的状态发生改变时,全部依赖于它的对象都会获得通知并更新
6)IOC是什么
IOC(控制反转),它把传统上由程序代码直接操控的对象的调用权交给容器,经过容器来实现对象组件的装配和管理。所谓“控制反转”概念就是对组件对象控制权的转移,从程序代码自己转移到了外部容器。Spring IOC负责建立对象,管理对象(经过依赖注入(DI)装配对象,配置对象,而且管理这些对象的整个生命周期)
7)IOC的优势
IOC 或 依赖注入把应用的代码量降到最低。
它使应用容易测试,单元测试再也不须要单例和JNDI查找机制。
最小的代价和最小的侵入性使松散耦合得以实现。
IOC容器支持加载服务时的饿汉式初始化和懒加载。
8)动态代理的两种方式以及区别
JDK动态代理: 利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。若是被代理的类没有实现接口则没法实现。
CGlib动态代理: 针对类实现代理,对指定的类生成一个子类,并覆盖其中的方法,这种经过继承类的实现方式,不能代理final修饰的类。
jdk动态代理的方式建立代理对象效率较高,执行效率较低,cglib建立效率较低,执行效率高
9)能够经过多少种方法完成依赖注入
构造函数注入
setter 注入
接口注入
构造函数注入 | setter注入 |
---|---|
没有部分注入 | 有部分注入 |
不会覆盖setter属性 | 会覆盖setter属性 |
任意修改都会建立一个新实例 | 任意修改不会建立一个新实例 |
适用于设置不少属性 | 适用于设置少许属性 |
10)BeanFactory 和 ApplicationContext 的区别
BeanFactory | ApplicationContext |
---|---|
懒加载 | 即时加载 |
不支持国际化 | 支持国际化 |
不支持基于依赖的注解 | 支持基于依赖的注解 |
11)ApplicationContext一般的实现是什么
FileSystemXmlApplicationContext
ClassPathXmlApplicationContext
WebXmlApplicationContext
12)Spring 支持的做用域
singleton: bean在每一个Spring ioc 容器中只有一个实例。
prototype: 一个bean的定义能够有多个实例。
request: 每次http请求都会建立一个bean,该做用域仅在基于web的Spring ApplicationContext情形下有效。
session: 在一个HTTP Session中,一个bean定义对应一个实例。该做用域仅在基于web的Spring ApplicationContext情形下有效。
global-session: 在一个全局的HTTP Session中,一个bean定义对应一个实例。该做用域仅在基于web的Spring ApplicationContext情形下有效。
13)spring 自动装配 bean 有哪些方式
no: 默认的方式是不进行自动装配的,经过手工设置ref属性来进行装配bean
byName 经过bean的名称进行自动装配,若是一个bean的 property 与另外一bean 的name 相同,就进行自动装配
byType: 经过参数的数据类型进行自动装配
constructor: 利用构造函数进行装配,而且构造函数的参数经过byType进行装配
autodetect: 自动探测,若是有构造方法,经过 construct的方式自动装配,不然使用 byType的方式自动装配
14)怎样开启注解装配
在Spring配置文件中配置 <context:annotation-config/>
元素
15)@Autowired 和 @Resource 的区别
@Autowired: 可用于构造函数、成员变量、Setter方法。默认是按照类型装配注入的,默认状况下它要求依赖对象必须存在(能够设置它required属性为false)
@Resource: 默认是按照名称来装配注入的,只有当找不到与名称匹配的bean才会按照类型来装配注入
16)spring 事务实现方式有哪些
编程式事务管理: 你能够经过编程的方式管理事务,给你带来极大的灵活性,可是难维护。
声明式事务管理: 你能够将业务代码和事务管理分离,你只需用注解和XML配置来管理事务。
17)Spring的事务传播行为
REQUIRED: 支持当前事务,当前存在事务就加入该事务,若是当前没有事务就建立一个事务
SUPPORTS: 支持当前事务,当前存在事务就加入该事务,若是当前没有事务就以非事务执行
MANDATORY: 支持当前事务,当前存在事务就加入该事务,若是当前没有事务就抛出异常
REQUIRES_NEW: 新建事务,不管当前有没有存在事务都会建立新事务
NOT_SUPPORTED: 以非事务方式执行,若是当前存在事务就把当前事务挂起
NEVER: 以非事务方式执行,若是当前存在事务就抛出异常
NESTED: 若是当前存在事务,则在嵌套事务内执行,若是当前没有事务,则按REQUIRED属性执行
18)spring 的事务隔离
READ_UNCOMMITTED: 未提交读,最低隔离级别,事务未提交前,就可被其余事务读取(会出现幻读、脏读、不可重复读)
READ_COMMITTED: 提交读,一个事务提交后才能被其余事务读取到(会形成幻读、不可重复读),SQL Server的默认级别
REPEATABLE_READ: 可重复读,保证屡次读取同一个数据时,其值都和事务开始时候的内容是一致的,禁止读取别的事务未提交的数据(会形成幻读),MySQL的默认级别
SERIALIZABLE: 序列化,代价最高最可靠的隔离级别,该隔离级别能防止脏读,不可重复读,幻读
脏读:
表示一个事务可以读取另外一个事务中还未提交的数据,好比:某个事务尝试插入记录A,此时该事务还未提交,而后另外一个事务尝试读取到了记录A不可重复读:
是指一个事务内,屡次读同一个数据,可是读出来的结果是不同的幻读:
指同一个事务内屡次查询返回的结果集不同,好比:另一个事务新增或删除第一个事务结果集里面的数据,同一个记录的数据内容别修改了,全部数据行的记录就变多或者变少了。
不可重复读通常是在修改数据的状况下,幻读通常是新增或者删除的状况下
19)Spring AOP and AspectJ AOP 有什么区别
Spring AOP 是为动态代理,AspectJ是为静态代理
Spring AOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改字节码,而是每次运行时在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的所有方法,而且在特定的切点作了加强处理,并回调原对象的方法。
AspectJ是静态代理的加强,所谓静态代理,就是AOP框架会在编译阶段生成AOP代理类,所以也称为编译时加强,他会在编译阶段将AspectJ(切面)织入到Java字节码中,运行的时候就是加强以后的AOP对象。
20)Spring AOP里面的几个名词
切面(Aspect): 切面是通知和切点的结合。通知和切点共同定义了切面的所有内容。在Spring AOP中,切面可使用通用类(基于模式的风格) 或者在普通类中以 @AspectJ 注解来实现。
链接点(Join point): 指方法,在Spring AOP中,一个链接点 老是 表明一个方法的执行。应用可能有数以千计的时机应用通知。这些时机被称为链接点。链接点是在应用执行过程当中可以插入切面的一个点。这个点能够是调用方法时、抛出异常时、甚至修改一个字段时。切面代码能够利用这些点插入到应用的正常流程之中,并添加新的行为。
通知(Advice): 在AOP术语中,切面的工做被称为通知。
切入点(Pointcut): 切点的定义会匹配通知所要织入的一个或多个链接点。咱们一般使用明确的类和方法名称,或是利用正则表达式定义所匹配的类和方法名称来指定这些切点。
引入(Introduction): 引入容许咱们向现有类添加新方法或属性。
目标对象(Target Object): 被一个或者多个切面(aspect)所通知(advise)的对象。它一般是一个代理对象。也有人把它叫作 被通知(adviced) 对象。既然Spring AOP是经过运行时代理实现的,这个对象永远是一个 被代理(proxied) 对象。
织入(Weaving): 织入是把切面应用到目标对象并建立新的代理对象的过程。在目标对象的生命周期里有多少个点能够进行织入:
编译期:切面在目标类编译时被织入。AspectJ的织入编译器是以这种方式织入切面的。
类加载期:切面在目标类加载到JVM时被织入。须要特殊的类加载器,它能够在目标类被引入应用以前加强该目标类的字节码。AspectJ5的加载时织入就支持以这种方式织入切面。
运行期:切面在应用运行的某个时刻被织入。通常状况下,在织入切面时,AOP容器会为目标对象动态地建立一个代理对象。SpringAOP就是以这种方式织入切面。
21)Spring通知有哪些类型
前置通知(Before): 在目标方法被调用以前调用通知功能;
后置通知(After): 在目标方法完成以后调用通知,此时不会关心方法的输出是什么;
返回通知(After-returning ): 在目标方法成功执行以后调用通知;
异常通知(After-throwing): 在目标方法抛出异常后调用通知;
环绕通知(Around): 通知包裹了被通知的方法,在被通知的方法调用以前和调用以后执行自定义的行为。
22)spring bean 容器的生命周期是什么样的
Spring 容器根据配置中的 bean 定义中实例化 bean。
Spring 使用依赖注入填充全部属性,如 bean 中所定义的配置。
若是 bean 实现 BeanNameAware 接口,则工厂经过传递 bean 的 ID 来调用 setBeanName()。
若是 bean 实现 BeanFactoryAware 接口,工厂经过传递自身的实例来调用 setBeanFactory()。
若是存在与 bean 关联的任何 BeanPostProcessors,则调用 preProcessBeforeInitialization() 方法。
若是为 bean 指定了 init 方法(
的 init-method 属性),那么将调用它。最后,若是存在与 bean 关联的任何 BeanPostProcessors,则将调用 postProcessAfterInitialization() 方法。
若是 bean 实现 DisposableBean 接口,当 spring 容器关闭时,会调用 destory()。
若是为 bean 指定了 destroy 方法(
的 destroy-method 属性),那么将调用它。23) DispatcherServlet 的工做流程
用户发请求-->DispatcherServlet,前端控制器收到请求后本身不进行处理,而是委托给其余的解析器进行处理,做为统一访问点,进行全局的流程控制。
DispatcherServlet-->HandlerMapping,HandlerMapping将会把请求映射为HandlerExecutionChain对象(包含一个Handler处理器,多个HandlerInterceptor拦截器)。
DispatcherServlet-->HandlerAdapter,HandlerAdapter将会把处理器包装为适配器,从而支持多种类型的处理器。
HandlerAdapter-->处理器功能处理方法的调用,HandlerAdapter将会根据适配的结果调用真正的处理器的功能处理方法,完成功能处理,并返回一个ModelAndView对象(包含模型数据,逻辑视图名)
ModelAndView的逻辑视图名-->ViewResolver,ViewResoler将把逻辑视图名解析为具体的View。
View-->渲染,View会根据传进来的Model模型数据进行渲染,此处的Model实际是一个Map数据结构
返回控制权给DispatcherServlet,由DispatcherServlet返回响应给用户。