Spring学习笔记之Spring圣经(要求熟读并背诵)

Spring自动装配的方式有哪些?

no:不自动装配
byName:根据Bean的名字进行自动装配
byType:根据Bean的类型进行装配
constructor:类似于byType,不过是应用于构造器参数,如果正好有一个Bean预购朝气的参数类型相同则可以自动装配,否则会导致错误
autodetect:如果有默认的构造器,则通过constructor的方式进行装配,否则使用byType的方式进行自动装配
**PS:**自动装配没有自定义装配那么精确,而且不能自动装配简单属性(基本类型、字符串等),在使用时应该注意

Spring中Bean的作用域有哪些?

早期版本:

  • singleton(常翻译为:单例模式)
    Bean以单例的方式存在;
  • prototype(常翻译为:原型模式)
    每次调用Bean返回一个新实例
    2.X以后加入:
  • request
    每次HTTP请求创建一个新的Bean
  • session
    同一个HttpSession共享同一个Bean
  • globalSession
    同一个全局Session共享一个Bean

**PS:**单例模式和原型模式都是重要的设计模式。一般情况下,无状态或状态不可变的类适合使用单例模式。在传统开发中,由于DAO持有Connection这个非线程安全对象因而没有使用单例模式;但在Spring环境下,所有DAO类对可以采用单例模式,因为Spring利用AOP和Java API中的ThreadLocal对非线程安全的对象进行了特殊处理。

请问什么是IoC和DI?并简要说明DI是如何实现的?

IoC叫控制反转,是Inversion of Control 的缩写,DI(Dependency Injection)叫依赖注入,是对IoC更简单的诠释。控制反转是把传统上由程序代码直接操控的对象的调用全交给容器,通过容器来实现对象组建的装配和管理。所谓的“控制反转”就是对组件对象的控制权的转移,从程序代码本身转移到了外部容器,有容器来创建对象并管理对象之间的依赖关系。IoC体现了好莱坞原则——“Don’t call me, we will call you”。依赖注入的基本原则是应用组件不应该负责查找资源或者其他依赖的协作对象。配置对象的工作应该由容器负责,查找资源的逻辑应该从应用组建的代码中抽取出来,交给容器来完成。DI是对IoC更准确的描述,即组件之间的依赖关系由容器在运行期决定,形象地说,即由容器动态地将某种依赖关系注入到组件之中。
一个类A需要用到接口B中的方法,那么就需要为类A和接口B建立关联或依赖关系,最原始的做法是在类A中船舰一个接口B的实现类C的实例,但是这种方法需要开发人员自行维护而职责的依赖关系,也就是说当以来关系发生变动时,需要修改代码并重写构建整个系统。如果通过一个容器来管理这些对象以及对象的依赖关系,则只需要在类A中定义好用于关联接口B的方法(构造器或者setter方法),将类A和接口B的实现类C放入容器中,通过堆容器的配置来实现二者的关联。
依赖注入可以通过setter方法注入(设值注入)、构造器注入和接口注入三种方式实现,而Spring支持setter注入和构造器注入,通常使用构造器注入来诸如必须的依赖关系,对于可选的依赖关系,则setter注入时更好的选怎,setter注入需要类提供无参构造或者物产的静态工厂方法来创建对象。

