Spring整理


描述下IOC的程?

XML-(取)->Resource-(解析)->BeanDefinition-(注)->BeanFactory

BeanDefinitionRegistry

BeanDefinitionRegistry 接口提供了向容器手工注 BeanDefinition 的方法。

BeanDefinitionReader

作用是取 Spring 配置文件中的内容,将其转换为 IoC 容器内部的数结构:BeanDefinition。

BeanDefinition

ioc实现中我在xml中描述的Bean信息最后都将保存至BeanDefinition象中,其中xml bean与BeanDefinition程一一的系。


是IOC?

Spring 通一个配置文件描述 Bean 及 Bean 之的依赖关系,利用 Java 言的反射功能例化Bean 并建立 Bean 之的依赖关系。 Spring 的 IoC 容器在完成工作的基上,提供了 Bean 存、生命周期管理、 Bean 例代理、事件布、源装等高

 

是AOP?

AOP(Aspect Orient Programming),作面向程的一种补充,广用于理一具有横切性的系统级,如日志集、事管理、安全检查存、象池管理等。

 

Spring事的原因有

  • 不支持事
  • bean没有被spring管理
  • 方法不是 public 的 大概意思就是 @Transactional 能用于 public 的方法上,否不会失,如果要用在非 public 方法上,可以开启 AspectJ 代理模式。
  • 自身问题,也就是中的方法1用方法2。而没有经过 Spring 的代理有在外部用事才会生
  • 源没有配置事管理器
  • 的隔离级别不支持事Propagation.NOT_SUPPORTED: 表示不以事务运行,当前若存在事务则挂起
  • 没有常【注意是没常,如果try,catch是不行的】,事被吃了,try catch也行,但是要手

 

JDK动态代理如何使用?

1.建一个实现接口InvocationHandler的须实现invoke方法

2.建被代理的以及接口

3.Proxy的静方法

newProxyInstance(ClassLoaderloader, Class[] interfaces, InvocationHandler h)建一个代理

4.通代理用方法

 

JDK动态代理生成的类为什要求实现接口?

生成的代理public final class $Proxy0 extends Proxy implements Hello经继承了Proxy,java不支持多承。

 

Spring是如何选择代理模式的?

1、如果目标对实现了接口,情况下会采用JDK的动态代理实现AOP

2、如果目标对实现了接口,可以制使用CGLIB实现AOP

3、如果目标对象没有实现了接口,必采用CGLIB,spring会自在JDK动态代理和CGLIB之间转换

 

Spring是如何管理事物的?

PlatfromTransactionManager是Spring事管理的核心接口

Spring 并不直接管理事,而是提供了多管理器,通过这个接口,Spring 各个平台如 

  • JDBC(DataSourceTransactionManager)
  • Hibernate(HibernateTransactionManager)
  • JPA(JpaTransactionManager)

等都提供了对应的事管理器,但是具体的实现就是各个平台自己的事情了。

Spring的事物管理器用Theadlocal不同线维护了一独立的connection副本。保证线程之不会互相影

 

Spring是如何定事物信息的?

信息-TransactionDefinition

的隔离级别、是否超、是否

管理器接口 PlatformTransactionManager 通 getTransaction(TransactionDefinition definition) 方法来得到一个事个方法里面的参数是 TransactionDefinition 就定了一基本的事属性。

 

Spring有离级别

TransactionDefinition 接口中定了五个表示隔离级别的常量:

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的隔离级别。所有的事依次逐个行,这样就完全不可能生干,也就是该级别可以防止脏读、不可重复读以及幻。但是重影程序的性能。通常情况下也不会用到该级别

 

Spring的事物

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。

 

Spring事物的实现方式有

1.程式事:配置文件中有对应配置,少用这这事物管理了

2.使用了XML配置的方式行事物管理,但是没有使用AOP,基于TransactionProxyFactoryBean

3.要采用注解的方式,需要在配置文件中开启注解事

4.基于XML、aop的配置方式,目前目中都是使用这种方式,有少了代

 

Spring如何解决循赖问题

造器的循这种spring是理不了的,直接出BeanCurrentlylnCreationException。

例模式下的setter循:通“三级缓存”理循

例循理。

比如:A依于B、B依于A,多个bean之相互依,形成了一个闭环。Spring的循,是Spring容器注入候出问题

例化A,将A个并不完整的存起来,这样当B例化后,注入A的候,能容器中取到A象,完成初始化。

最后将B象注入到A中,A完成初始化。

例bean,会依次访问级缓存、二级缓存、三级缓存,存命中返回。通级缓存来解决存依赖问题

第一级缓存(例池:维护着所有建完成的Bean)singletonObjects

第二级缓存: earlySingletonObjects(维护早期暴露的Bean(行了例化,并未行属性注入))

第三级缓存: Map> singletonFactories(维护创建中Bean的ObjectFactory(解决循关键))

 

Springbean为单例?

Spring提供了5scope分singleton、prototype、request、session、global session。

例:一个bean被声明为单理多次spring容器里例化一个bean,后求公用象,象存在一个map中,当有,先在存中(map)查找是否存在,存在使用,不存在才例化一个象原型:当有求来就例化一个新的bean,没有存以及存中由于不会次都新建新象所以有一下几个

