Spring 专题


Spring 专题

1. 什么是 spring?
Spring 是最受欢迎的企业级 Java 应用程序开发框架,数以百万的来自世界各地的开发人员使用 Spring 框架来创建性能好、易于测试、可重用的代码。
Spring 框架是一个开源的 Java 平台,它最初是由 Rod Johnson 编写的,并且于2003 年 6 月首次在 Apache 2.0 许可下发布。
Spring 是轻量级的框架,其基础版本只有 2 MB 左右的大小。
Spring 框架的核心特性是可以用于开发任何 Java 应用程序,但是在 Java EE 平台上构建 web 应用程序是需要扩展的。 Spring 框架的目标是使 J2EE 开发变得更容易使用,通过启用基于 POJO 编程模型来促进良好的编程实践。

2. 谈谈你对 Spring 的理解
Spring 是一个开源框架,为简化企业级应用开发而生。Spring 可以是使简单的JavaBean 实现以前只有 EJB 才能实现的功能。Spring 是一个 IOC 和 AOP 容器框架。
Spring 容器的主要核心是:控制反转(IOC),传统的 java 开发模式中,当需要一个对象时,我们会自己使用 new或者 getInstance 等直接或者间接调用构造方法创建一个对象。而在 spring 开发模式中,spring 容器使用了工厂模式为我们创建了所需要的对象,不需要我们自己创建了,直接调用 spring 提供的对象就可以了,这是控制反转的思想。
依赖注入(DI),spring 使用 JavaBean 对象的 set 方法或者带参数的构造方法为我们在创建所需对象时将其属性自动设置所需要的值的过程,就是依赖注入的思想。
面向切面编程(AOP),在面向对象编程(oop)思想中,我们将事物纵向抽成一个个的对象。而在面向切面编程中,我们将一个个的对象某些类似的方面横向抽成一个切面,对这个切面进行一些如权限控制、事物管理,记录日志等公用操作处理的过程就是面向切面编程的思想。AOP 底层是动态代理,如果是接口采用 JDK 动态代理,如果是类采用 CGLIB 方式实现动态代理

3. 使用 Spring 框架的好处是什么?
① 轻量:Spring 是轻量的,基础版本只有 2MB 左右的大小
② 控制反转:Spring 通过控制反转实现了松散耦合,对象们给出它们的依赖,而不是创建或查找依赖的对象们。
③ 面向切面的编程(AOP):Spring 支持面向切面的编程,并且把应用业务逻辑和系统服务分开。
④ 容器:Spring 包含并管理应用中对象的生命周期和配置。
⑤ MVC 框架:Spring 的 WEB 框架是个精心设计的框架,是 Web 框架的一个很好的替代品。
⑥ 事务管理:Spring 提供一个持续的事务管理接口,可以扩展到上至本地事务下至全局事务(JTA)。
⑦ 异常处理:Spring 提供方便的 API 把具体技术相关的异常(比如由 JDBC,HibernateorJDO 抛出的)转化为一致的 unchecked 异常。

4. Spring 的体系结构?
① Spring Core:即,Spring 核心,它是框架最基础的部分,提供 IOC 和依赖注入特性
② Spring Context:即,Spring 上下文容器,它是 BeanFactory 功能加强的一个子接口
③ Spring Web:它提供 Web 应用开发的支持
④ Spring MVC:它针对 Web 应用中 MVC 思想的实现
⑤ Spring DAO:提供对 JDBC 抽象层,简化了 JDBC 编码,同时,编码更具有健壮性。
⑥ Spring ORM:它支持用于流行的 ORM 框架的整合,比如:Spring + Hibernate、Spring + iBatis、Spring + JDO 的整合等等。
⑦ Spring AOP:AOP 即,面向切面编程,它提供了与 AOP 联盟兼容的编程实现

5. 什么是控制反转(IOC),什么是依赖注入(DI)?
IOC:就是对象之间的依赖关系由容器来创建,对象之间的关系本来是由我们开发者自己创建和维护的,在我们使用 Spring 框架后,对象之间的关系由容器来创建和维护,将开发者做的事让容器做,这就是控制反转。BeanFactory 接口是 Spring Ioc 容器的核心接口。
DI:我们在使用 Spring 容器的时候,容器通过调用 set 方法或者是构造器来建立对象
之间的依赖关系。控制反转是目标,依赖注入是我们实现控制反转的一种手段。

