spring|Spring 原理

Spring基本概念 Spring 特点
sring是一个全面的、企业应用一站式解决,贯穿表现层、业务层、持久层,能够与其他框架无缝衔接整合。

  • 轻量 :从大小与开销两方面而言Spring都是轻量级的,完整的spring框架可以在一个大小只有1M多的JAR文件里面发布,并且spring所需的处理开销也是微不足道的
  • 控制反转:spring通过一种被称作控制反转的IOC的技术促进低耦合,当应用了IOC,一个对象依赖的其他对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找。
  • 面向切片 spring支持面向切片的变成,并且把应用业务逻辑和系统服务分开
  • 容器:spring包含并管理应用对象的配置和生命周期,在这个意义上是一个容器,你可以配置每个bean如何被创建–基于一个可配置原型,bean可以创建一个单独的实例或者每次都声称一个新的实例。
  • 框架 spring可以讲简单的组件配置,组合成复杂的应用
  • 在spring中应用对象被声明式组合在XML文件中,spring也提供了很多基础功能(事务管理、持久框架集成等),将应用逻辑的开发留给开发者。
Spring常用注解
bean注入与装配的方式有很多种,可以通过xml,get/set方式,构造函数或者注解。简单易用的方式就是使用spring的注解,spring提供了大量的注解方式。
常用注解:@Controller,@RestController,@Component,@Repository@Service
@Responsebody @RequestMapping @Autowired @PathVariable @requestParam @RequestHeader @ModelAttribute @SessionAttributes @Valid
Spring 第三方结合
权限:shiro
缓存:redis/enchace
持久层框架:Hibernate/Mybatis
Spring IOC原理
概念:spring通过配置文件描述bean以及bean之间的依赖关系,利用java语言的反射功能实例化Bean,并建立bean之间的依赖关系。spring的IOC容器在完成这些底层工作的基础上,还提供了Bean实例缓存、生命周期管理、Bean实例代理、事件发布、资源装载等高级服务
spring 容器高层视图: Spring启动时候读区应用程序提供的Bean配置信息,并在spring容器中生成一份Bean配置注册表,然后根据这张注册表实例化Bean,装配好Bean之间的依赖关系,为上层应用提供准备就绪的运行环境。其中Bean缓存池为HashMap实现。
IOC容器实现
BeanFactory–框架基础设施 BeanFactory 是spring框架的基础设施,面向spring本身;AppllicationContext面向使用Spring框架的开发者,几乎所有的应用场合我们都直接使用ApplicationContext而非底层的BeanFactory
BeanDefinitionRegistry 注册表 Spring配置文件中的每一个节点元素在Spring容器里面都通过一个BeanDefinition对象表示,它描述了Bean的配置信息,而BeanDefinitionRegistry接口提供了向容器手工注册BeanDefinition对象的方法
BeanFactory 顶层接口 位于类结构树的顶端,它的最主要方式就是getBean(String beanName),该方法从容器中返回特定名称的Bean,BeanFactory的功能通过其他接口得到不断的扩展
ListableBeanFactory 该接口定义了访问容器中的Bean基本信息的若干方法,如查看Bean的个数,获取某一类型Bean的配置名,查看容器中是否包括某一bean等方法:
HierarchicalBeanFactory 父子级联 父子级联IOC容器的接口,子容器可以通过接口方法访问父容器;通过HierarchicalBeanFactory接口,Spring的ioc容器可以建立父子层级关系的容器体系,子容器可以访问父容器中的bean,但父容器不能访问子容器中的bean。spring使用父子容器实现很多功能,比如在spring mvc中,展现层bean位于一个子容器内,而业务层和持久层的bean位于父容器中。这样,展现层bean就可以饮用业务层和持久层bean,而业务层和持久层的bean看不到展现层的bean
ConfigurationBeanFactory 是一个重要的接口,增强了IOC容器的可定制性,定义设置了类装载器、属性编辑器、容器初始化后处理器等方法:
AutowiredCapableBeanfactory 自动装配 定义了容器中的bean按照某种规则进行自动装配的方法 定义了将容器中的bean按照某种规则(如按名字匹配、按类型匹配等)进行自动装配的方法。
SingletonBeanRegistry 运行期间注册单实例Bean 允许在运行期间向容器注册单实例bean的方法,对于单实例signleton的bean来说,beanfactory会缓存bean实例,所以第二次使用getBean()获取bean时直接从IOC容器的缓存中获取Bean实例,所以第二次使用getBean()获取bean直接从IOC容器的缓存中获取bean实例
依赖日志框架 初始化BeanFactory时,必须为其提供一种日志框架,比如使用Log4j,即在类路径下提供Log4配置文件,这样启动Spring容器才不会报错
ApplicationContext面向开发应用 ApplicationContext由BeanFactory派生而来,提供了更多面向实际应用的功能。ApplicationContext继承了HierarchicalBeanFactory和ListableBeanFactory接口,在此基础上,还通过多个其他接口扩展了BeanFactory功能
  • ClassPathXmlApplicationConext :默认从类路径加载配置文件
  • FileSystemXmlApplicationContext:默认从文件系统中庄在配置文件
  • ApplicationEventPublisher: 让容器拥有发布应用上下文事件的功能,包括容器启动事件、关闭事件等
  • MessageSource 为应用提供i18n国际化消息访问功能
  • ResourcePatternResolver: 所有ApplicationContext实现类都实现了类似于PathMatchingResurcePatternResolver的功能,可以通过带前缀的ant风格的资源文件路径装载spring的配置文件
  • LifeCycle: 提供start()和stop()两个方法,主要用于控制异步处理过程。在具体使用时,该接口同时被ApplicationCOntext实现及具体Bean实现,ApplicationContext会将start/stop的信息传递给容器中所有实现了该接口的Bean,以达到管理和控制JMX、任务调度的目的。
  • ConfihurableApplicationContext 扩展于ApplicationContext,新增加两个主要的方法:refresh() 和close(), 让ApplicationContext具有启动,刷新和关闭上下文的能力。在应用上下文关闭的情况下调用refresh()即可启动应用的上下文,在已经启动的状态下,调用refresh()则清楚缓存并重新装载配置信息,而调用close()则可关闭应用上下文
