一、IOC:
控制反转,利用java反射机制,只要在配置文件中配置好对象,对象的创建、管理都由spring来管理;
二、DI:
依赖注入,通过@Autowired将依赖的对象注入到本对象中,依赖的对象有容器进行管理;
三、AOP:
切面编程,通过动态代理的方式,在不修改原有代码的情况下,灵活的添加业务实现逻辑,如果日志,事物等。
四、循环依赖:
判断当前 singleton bean 是否处于创建中。bean 处于创建中,也就是说 bean 在初始化但是没有完成初始化,有一个这样的过程其实和 Spring 解决 bean 循环依赖的理念相辅相成。因为 Spring 解决 singleton bean 的核心就在于提前曝光 bean,allowEarlyReference
变量:从字面意思上面理解就是允许提前拿到引用。其实真正的意思是,是否允许从 singletonFactories
缓存中通过 #getObject()
方法,拿到对象。为什么会有这样一个字段呢?原因就在于 singletonFactories
才是 Spring 解决 singleton bean 的诀窍所在。
五、单例线程非安全:
单例其实就是所有请求公用这个对象资源,如果没有自己实现业务线程安全,那单例肯定是不安全的,要写线程安全,应该采用Prototype方式,每次请求都产生一个新的实例。
Spring Bean 支持 5 种 Scope ,分别如下:
- Singleton - 每个 Spring IoC 容器仅有一个单 Bean 实例。默认
- Prototype - 每次请求都会产生一个新的实例。
- Request - 每一次 HTTP 请求都会产生一个新的 Bean 实例,并且该 Bean 仅在当前 HTTP 请求内有效。
- Session - 每一个的 Session 都会产生一个新的 Bean 实例,同时该 Bean 仅在当前 HTTP Session 内有效。
- Application - 每一个 Web Application 都会产生一个新的 Bean ,同时该 Bean 仅在当前 Web Application 内有效。
六、AOP 有哪些实现方式?
静态代理:实现接口;
动态代理(在运行时在内存中“临时”生成 AOP 动态代理类):jdk、cglib;:建议尽量使用 JDK 的动态代理,性能上现在差不多了。jdk性能已经改进了,cglib基本没变化近些年。
-
JDK 动态代理通过反射来接收被代理的类,并且要求被代理的类必须实现一个接口。JDK动态代理的核心是 InvocationHandler 接口和 Proxy 类。
- 如果目标类没有实现接口,那么 Spring AOP 会选择使用 CGLIB 来动态代理目标类。当然,Spring 也支持配置,强制使用 CGLIB 动态代理。
CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动态的生成某个类的子类,注意,CGLIB 是通过继承的方式做的动态代理,因此如果某个类被标记为final
,那么它是无法使用 CGLIB 做动态代理的。
七、事务传播行为
(为了解决业务层方法之间互相调用的事务问题),TransactionDefinition类常量属性:
支持当前事务的情况:
-
PROPAGATION_REQUIRED: 如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。
-
PROPAGATION_SUPPORTS: 如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
-
PROPAGATION_MANDATORY: 如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。
不支持当前事务的情况:
-
PROPAGATION_REQUIRES_NEW: 创建一个新的事务,如果当前存在事务,则把当前事务挂起。
-
PROPAGATION_NOT_SUPPORTED: 以非事务方式运行,如果当前存在事务,则把当前事务挂起。
-
PROPAGATION_NEVER: 以非事务方式运行,如果当前存在事务,则抛出异常。
其他情况:
-
PROPAGATION_NESTED: 如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。