6. Java 中实现依赖注入的三种方式?
①构造器注入:构造器依赖注入通过容器触发一个类的构造器来实现的,该类有一系列参数,每个参数代表一个对其他类的依赖。
②Setter 方法注入:Setter 方法注入是容器通过调用无参构造器或无参 static 工厂方法实例化 bean 之后,调用该 bean 的 setter 方法,即实现了基于 setter 的依赖注入。
③接口注入:这种接口注入的方式需要调用者必须实现一个指定的接口,这种方式使用比较少,一般不推荐使用

7. 你建议使用那种注入是构造器注入,还是 Setter 方法注入?
这两种注入方式都可以使用。最好分情况使用者两种注入方式:
①用构造器参数实现强制依赖
②setter 注入方式实现可选依赖

8. 什么是 AOP?
AOP(面向切面编程)是 Spring 的另一个核心内容,是 OOP(面向对象编程)的延续,主要应用于①日志记录②性能统计③安全控制④事务处理等方面。
AOP 是基于代理设计模式的,代理模式分为静态代理和动态代理。(详细介绍请看设计模式专题)
AOP 的目的:
AOP 能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性。
①切面(Aspect):有切点(point Cut)和通知(Advice)组成,它既包括横切逻辑的定义,也包括了连接点的定义。
②切点(pointCut):一个切点定位多个类的多个方法。
③通知也叫增强(Advice):由方位和横切逻辑构成,所谓的方位指的是前置通知,后置通知,返回后通知,环绕通知,抛出异常后通知
④连接点(JoinPoint):由切点和方位构成,用来描述在在哪些类的指定方法之前或之后执行
所谓的方位包括:
前置通知(Before advice):在连接点(join point)之前执行的通知,但这个通知不能阻止连接点前的执行(除非它抛出一个异常)。
返回后通知(After returning advice): 在连接点(join point)正常完成后执行的通知:例如,一个方法没有抛出任何异常,正常返回。
抛出异常后通知(After throwing advice):在方法抛出异常退出时执行的通知。
后置通知(After (finally) advice):当连接点退出的时候执行的通知(不论是正常返回还是异常退出)。
环绕通知(Around Advice):包围一个连接点(join point)的通知,如方法调用。这是最强大的一种通知类型。环绕通知可以在方法调AOP 的使用场景: 缓存、权限管理、内容传递、错误处理、懒加载、记录跟踪、优化、校准、调试、持久化、资源池、同步管理、事物控制等。

9. 什么是引入?
引入允许我们在已存在的类中增加新的方法和属性。

9.1什么是目标对象?
被一个或者多个切面所通知的对象。它通常是一个代理对象。也指被通知(advised)对象。

9.2什么是代理?
代理是通知目标对象后创建的对象。从客户端的角度看,代理对象和目标对象是一样的。

9.3有几种不同类型的自动代理?
BeanNameAutoProxyCreator
DefaultAdvisorAutoProxyCreator
Metadataautoproxying

9.4什么是织入。什么是织入应用的不同点?
织入是将切面和到其他应用类型或对象连接或创建一个被通知对象的过程。
织入可以在编译时,加载时,或运行时完成。

9.5解释基于 XMLSchema 方式的切面实现。
在这种情况下,切面由常规类以及基于 XML 的配置实现。

10. 解释基于注解的切面实现
在这种情况下(基于@AspectJ 的实现),涉及到的切面声明的风格与带有 java5 标注的普通 java 类一致。

11. Spring 容器中如何创建对象?
①无参构造创建 ②静态工厂创建 ③实例工厂创建

12. 什么是 Springbeans?
Springbeans 是那些形成 Spring 应用的主干的 java 对象。它们被 SpringIOC 容器初始化,装配,和管理。这些 beans 通过容器中配置的元数据创建。比如,以 XML 文件中<bean/>的形式定义。
Spring 框架定义的 beans 都是单件 beans。在 beantag 中有个属性”singleton”,如果它被赋为 TRUE,bean 就是单件,否则就是一个 prototypebean。默认是 TRUE,所以所有在 Spring 框架中的 beans 缺省都是单件。