前方黄色警告!!!
可以举出一个 黄色的类比以更好理解IoC: 传统的开发模式需要维护对象之间的依赖关系:对象之间的依赖关系在写代码时就已经确定下来(相当于指腹为婚?)。现在假设你是一个对象,你的女朋友是你依赖的对象,那么你调用女朋友的方法是没问题的,但是万一你要换一个女朋友(依赖关系发生变动),因为你对前女友和现女友调用方法时会不一样(因为他们不是同一个类的实例),所以你可能要修改代码重写整个系统。但是Spring作为容器,它的作用就像会所。会所的嫩模个个都实现女人这个接口,你要调用你依赖的女人的某个方法时,会所(Spring)直接给你一个,用完还可以给其他人用,你也可以随时换别的女人(运行时修改对象)????所以结果就是你不会依赖某个具体的对象,一切取决于会所给你什么。这么做的好处是提高代码的复用率,降低耦合度。 ## 请说明一下Spring中BeanFactory和ApplicationContext的区别是什么?
  • BeanFactory:
    BeanFactory是Spring中比较原始的Factory,因为比较古老,所以BeanFactory无法支持Spring插件,例如:AOP、Web应用等功能。
  • ApplicationContext
    ApplicationContext是BeanFactory的子类,因为古老的BeanFactory无法满足不断更新的Spring需求,于是ApplicationContext就基本上代替了BeanFactory的工作,以一种更面向框架的工作方式以及对上下文进行分层和实现线程,并在这个基础上进行拓展(面对修改关闭,面对拓展开放):
  1. MessageSource,提供国际化的消息访问
  2. 资源访问(如URL和文件)
  3. 事件传递
  4. Bean自动装配
  5. 各种不同应用层的Context实现
    区别:
    如果使用ApplicationContext,如果配置Bean是singleton,那么不管你有没有或者想不想用它,它都会被实例化。好处是可以预先加载,坏处是浪费内存。
    如果使用BeanFactory实例化对象是,配置bean不会被马上实例化,二十等到你使用该bean时(getBean)才会被实例化,好处是节省内存,坏处是速度比较慢。
    没有特殊要求的情况下,应该使用ApplicationContext完成。因为BeanFactory能完成的事情,ApplicationContext都能完成,并且提供了更多接近现在开发的功能。

请说明一下springIOC原理是什么?如果你要实现IOC需要怎么做?请简单描述一下实现步骤?

①IoC(Inversion of Control,控制反转)。这是spring的核心,贯穿始终。所谓IoC,对于spring框架来说,就是由spring来复折控制对象的生命周期和对象间的关系。

IoC的一个重点就是在系统运行中,动态地向某个对象提供它所需要的其他对象。这一点是通过DI(Dependency Injection,依赖注入)来实现的。比如对象A需要操作数据库,以前我们总是要在A中自己编写代码来获取一个Connection对象,有了spring我们就只需要告诉spring,A中需要一个Connection,至于Connection怎么构造,何时构造,A不需要知道.在系统运行时,spring会在适当的时候制造一个Connection,然后像打针一样,注射到A中,这样就完成了对各个对象之间关系的控制。A需要依赖Connection才能正常运行,而这个Connection是由spring注入到A中的,依赖注入的名字就这么来的。那么DI是如何实现的呢? Java 1.3之后一个重要特征是反射(reflection),它允许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性,spring就是通过反射来实现注入的。

举个简单的例子,我们找女朋友常见的情况是,我们到处去看哪里有长得漂亮身材又好的女孩子,然后打听她们的兴趣爱好、qq号、电话号、ip号、iq号………,想办法认识她们,投其所好送其所要,这个过程是复杂深奥的,我们必须自己设计和面对每个环节。传统的程序开发也是如此,在一个对象中,如果要使用另外的对象,就必须得到它(自己new一个,或者从JNDI中查询一个),使用完之后还要将对象销毁(比如Connection等),对象始终会和其他的接口或类藕合起来。

②实现IOC的步骤

定义用来描述bean的配置的Java类

解析bean的配置,將bean的配置信息转换为上面的BeanDefinition对象保存在内存中,spring中采用HashMap进行对象存储,其中会用到一些xml解析技术

遍历存放BeanDefinition的HashMap对象,逐条取出BeanDefinition对象,获取bean的配置信息,利用Java的反射机制实例化对象,將实例化后的对象保存在另外一个Map中即可。

请简单说明一下依赖注入的方式有哪几种?以及这些方法如何使用?