WebApplication 体系架构 WebApplicationContext是专门为Web应用准备的,它允许从相对于Web根目录的路径中装载配置文件完成初始化工作。从WebApplicationContext中可以获得ServletContext的引用,整个Web应用上下文对象将作为属性放置到ServletContext中,以便web应用环境可以访问Spring应用上下文。
Spring Bean 作用域
spring 3中为bean定义了5种作用域,分别为singleton、prototype、request、session、global session。
  • singleton:单例模式,Spring ioc容器中只会存在一个共享的bean实例,无论有多少个bean引用它,始终指向同一个对象。该模式在多线程下是不安全的。singleton作用域是Spring中缺省的作用域。
  • prototype:原型模式每次使用时候常见,每次通过spring容器获取prototype定义的bean时候,容器都将常见一个新的bean实例,每个bean实例都有自己的属性和状态,而singleton全局只有只有一个对象。根据经验,对有经验的bean使用prototype作用域,而对于无状态的bean使用singleton作用域
  • request: 一次request一个实例
    再一次http请求中,容器回返回该bean的同一实例子,而对不同的http请求则会产生新的bean,而且该bean仅在当前http request 內有效,当前http请求结束,该bean实例也会被销毁。
  • session
    再一次http session中,容器会返回该bean的同一实例,而对不同的session请求则会创建新的实例,该bean实例仅在当前session內有效。同http请求相同,每一次session请求创建新的实例,而不同实例之间不共享属性,且实例仅在自己的session请求內有效,请求结束,则实例将被销毁。
  • global session
    global session 在一个全局的http session 中,容器会返回该bean的同一个实例,仅在使用portlet context时候有效
Spring bean 生命周期
  • 实例化 :实例化一个bean,也就是new
  • IOC依赖注入 :按照spring 上下文对实例化的bean进行配置,也就是IOC注入。
  • setBeanName实现:如果这个bean已经实现了BeanNameAware接口,会调用它实现的setBeanName(String)方法,此处传递的就是spring配置文件中的bean的id
  • BeanFactoryAware 实现:如果这个bean已经实现了beanfactoryAware接口,会调用它实现的setBeanFactory,setBeanFactory传递的是spring工厂自身
  • ApplicationContextAware实现:如果这个类实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext)方法,将spring上下文传入
  • postProcessbeforeInitialization接口-初始化预处理:如果这个bean关联了beanpostProcessor接口,将会调用postProcessBeforeInitialization.beanPostProcessor经常被用作是bean内容的更改,并且由于这个是bean初始化结束时调用的那个方法,可以被应用于内存/缓存技术
  • init-method:如果Bean在spring配置文件中配置了init-method属性会自动调用其配置的初始化方法。
  • postProcessAfterInitialization:如果这个bean关联了beanpostProcess接口将会调用postProcessAfterInitialization(Object obj, String s)方法。注:以上工作完成以后就可以用这个bean了,那这个bean是一个singleton的,所以一般情况下我们调用一个id的bean会是在内容地址相同的实例,当然在spring配置文件中也可以配置非singleton
  • destroy过期自动清理阶段:当bean不再需要时候,会经过清理阶段,如果bean实现了disposablebean这个接口,会调用那个其实现的destroy方法。
  • destroy-method:最后如果这个bean的spring配置了destroy-method属性,会自动调用其配置的销毁方法。