13. 一个 SpringBean 定义包含什么?
一个 SpringBean 的定义包含容器必知的所有配置元数据,包括如何创建一个 bean,它的生命周期详情及它的依赖。

14. 如何给 Spring 容器提供配置元数据?
这里有三种重要的方法给 Spring 容器提供配置元数据。
①XML 配置文件。 ②基于注解的配置。 ③基于 java 的配置。

15. 你怎样定义类的作用域?
当定义一个<bean>在 Spring 里,我们还能给这个 bean 声明一个作用域。
它可以通过 bean 定义中的 scope 属性来定义。如,当 Spring 要在需要的时候每次生产一个新的 bean 实例,bean 的 scope 属性被指定为 prototype。另一方面,一个 bean 每次使用的时候必须返回同一个实例,这个 bean 的 scope 属性必须设为 singleton。

16. 解释 Spring 支持的几种 bean 的作用域。
Spring 框架支持以下五种 bean 的作用域:
①singleton:bean 在每个 Springioc 容器中只有一个实例。
②prototype:一个 bean 的定义可以有多个实例。
③request:每次 http 请求都会创建一个 bean,该作用域仅在基于 web 的SpringApplicationContext 情形下有效。
④session:在一个 HTTPSession 中,一个 bean 定义对应一个实例。该作用域仅在基于 web 的 SpringApplicationContext 情形下有效。
⑤global-session:在一个全局的 HTTPSession 中,一个 bean 定义对应一个实例。该作用域仅在基于 web 的 SpringApplicationContext 情形下有效。缺省的 Springbean 的作用域是 Singleton.

17. Spring 框架中的单例 bean 是线程安全的吗?
不,Spring 框架中的单例 bean 不是线程安全的。

18. 解释 Spring 框架中 bean 的生命周期。
Spring 容器从 XML 文件中读取 bean 的定义,并实例化 bean。
Spring 根据 bean 的定义填充所有的属性。
如果 bean 实现了 BeanNameAware 接口,Spring 传递 bean 的 ID 到 setBeanName方法。
如果 Bean 实现了 BeanFactoryAware 接口,Spring 传递 beanfactory 给setBeanFactory 方法。
如果有任何与 bean 相关联的 BeanPostProcessors,Spring 会在postProcesserBeforeInitialization()方法内调用它们。
如果 bean 实现 IntializingBean 了,调用它的 afterPropertySet 方法,如果 bean 声明了初始化方法,调用此初始化方法。
如果有 BeanPostProcessors 和 bean 关联,这些 bean 的postProcessAfterInitialization()方法将被调用。
如果 bean 实现了 DisposableBean,它将调用 destroy()方法。

19. 哪些是重要的 bean 生命周期方法?你能重载它们吗?
有两个重要的 bean 生命周期方法:
第一个是 setup,它是在容器加载 bean 的时候被调用。第二个方法是 teardown 它是在容器卸载类的时候被调用。Thebean 标签有两个重要的属性(init-method 和 destroy-method)。用它们你可以自己定制初始化和注销方法。它们也有相应的注解(@PostConstruct 和@PreDestroy)。

20. 什么是 Spring 的内部 bean?
当一个 bean 仅被用作另一个 bean 的属性时,它能被声明为一个内部 bean,为了定义 innerbean,在 Spring 的基于 XML 的配置元数据中,可以在<property/>或<constructor-arg/>元素内使用<bean/>元素,内部 bean 通常是匿名的,它们的 Scope 一般是 prototype。

21. 在 Spring 中如何注入一个 java 集合(Java Collection)?
Spring 提供以下几种集合的配置元素:
<list>类型用于注入一列值,允许有相同的值。
<set>类型用于注入一组值,不允许有相同的值。
<map>类型用于注入一组键值对,键和值都可以为任意类型。
<props>类型用于注入一组键值对,键和值都只能为 String 类型。

22. 解释什么叫延迟加载 ?
默认情况下,容器启动之后会将所有作用域为单例的 bean 创建好;但是有的业务场景我们并不需要它提前都创建好;此时,我们可以在 bean 中设置 lzay-init=“true”,这样,当容器启动之后,作用域为单例的 bean,就不在创建。