性能上的优势

1 少了新生成例的消耗新生成例消耗包括方面,第一,spring会通反射或者cglib来生成bean都是耗性能的操作,其次给对象分配内存也会复杂算法。

2 少jvm垃圾由于不会给每求都新生成bean例,所以自然回象少了。

3 可以快速取到bean因为单例的取bean操作除了第一次生成之外其余的都是存里取的所以快。

例bean的劣势单例的bean一个大的劣就是他不能线程安全,由于所有求都共享一个bean例,所以个bean要是有状的一个bean的可能在并发场景下出现问题,而原型的bean不会有这样问题(但也有例外,比如他被例bean依),因为给每求都新例。

 

Spring中用到的设计模式有

  • 简单工厂

Spring中的BeanFactory就是一个简单工厂,根入一个唯一标识bean来取Bean象,也就是getbean.

  • 工厂方法

实现了FactoryBean接口的bean是一叫做Factory的bean.其特点是,spring会在使用getbeanbean,会自动调bean的getobject方法,所以返回的不是factory的个bean而是个bean.getObject()方法的返回

  • 工厂设计模式 : Spring使用工厂模式通 BeanFactory、ApplicationContext 建 bean 象。
  • 代理设计模式 : Spring AOP 功能的实现
  • 设计模式 : Spring 中的 Bean 都是例的。
  • 模板方法模式 : Spring 中 jdbcTemplate、hibernateTemplate 等以 Template 尾的操作的就使用到了模板模式。
  • 包装器设计模式 : 我目需要接多个数,而且不同的客访问中根需要会去访问不同的数这种模式可以根的需求能够动态不同的数源。
  • 察者模式: Spring 事件驱动模型就是察者模式典的一个用。
  • 配器模式 :Spring AOP 的增强或通知(Advice)使用到了配器模式、spring MVC 中也是用到了配器模式配Controller。

 

是代理模式?

代理模式 (Proxy Pattren) 也称模式,是属于结构设计模式,作用是为为象提供一代理以控制对这象的访问简单说这就是标对象生成一个代理象,并由代理象控制标对象的引用。

 

ApplicationContext与BeanFactory有何同?

ApplicationContext:是BeanFactory的子,除了提供BeanFactory相同的方法之外,提供AOP的集成,消息源的理,事件布,用的特定上下文(比如web),在ApplicationContext 容器启动之后,全部初始化并定完成,所以,于BeanFactory来,ApplicationContext 往往要求更多的系统资

ApplicationContext的三个实现类

  • ClassPathXmlApplication:的根路径下加xml配置文件(推这种)。
  • FileSystemXmlApplication: 路径上加配置文件,配置文件可以在磁的任意位置。(但使用不活,不推
  • AnnotationConfigApplication:当我使用注解配置容器,需要使用此建spring容器。用来取注解。(springboot使用个)

 

Bean的生命周期?

  • Spring启动查找并加需要被Spring管理的bean,行Bean的例化
  • Bean例化后Bean的引入和注入到Bean的属性中(ioc注入)
  • 如果Bean实现BeanNameAware接口的Spring将Bean的Id传递给setBeanName()方法,此处传递的就是Spring配置文件中Bean的id
  • 如果Bean实现BeanFactoryAware接口的Spring将用setBeanFactory()方法,将BeanFactory容器
  • 如果Bean实现ApplicationContextAware接口的Spring将用Bean的setApplicationContext()方法,将bean所在用上下文引用
  • 如果Bean实现BeanPostProcessor接口,Spring就将用他postProcessBeforeInitialization()方法。BeanPostProcessor常被用作是Bean内容的更改,并且由于个是在Bean初始化时调用那个的方法,也可以被用于内存或存技
  • 如果Bean 实现InitializingBean接口,Spring将用他afterPropertiesSet()方法。似的,如果bean使用init-method声明了初始化方法,方法也会被
  • 如果Bean 实现BeanPostProcessor接口,Spring就将用他postProcessAfterInitialization()方法。此,Bean已,可以被用程序使用了。他将一直留在用上下文中,直到用上下文被销毁
  • 如果bean实现DisposableBean接口,Spring将的destory()接口方法,同,如果bean使用了destory-method 声明销毁方法,方法也会被用。

 

SpringMVCrequest到controller的

 DispatcherServlet→理器映射→控制器

 

要用三级缓存来解决循赖问题用一级缓存行不行,用二级缓存行不行)?

用一级缓存也是可以解决的,但是会复杂化整个逻辑,半成品象是没法直接使用的(存在 NPE 问题),所以 Spring 需要保启动程中,所有中间产生的半成品象最都会成成品象,如果将半成品象和成品象都混在一级缓存中,那么为了区分他必会加一而外的标记逻辑处理,就会象的复杂化了。

 

ApplicationContext和BeanFactory有什不同?

1 ApplicationContext提供了更富的功能

  • 支持国
  • 源的访问方式
  • 提供在听器中注bean事件。
  • 多个文件
  • 入多个上下文。

2 加方式不同

BeanFactory采用的是延的形式来注入bean,也就是有用到某个bean的候才对该bean行加载实例化,这样的坏是加入某个bean的某个属性没有被注入,有使用才会发现

ApplicationContext是在容器启动时一次建了所有的bean