反射是什么?
是事先不需要事先知道运行的对象(写代码或编译阶段),在jvm运行时动态的加载类或调用方法/属性
反射的主要运用于哪里?
发射一般主要运用于开发各自框架
与反射相关的类有哪些?
(1)Class类,每一个类都有对应的Class对象,包含了类中的信息
(2)Field,使用,通过get()和set()来设置Field对象关联的字段
(3)Method,可以使用invoke()方法调用与Method对象关联的方法
(4)Constructor,调用其newInstance()方法创建新的对象
说说反射的优点和缺点分别有什么?
优点:
(1)提高了灵活性和程序的扩展性
(2)降低了程序的耦合性
缺点:
(1)性能开销较大
(2)安全性降低
(3)内部暴露
异常的继承关系图:
2.25
类之间的关系有哪些?
依赖、聚合、继承
对象的3个主要特性是什么?
行为、状态、标识
Spring框架是什么?
(1)包含了许多模块,如Core,Testing,Data Access,Web Servlet等
(2)Core是Spring的核心
(3)Core中包含了IOC容器、AOP、数据绑定、类型转换等一系列功能
(4)上述功能都是基于IOC和AOP实现的,所以IOC和AOP是Spring框架的核心
什么是IOC?
(1)IOC英文Inversion of Control ,是控制反转的意思
(2)是一种面向对象的编程设计思想
(3)传统模式下,我们需要自己对对象依赖关系进行管理,容易造成对象间的耦合度过高,不利于大型软件的开发和维护
(4)IOC可以帮助我们维护对象,这样可以降低对象的耦合度
什么是DI?
(1)DI是依赖注入,他是实现IOC的一种方式
(2)实现依赖注入的关键是IOC容器,IOC容器实际上是工厂
什么是AOP?
(1)AOP是对面向对象思想的一种补充,在面向对象的基础上对效率进行提升
(2)AOP实际上是将代码的共性需求提取出来(日志,权限检查)等,在不改变原来代码的基础上,通过配置文件将共性需求植入代码指定位置
Spring提供了什么样的容器?
(1)Spring提供了两种类型容器BeanFactory 和 ApplicationContext
BeanFactory的特点 :
(1)基础类型的IOC容器
(2)默认采用延迟初始化策略,只有bean在访问时才进行初始化和依赖注入操作
(3)加载内容有限,加载速度快,对于资源有限的场景,通常使用BeanFactory
ApplicationContext的特点:
(1)是在BeanFactory的基础上创建的,相比于BeanFactory还多了些功能,如:事件发布,国际化信息支持
(2)ApplicationContext与BeanFactory的的加载机制不同,其是在装配入容器后,就完成对对象的初始化和依赖注入
(3)对于一些功能丰富,资源充足的项目,通常使用ApplicationContext
BeanFactory 是什么?
(1)类的通用工厂
(2)用来管理类的实例化对象
(3)spring称这些被管理的对象成为bean
(4)是spring顶层接口,spring中有其很多实现方式,如:xmlBeanFactory、XmlBeanDefinitionReader、defaultLisableBeanFactory
(5)最常用的方法getbean(),用来获取该名称下的bean实例
依赖注入的三种方式是什么?
(1)构造方法注入
(2)setter注入
(3)接口注入,实现某个接口,设置一个方法,用来为其注入依赖对象
Spring是如何管理bean的?
Spring通过IOC容器来管理bean,通常有两种方式:配置文件,注解来知道IOC容器去管理bean,由于注解比配置文件更简单的能够管理bean,通常使用注解来管理
spring常用的注解有哪些,作用分别是什么?
@ComponentScan用于声明扫描策略,容器便可以知道要扫描哪些包下带有声明的类
@Component、@Repository、@Controller、@Service作用是一样的,但是语义不同
@Autowired、@Qualifier告诉容器为属性注入哪个bean,@Autowired按照类型匹配,同种类型有多个的情况下,使用@Qualifier按照名称进行匹配
@Scope,用来指定bean的作用域,Spring创建的bean通常为单例,也可指定作用域为“prototype”设置为多例,也可指定作用域为“request”或“session”
@PostConstruct和@PreDestory用于指定bean的生命周期,@PostConstruct在bean初始化之后执行,@PreDestory在容器销毁前执行
Bean的作用域:
singleton
prototype
request
session
globalSession
Bean的生命周期
(1)解析xml、注解配置的类,得到BeanDefinition
(2)通过BeanDefinition反射创建Bean对象
(3)进行属性的注入
(4)回调实现Aware接口的方法,如BeanNameAware
(5)执行BeanPostProcessor的初始化前方法
(6)执行init()方法
(7)执行BeanPostProcessor的初始后方法,此处会执行AOP
(8)将Bean对象装载如MAP集合中
(9)业务使用Bean对象
(10)Spring容器关闭时调用DisposableBean中的destory()方法。
Spring是如何解决循环依赖的?
(1)两个或两个以上的bean相互之间持有对方的引用->循环依赖
(2)循环依赖会导致注入出现死循环
(3)循环依赖有三种形态:1. 互相依赖:A依赖于B,B依赖于A;2. 三者依赖:A依赖于B,B依赖于C,C依赖于A;3.自我依赖,依赖于自身
(4)Spring通过设计三级缓存去解决循环依赖这个问题
(5)调用getbean()去获取一个对象实例时
(6)先从一级缓存中去找,再从二级缓存中去找
(7)一二级缓存中都没有找到,意味着这个bean还没有被实例化
(8)spring容器会去实例化这个bean,这个bean称为早期bean
(9)将这个bean放入二级缓存,同时增加一个标记,表明其是否存在循环依赖
(10)如果不存在循环依赖,则将其放入二级缓存,若存在循环依赖,则在下一次轮询的时候去赋值(@Autowired注解),将其放在一级缓存
一级缓存:存放所有成熟的bean
二级缓存:存放所有早期的bean
三级缓存:存放需要代理的bean,最终会把赋值好的bean存放到一级缓存
Spring无法解决哪些循环依赖的问题?
- 多实例的bean通过setter注入的时候
- 构造器注入的情况下无法解决循环依赖问题
- 单例的代理bean通过setter注入下
- 设置@Dependson注解下Bean不能解决
@Autowired和@Resource注解有什么区别?
-
@Autowired由Spring提供,@Resource由JDK提供
-
@Autowired默认按类型装配依赖对象,对象默认需要存在若没有则需要将required的属性值设为false,想使用按名称进行装配,则需要结合注解@Qualifier一起使用
-
@Resource可以按照类型也可以按照名字进行装配
Spring中默认提供的单例是线程安全的吗?
(1)不是,spring没有提供关于线程的安全策略
(2)对于无状态bean,即不进行除查找以外的功能,如Controller、DAO、Service等就是线程安全的
(3)对于有状态的bean,使用ThreadLocal()进行线程安全隔离
解释一下AOP中的连接点,切点,通知,切面是什么意思?
(1)连接点:类中可以被增强的方法
(2)切点:实际被增强的方法
(3)通知:增强的逻辑语句
- 前置通知
- 后置通知
- 循环通知
- 异常通知
- 最终通知
(4)切面:动作,把通知运用到切点的过程
AOP的代理方式有哪几种?
(1)JDK代理,Java提供的动态代理技术,AOP的默认代理方式,运行时创建接口的代理实例,在接口的代理实例中植入代码
(2)CGlib代理,字节码技术,通过运行时,创建子类的代理对象实例,该代理方法用在对象不存在接口时
Spring AOP不能对哪些类进行增强?
(1)没有被IOC容器管理的对象不能进行方法增强
(2)CGLIb要生成代理对象子类的实例,所以要使用该代理,类不能被final修饰
既然有没有接口都可以用CGLIB,为什么Spring还要使用JDK动态代理?
(1)JDK创建对象的所花费的时间比CGLIB的少得多
(2)所以,在单例情况下,通常使用CGLIB,而多例情况下,通常使用JDK
Spring如何管理事务?
(1)编程式事务
编程式事务,不必关心资源的获取、释放、同步,这种方式相对于声明式事务来说比较繁琐,但好在灵活
(2)声明式事务
写上注解@Transactional
List和set的区别是什么?
List:有序,可重复,允许有多个null,可以按存入的顺序输出,可以使用迭代器进行遍历,也可以使用get(数组下标)来获取元素
Set:无序,不可重复,只运行最多有一个null,可以使用迭代器进行遍历
hashcode()和equal()的区别和联系是什么?
相同点:(1)都是用来比较对象是否相同的
差异:(1)hashcode相同的两对象,却不一定相等
(2)hashcode的效率要比equal的效率搞
以hashset为例,说明hashcode的执行流程是什么?
(1)对象经过散列函数的计算,得到一个哈希码
(2)检查该哈希码下是否存在对象
(3)若不存在对象,则将对象存入该哈希码下
(4)若存在对象,则使用equal方法判断两对象是否相同
(5)相同,则舍弃该对象
(6)不相同,则再次使用散列函数得到新的哈希码,重新散列到其他位置
这样就大大减少了equal的使用次数,大大提高了效率。
要点:
(1)两对象相同,equal返回true
(2)两对象相同,hashcode一定相同
(3)hascode相同,两对象不一定相同
(4)因此,重写了equal方法,hashcode也一定要重写
(5)hascode的值是从堆上产生的独特值,因此两对象如果不重写hascode方法,则hascode的值一定不相同