23. 什么是 bean 装配?
装配,或 bean 装配是指在 Spring 容器中把 bean 组装到一起,前提是容器需要知道bean 的依赖关系,如何通过依赖注入来把它们装配到一起。

24. 什么是 bean 的自动装配?
Spring 容器能够自动装配相互合作的 bean,这意味着容器不需要<constructor-arg>和<property>配置,能通过 Bean 工厂自动处理 bean 之间的协作。

25. 请解释自动装配模式的区别?。
有五种自动装配的方式,可以用来指导 Spring 容器用自动装配方式来进行依赖注入。
① no:默认的方式是不进行自动装配,通过显式设置 ref 属性来进行装配。
② byName:通过参数名自动装配,Spring 容器在配置文件中发现 bean 的 autowire属性被设置成 byname,之后容器试图匹配、装配和该 bean 的属性具有相同名字的 bean。
③ byType::通过参数类型自动装配,Spring 容器在配置文件中发现 bean 的autowire 属性被设置成 byType,之后容器试图匹配、装配和该 bean 的属性具有相同类型的 bean。如果有多个 bean 符合条件,则抛出错误。
④ constructor:这个方式类似于 byType,但是要提供给构造器参数,如果没有确定的带参数的构造器参数类型,将会抛出异常。
⑤ autodetect:首先尝试使用 constructor 来自动装配,如果无法工作,则使用byType 方式。

26. 如何开启基于注解的自动装配?
要使用 @Autowired,需要注册 AutowiredAnnotationBeanPostProcessor,可以有
以下两种方式来实现:
① 引入配置文件中的<bean>下引入 <context:annotation-config>
② 在 bean 配置文件中直接引入 AutowiredAnnotationBeanPostProcessor

27. 自动装配有哪些局限性?
自动装配的局限性是:
① 重写:你仍需用<constructor-arg>和<property>配置来定义依赖,意味着总要重
写自动装配。
② 基本数据类型:你不能自动装配简单的属性,如基本数据类型,String 字符串,和
类。
③ 模糊特性:自动装配不如显式装配精确,如果有可能,建议使用显式装配。

28. 你可以在 Spring 中注入一个 null 和一个空字符串吗?
可以。

29. 什么是基于 Java 的 Spring 注解配置?
给一些注解的例子. 基于 Java 的配置,允许你在少量的 Java 注解的帮助下,进行你的大部分 Spring 配置
而非通过 XML 文件。
以@Configuration 注解为例,它用来标记类可以当做一个 bean 的定义,被 SpringIOC容器使用。另一个例子是@Bean 注解,它表示此方法将要返回一个对象,作为一个 bean注册进 Spring 应用上下文。

30. 什么是基于注解的容器配置?
相对于 XML 文件,注解型的配置依赖于通过字节码元数据装配组件,而非尖括号的声
明。
开发者通过在相应的类,方法或属性上使用注解的方式,直接组件类中进行配置,而不是使用 xml 表述 bean 的装配关系。

31. 怎样开启注解装配?
注解装配在默认情况下是不开启的,为了使用注解装配,我们必须在 Spring 配置文件中配置<context:annotation-config/>元素。

32. @Required 注解
这个注解表明 bean 的属性必须在配置的时候设置,通过一个 bean 定义的显式的属性值或通过自动装配,若@Required 注解的 bean 属性未被设置,容器将抛出BeanInitializationException。

33. @Autowired 注解
@Autowired 注解提供了更细粒度的控制,包括在何处以及如何完成自动装配。它的用法和@Required 一样,修饰 setter 方法、构造器、属性或者具有任意名称和/或多个参数的 PN 方法。

34. @Qualifier 注解
当有多个相同类型的 bean 却只有一个需要自动装配时,将@Qualifier 注解和@Autowire 注解结合使用以消除这种混淆,指定需要装配的确切的 bean。

35. 在 Spring 框架中如何更有效地使用 JDBC?
使用 SpringJDBC 框架,资源管理和错误处理的代价都会被减轻。所以开发者只需写statements 和 queries 从数据存取数据,JDBC 也可以在 Spring 框架提供的模板类的帮助下更有效地被使用,这个模板叫 JdbcTemplate(例子见这里 here)

