没有IOC 之前:我们需要一个对象,都是我们自己去new 一个依赖对象。 有了IOC 之后: 我们将创建对象的权益交给了IOC 容器,由容器来控制对象的创建和生命周期。对象只是被动的接受依赖对象。
控制反转其实是一种设计思想。没有控制反转,我们需要一个对象,我们就自己去NEW ,导致代码之间的高度耦合。有了控制反转,由容器来控制对象的依赖注入,代码之间松散耦合。
参考: blog.csdn.net/qq_42709262…
IOC 和DI 主要是通过反射机制完成的。
@Override public void refresh() throws BeansException, IllegalStateException { // 来个锁,不然 refresh() 还没结束,你又来个启动或销毁容器的操作,那不就乱套了嘛 synchronized (this.startupShutdownMonitor) { // 准备工作 // 1、记录下容器的启动时间 // 2、标记“已启动”状态 // 3、处理配置文件中的占位符 prepareRefresh(); // 生成BeanFactory // 1、生成 BeanFactory // 2、解析配置文件,生成BeanDefinition, 注册到BeanFactory // 此时,Bean 还未初始化,只是配置信息提取出来了。BeanDefinition 的保存格式 // beanName-> beanDefinition 的 map ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 1、设置 BeanFactory 的类加载器,用于BeanFactory 加载类; // 2、添加一个 BeanPostProcessor // 3、对ApplicationContext 继承的对象进行赋值 // 4、手动注册几个特殊的 bean,如environment、systemProperties、systemEnvironment // 这块待会会展开说 prepareBeanFactory(beanFactory); try { // 【这里需要知道 BeanFactoryPostProcessor 这个知识点,Bean 如果实现了此接口, // 那么在容器初始化以后,Spring 会负责调用里面的 postProcessBeanFactory 方法。】 // 这里是提供给子类的扩展点,到这里的时候,所有的 Bean 都加载、注册完成了,但是都还没有初始化 // 具体的子类可以在这步的时候添加一些特殊的 BeanFactoryPostProcessor 的实现类或做点什么事 postProcessBeanFactory(beanFactory); // 调用 BeanFactoryPostProcessor 各个实现类的 postProcessBeanFactory(factory) 回调方法 invokeBeanFactoryPostProcessors(beanFactory); // 注册 BeanPostProcessor 的实现类,注意看和 BeanFactoryPostProcessor 的区别 // 此接口两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization // 两个方法分别在 Bean 初始化之前和初始化之后得到执行。这里仅仅是注册,之后会看到回调这两方法的时机 registerBeanPostProcessors(beanFactory); // 初始化当前 ApplicationContext 的 MessageSource,国际化这里就不展开说了,不然没完没了了 initMessageSource(); // 初始化当前 ApplicationContext 的事件广播器,这里也不展开了 initApplicationEventMulticaster(); // 从方法名就可以知道,典型的模板方法(钩子方法),不展开说 // 具体的子类可以在这里初始化一些特殊的 Bean(在初始化 singleton beans 之前) onRefresh(); // 注册事件监听器,监听器需要实现 ApplicationListener 接口。这也不是我们的重点,过 registerListeners(); // 重点,重点,重点 // 初始化所有的 singleton beans //(lazy-init 的除外) finishBeanFactoryInitialization(beanFactory); // 最后,广播事件,ApplicationContext 初始化完成,不展开 finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. // 销毁已经初始化的 singleton 的 Beans,以免有些 bean 会一直占用资源 destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // 把异常往外抛 throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); } } 复制代码
参考: yikun.github.io/2015/05/29/… javadoop.com/post/spring…
加载XML——创建BeanFactory ——读取Resource —— 解析BeanDefinition ——注册到BeanFactory ——初始化Bean ——创建Bean 实例 —— 注入Property
静态代理、JDK动态代理、CGLIB动态代理。
静态代理:代理类实现被代理类的接口,同时与被代理类是组合关系。 JDK动态代理:代理类可代理任意类的任意方法,但是,任意类必须要实现某个接口。 CGLIB动态代理:CGlib是一个字节码增强库,为AOP等提供了底层支持。
AOP:即面向切面编程,AOP可以分离系统的业务逻辑和系统服务。
参考: www.cnblogs.com/puyangsky/p… juejin.im/post/5aa781…
懒加载:spring 默认的是非懒加载,即在容器初始化时候初始化;懒加载即用户向容器第一次索要bean时进行初始化。
spring依赖注入时,使用了双重判断加锁的单例模式。首先从缓存中获取bean实例,如果为null,对缓存map加锁,然后再从缓存中获取bean,如果继续为null,就创建一个bean。这样双重判断,能够避免在加锁的瞬间,有其他依赖注入引发bean实例的创建,从而造成重复创建的结果。
参考: www.cnblogs.com/chengxuyuan…
TransactionDefinition.ISOLATION_DEFAULT: 使用后端数据库默认的隔离级别,Mysql 默认采用的 REPEATABLE_READ隔离级别 Oracle 默认采用的 READ_COMMITTED隔离级别. TransactionDefinition.ISOLATION_READ_UNCOMMITTED: 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读 TransactionDefinition.ISOLATION_READ_COMMITTED: 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生 TransactionDefinition.ISOLATION_REPEATABLE_READ: 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。 TransactionDefinition.ISOLATION_SERIALIZABLE: 最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。
支持当前事务的情况:
TransactionDefinition.PROPAGATION_REQUIRED: 如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。 TransactionDefinition.PROPAGATION_SUPPORTS: 如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。 TransactionDefinition.PROPAGATION_MANDATORY: 如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。(mandatory:强制性)
不支持当前事务的情况:
TransactionDefinition.PROPAGATION_REQUIRES_NEW: 创建一个新的事务,如果当前存在事务,则把当前事务挂起。 TransactionDefinition.PROPAGATION_NOT_SUPPORTED: 以非事务方式运行,如果当前存在事务,则把当前事务挂起。 TransactionDefinition.PROPAGATION_NEVER: 以非事务方式运行,如果当前存在事务,则抛出异常。
其他情况:
TransactionDefinition.PROPAGATION_NESTED: 如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。
1、基于 TransactionInterceptor 的声明式事务: Spring 声明式事务的基础,通常也不建议使用这种方式,但是与前面一样,了解这种方式对理解 Spring 声明式事务有很大作用。
2、基于 TransactionProxyFactoryBean 的声明式事务: 第一种方式的改进版本,简化的配置文件的书写,这是 Spring 早期推荐的声明式事务管理方式,但是在 Spring 2.0 中已经不推荐了。
3、基于< tx> 和< aop>命名空间的声明式事务管理: 目前推荐的方式,其最大特点是与 Spring AOP 结合紧密,可以充分利用切点表达式的强大支持,使得管理事务更加灵活。
4、基于 @Transactional 的全注解方式: 将声明式事务管理简化到了极致。开发人员只需在配置文件中加上一行启用相关后处理 Bean 的配置,然后在需要实施事务管理的方法或者类上使用 @Transactional 指定事务规则即可实现事务管理,而且功能也不必其他方式逊色。
参考: juejin.im/post/5b010f…