Spring依赖注入的4种方式
  • 构造器注入(带参数)
  • setter方法注入
  • 静态工厂注入:静态工厂顾名思义,就是通过调用静态工厂的方法来获取自己需要的对象,为了让spring管理所有对象,我们不能直接通过工程类.静态方法来获取对象,而是依然通过soring注入形式获取。
  • 实例工厂:获取对象实例的方法不是静态的,所以你需要先new工厂类,再调用普通的实例方法
5种不同方式的自动装配 spring装配包括手动装配和自动装配,手动装配时基于XML装配,构造方法、setter等方法,自动装配有5种方式,可以用来指导spring容器用自动装配方式来进行依赖注入
  • no:默认方式不进行自动装配,通过显示设置ref属性来进行装配
  • byName:通过参数名自动装配,Spring容器在配置文件中发现bean的autowire属性被设置为byName,之后容器试图匹配、装配和该bean的属性具有相同名字的bean
  • bytype autowire被设置为bytype,之后容器试图匹配,spring容器在配置文件中发现bean相同的type
  • constructor: 类似于bytype
  • autodetect:首先会尝试使用constructor来自动装配,如果无法工作,则使用byType方式。
Spring AOP原理
概念 面向切面编程,将影响多个类的公共行为封装到一个可重用的模块,并将其命名为aspect,切面,简单的说就是与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间耦合度。
主要应用场景:权限认证、Cacheing缓存、Debuggig调试,同步锁等
AOP核心概念
  • 切面 :类是对物体特征的抽象,切面就是对横切关注点的抽象
  • 横切关注点:对哪些方法进行拦截,拦截后如何处理
  • 连接点:被拦截的点,因为spring只支持方法类型的连接点,所以在spring中连接点指的就是被拦截到的方法,实际上连接点还可以是字段或者构造器。
  • 切入点:对连接点进行拦截的定义
  • 通知:所谓通知指的就是拦截到拦截点之后要执行的代码,通知氛围前、后、异常、最终、环绕通知五类
  • 目标对象:代理的目标对象
  • 织入:将切面应用到目标对象并导致代理对象创建的过程
  • 引入:在不修改代码的前提下,引入可以在运行期为类动态的添加一些方法或字段
AOP两种代理方式 Spring 提供两种方式来生成代理对象:JDKProxy和Cglib。默认策略是如果目标类是接口,则使用JDK动态代理技术、否则使用Cglib来代理。
JDK动态代理接口:
JDK动态代理主要涉及到java.lang.reflect包中的两个类:Proxy和InvocationHandler.InvocationHandler是一个接口,通过实现该接口定义横切逻辑,并通过反射机制调用目标类的代码,动态将横切逻辑和业务逻辑编织在一起。proxy利用invocationHandler动态创建一个符合某一接口的实例,生成目标类的代理对象
【spring|Spring 原理】Cglib: Code generation lib 是一个强大的高性能,高质量的代码生成类库,可以在运行期扩展java类与实现java接口,可以在运行期动态生成新的class。JDK创建代理又一个限制,就是只能为接口创建代理实例,而对于没有通过接口定义业务方法的类,则可以通过CGLIB创建动态代理
Spring mvc原理
围绕一个dispatcherServlet来设计,这个servlet把请求分发给各个处理器,并支持可配置的处理器映射、视图渲染、本地化、时区与主题渲染等,甚至还能支持文件上传。
Springboot 原理
简化spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不需要再定义样板化的配。有如下特点:
  • 创建独立的spring应用程序
  • 嵌入的tomcat,无需部署war文件
  • 简化maven配置
  • 自动配置spring
  • 提供生产就绪型功能
  • 绝对没有代码生成和对xml没有要求配置
JPA原理
事务(ACID)
本地事物:依赖于底层的资源管理器,事务处理局限在当前事务资源內。此种事物处理方式不存在对应用服务器的依赖,因而部署灵活却无法支持多数据源的分布式事务。在数据库连接中使用本地事物
分布式事务 分布式事务包括事物管理器(Transaction manager) 和一个或多个支持XA协议的资源管理器。
两阶段提交 第一阶段:准备阶段
事务协调者给每个参与者发送prepare消息,每个参与者要么直接返回失败(如权限验证),那么在本地执行事务,写本地redo和undo日志,但不提交,到达好准备状态
第二阶段:提交阶段
如果协调者收到参与者失败/超时消息时,直接给每个参与者发送回滚消息,否则发送提交消息。参与者根据协调者的指令执行提交或者回滚操作,释放所有事物处理过程中使用的锁资源

    推荐阅读