36. JdbcTemplate
JdbcTemplate 类提供了很多便利的方法解决诸如把数据库数据转变成基本数据类型或对象,执行写好的或可调用的数据库操作语句,提供自定义的数据错误处理。

37. Spring 对 DAO 的支持
Spring 对数据访问对象(DAO)的支持旨在简化它和数据访问技术如 JDBC,HibernateorJDO 结合使用。这使我们可以方便切换持久层。编码时也不用担心会捕获每种技术特有的异常。

38. 使用 Spring 通过什么方式访问 Hibernate?
在 Spring 中有两种方式访问 Hibernate:
① 控制反转 HibernateTemplate 和 Callback。
② 继承 HibernateDAOSupport 提供一个 AOP 拦截器。

39. Spring 支持的 ORM
Spring 支持以下 ORM:
① Hibernate
② iBatis
③ JPA(JavaPersistenceAPI)
④ TopLink
⑤ JDO(JavaDataObjects)
⑥ OJB

40. 如何通过 HibernateDaoSupport 将 Spring 和 Hibernate 结合起
来?
用 Spring 的 SessionFactory 调用 LocalSessionFactory。集成过程分三步:
配置 theHibernateSessionFactory。
继承 HibernateDaoSupport 实现一个 DAO。
在 AOP 支持的事务中装配。

41. Spring 支持的事务管理类型
Spring 支持两种类型的事务管理:
① 编程式事务管理:这意味你通过编程的方式管理事务,给你带来极大的灵活性,但是难维护。
② 声明式事务管理:这意味着你可以将业务代码和事务管理分离,你只需用注解和XML 配置来管理事务。

42. Spring 框架的事务管理有哪些优点?
它为不同的事务 API 如 JTA,JDBC,Hibernate,JPA 和 JDO,提供一个不变的编程模式。
它为编程式事务管理提供了一套简单的 API 而不是一些复杂的事务 API 如它支持声明式事务管理。它和 Spring 各种数据访问抽象层很好得集成。

43. 你更倾向用那种事务管理类型?
大多数 Spring 框架的用户选择声明式事务管理,因为它对应用代码的影响最小,因此更符合一个无侵入的轻量级容器的思想。声明式事务管理要优于编程式事务管理,虽然比编程式事务管理(这种方式允许你通过代码控制事务)少了一点灵活性。

44. Spring 中的设计模式?
设计模式 一句话归纳
工厂模式(Factory) 只对结果负责, 不要三无产品。
单例模式(Singleton) 保证独一无二。
适配器模式(Adapter) 需要一个转换头(兼容) 。
装饰器模式(Decorator) 需要包装, 但不改变本质(同宗同源)。
代理模式(Proxy) 办事要求人, 所以找代理。
观察者模式(Observer) 完成时通知我。
策略模式(Strategy) 我行我素, 达到目的就行。
模板模式(Template) 流程标准化, 原料自己加。
委派模式(Delegate)
干活是你的(普通员工) , 功劳是我的(项目经理) 。原型模式(Prototype) 拔一根猴毛, 吹出千万个。

45. 编程思想总结
Spring 思想
应用场景(特点) 一句话归纳AOP
Aspect Oriented Programming(面向切面编程)找出多个类中有一定规律的代码, 开发时拆开, 运行时再合并。面向切面编程, 即面向规则编程。解耦, 专人做专事。
OOP Object Oriented Programming(面向对象编程)归纳总结生活中一切事物。封装、 继承、多态。
BOP Bean Oriented Programming(面向 Bean 编程)面向 Bean(普通的 java 类) 设计程序。一 切 从Bean 开始。
IOC,Inversion of Control(控制反转)将 new 对象的动作交给 Spring 管理, 并由 Spring 保存已创建的对象(IOC 容器) 。转 交 控 制 权( 即 控 制 权反转)。
DI/DL
Dependency Injection ( 依 赖 注 入 ) 或 者Dependency Lookup(依赖查找)依赖注入、 依赖查找, Spring 不仅保存自己创建的对象, 而且保存对象与对象之间的关系。注入即赋值, 主要三种方式构造方法、 set 方法、 直接赋值。先 理 清 关 系再赋值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值