1、Set注入 2、构造器注入 3、接口注入

autowired 和resource区别是什么?

共同点:

两者都可以写在字段和setter方法上,如果写在字段上,则不需要写setter方法

不同点:

@Autowired为spring注解,需要导入包

org.springframework.beans.factory.annotation.Autowired;只按照byType注入。

@Resource默认按照ByName自动注入,由J2EE提供,需要导入包javax.annotation.Resource。

@Resource有两个重要的属性:name和type,而Spring将@Resource注解的name属性解析为bean的名字,而type属性解析为bean的类型。所以,如果使用name属性,则使用byName的自动注入策略,而是用type属性时则使用byType自动注入策略。如果既不制定name也不制定type属性,这时将通过反射机制使用byName自动注入策略。

bean的生命周期

img

简要说明一下IOC和AOP是什么?

依赖注入的三种方式:(1)接口注入(2)Construct注入(3)Setter注入

控制反转(IoC)与依赖注入(DI)是同一个概念,引入IoC的目的:

  1. 脱开、减低类之间的耦合
  2. 倡导面向接口编程、试试依赖倒置原则
  3. 提高系统可插入、可测试、可修改等特性

具体做法:

  1. 将bean之间的依赖关系尽可能地转换为关联关系;[点此了解关联关系和依赖关系]( https://www.cnblogs.com/iyangyuan/archive/2013/06/16/3138463.html >)
  2. 将对具体类的关联尽可能地转换为对Java Interface的关联,而不是与具体的服务对象相关联。
  3. Bean实例具体关联相关Java Interface的哪个实现类的实例,在配置信息的元数据中描述;
  4. 由IoC组件(或称容器)根据配置信息,实例化具体bean类,将bean之间的依赖关系注入进来

AOP(Aspect Oriented Programming),即面向切面编程,可以说是OOP(Object Oriented Programming,面向对象编程)的补充和完善。OOP引入封装、继承、堕胎等概念来建立一种对象层次结构,用于模拟公共行为的一个集合。不过OOP允许开发者定义纵向关系,但并不适合定义横向关系,例如日志功能。日志代码往往横向地散布在所有对象层次中,而与他对应的对象的核心功能毫无关系,对于其他类型的代码,如安全性、异常处理和透明性也都是如此,这种散步在各处的无关代码被称为横切(cross cutting),在OOP设计中,它导致了大量代码的重复,而不利于个个模块的重用。

AOP技术恰恰相反,它利用一种称为横切的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为“Aspect”,即切面。所谓“切面”, 简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。

使用“横切技术”,AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点就是,他们经常发生在核心关注点的多出,而各处基本相似,比如权限认证、日志、事务。AOP的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。

Spring支持的事务管理类型有哪些?以及你在项目中会使用哪种方式?

Spring支持编程式事务管理和声明式事务管理。许多spring框架的用户选择生命是事务管理,因为这种方式和应用程序的关联较少,因此更加符合轻量级容器的概念。声明式事务管理要优于编程式事务管理,尽管灵活性方面他弱于编程式事务管理,因为编程式事务管理允许你通过代码控制业务。

事务分为全局事务和局部事务。全局事务有应用服务器管理,需要底层服务器JTA支持(WeBLogic、WildFly等)。局部食物和底层采用的持久化方案有关,例如使用JDBC进行持久化时,需要使用Connection对象来操作事务;而采用Hibernate进行持久化时,需要使用Session对象来操作事务。

这些事务的父接口都是Platform TransationManager。Spring的事务管理机制时一种典型的策略模式, PlatformTransactionManager 代表事务管理接口,该接口定义了三个方法,该接口并不知道底层如何实现管理事务,但是他的实现类必须提供getTransaction()方法(开启事务)、commit()方法(提交事务)、rollback()方法(回滚事务)的多态实现,这样就可以用不同的实现类代表不同的事务管理策略。使用TJTA全局事务策略时,需要底层应用服务器支持,而不同的应用服务器提供的JTA全局事务可能存在细节上的差异,因此实际配置全局事务管理器可能需使用 JtaTransactionManager的子类,如:WebLogicJtaTransactionManager(Oracle的WebLogic服务器提供)、UowJtaTransactionManager(IBM的WebSphere服务器提供)等。

如何理解AOP中的连接点(Joinpoint)、切点(Pointcut)、增强(Advice)、引介(Introduction)、织入(Weaving)、切面(Aspect)这些概念?

a. 连接点(Jionpoint):程序执行的某个特定位置(如:某个方法调用前、调用后,方法抛出异常后)。一个类或者一段程序代码拥有一些具有边界的特定点,这写代码中的特定点就是连接点,Spring仅支持方法的连接点。

b. 切点(Pointcut):如果连接点相当于数据中的记录,那么切点就相当于查询条件,一个切点可以匹配多个连接点。Spring AOP的规则解析引擎负责解析切点所设定的查询条件,找到对应的连接点。

c. 增强(Advice):增强是织入到目标类连接点上的一段程序代码。Spring提供的增强接口都是带方位名的,如:BeforeAdvice、AfterReturningAdvice、ThrowsAdvice等。

d. 引介(Introdution):引介是一种特殊的增强,他为类添加一些属性和方法。这样,即使一个业务类原本没有实现某个接口,通过引介功能,可以动态的为该业务类添加接口的实现逻辑,让业务类成为这个接口的实现类。

e. 织入(Weaving):织入是见增加添加到目标类具体连接点上的过程,AOP有三种方式:①编译期织入:需要特殊的Java编译器(例如AspectJ的ajc);②装载期织入:要求使用特殊的类加载器,在装载类时实现增强。③运行时织入:在运行时为目标类生成代理实现增强。Spring采用了动态代理的方式实现了运动时织入,而AspectJ采用了编译期织入和装载期织入的方式。

f. 切面(Aspect):切面时由切点和增强(引介)组成的它包括了对横切关注功能的定义,也包括了对连接点的定义。

AOP的原理是什么?

AOP( Aspect Oriented Programming),值面向切面编程,作为面向对象的一种补充,用于处理系统中分布于各个模块的横切关注点,比如事务管理、日志、缓存等等。AOP实现的关键在于AOP框架自动创建AOP代理,AOP代理主要分为静态代理和动态代理,静态代理的代表为AspectJ;而动态代理则以Spring AOP为代表。通常使用AspectJ的编译时增强实现AOP,AspectJ时静态代理的增强,所谓静态代理就是AOP框架会在编译阶段生成AOP代理类,因此也被称为编译时增强。

Spring AOP中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理。JDK动态代理通过反射来接受被代理对象,并且要求被代理类必须实现一个接口,JDK动态代理的核心时InvocationHandler接口和Proxy类。

如果目标类,没有实现接口,那么Spring AOP就会选择CGLIB来动态代理目标类。

CGLIB(Code Generation Library),是一个的代码生成的类库,可以在运行时动态生成某个类的子类,注意,CGLIB时通过继承的方式做动态代理,因此如果某个类被标记为final,那么他是无法使用CGLIB做动态代理的。

aop的应用场景有哪些?

Authentication 权限 ,Caching 缓存 ,Context passing 内容传递 ,Error handling 错误处理 ,Lazy loading 懒加载 ,Debugging 调试 ,logging, tracing, profiling and monitoring 记录跟踪 优化 校准,Performance optimization 性能优化 ,Persistence 持久化 ,Resource pooling 资源池 ,Synchronization 同步,Transactions 事务。

Spring框架为企业级开发带来的好处有哪些?

  • 非侵入式:支持基于POJO的编程模式,不强制性的要求实现Spring框架中的接口或继承Spring框架中的类。
  • IoC容器:IoC容器帮助应用程序管理对象以及对象之间的依赖关系,对象之间的依赖关系如果发生了该百年只需要修改配置文件而不是修改代码,因为代码的修改可能意味着项目的重构和完整的回归测试。有了IoC容器,程序员再也不需要自己编写工厂、单例,这一点特别符合Spring的精神”不要重复发明轮子“
  • AOP(面向切面编程):将所有的横切关注功能封装到切面(Aspect)中,通过配置的方式将横切关注功能动态添加到目标代码上,进一步实现业务逻辑和系统服务之间的分离。另一方面,有了AOP程序员可以省去很多自己写代理类的工作。
  • MVC:Spring的MVC框架为Web表示层提供了更好的解决方案。
  • 事务管理:Spring以宽广的胸怀接纳多种持久层技术,并未Java提供了声明式的事务管理,在不需要任何一行代码的情况下就能够完成事务管理器。
  • 其他:选择Spring框架的原因远远不止于此,Spring为Java企业级开发提供了一站式选择,你可以在需要的时候使用它的部分和全部,更重要的是,甚至可以在完全感受不到Spring存在的情况下,在你的项目中使用Spring提供的各种优秀的功能。

spring框架的优点都有哪些?

Spring是一个轻量级的DI和AOP容器框架,在项目的中的使用越来越广泛,它的优点主要有以下几点:

Spring是一个非侵入式框架,其目标是使应用程序代码对框架的依赖最小化,应用代码可以在没有Spring或者其他容器的情况运行。

Spring提供了一个一致的编程模型,使应用直接使用POJO开发,从而可以使运行环境隔离开来。

Spring推动应用的设计风格向面向对象及面向接口编程转变,提高了代码的重用性和可测试性。

Spring改进了结构体系的选择,虽然作为应用平台,Spring可以帮助我们选择不同的技术实现,比如从Hibernate切换到其他的ORM工具,从Struts切换到Spring MVC,尽管我们通常不会这么做,但是我们在技术方案上选择使用Spring作为应用平台,Spring至少为我们提供了这种可能性的选择,从而降低了平台锁定风险。

Struts拦截器和Spring AOP有什么区别?

拦截器是AOP的一种实现,struts2 拦截器采用xwork2的interceptor!而spring的AOP基于IoC基础,其底层采用动态代理与CGLIB代理两种方式结合的实现方式。

简单介绍一下spring?

Spring是一个轻量级框架,可以一站式构建你的企业级应用。

Spring的模块大概分为6个。分别是:

1、Core Container(Spring的核心)【重要】

2、AOP(面向切面变成)【重要】

3、Messaging(消息发送的支持)

4、Data Access/Integration(数据访问和集成)

5、Web(主要是SpringWeb内容,包括MVC)【重要】

6、Test(Spring测试支持,包含JUint等测试单元的支持) 7、Instrumentation(设备支持,比如Tomcat的支持)

持久层设计要考虑的问题有哪些?请谈一下你用过的持久层框架都有哪些

所谓"持久"就是将数据保存到可掉电式存储设备中以便今后使用,简单的说,就是将内存中的数据保存到关系型数据库、文件系统、消息队列等提供持久化支持的设备中。持久层就是系统中专注于实现数据持久化的相对独立的层面。

持久层设计的目标包括:
- 数据存储逻辑的分离,提供抽象化的数据访问接口。
- 数据访问底层实现的分离,可以在不修改代码的情况下切换底层实现。
- 资源管理和调度的分离,在数据访问层实现统一的资源调度(如缓存机制)。
- 数据抽象,提供更面向对象的数据操作。

持久层框架有:
- Hibernate
- MyBatis
- TopLink
- Guzz
- jOOQ
- Spring Data
- ActiveJDBC

发布了41 篇原创文章 · 获赞 27 · 访问量 5842

猜你喜欢

转载自blog.csdn.net/weixin_43217564/article/details/102670821