欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【温故而知新】Java Spring回顾(十一)

程序员文章站 2022-04-11 19:02:54
...

1、不同版本的 Spring Framework 有哪些主要功能? 

Version 

Spring 2.5 发布于 2007 年。这是第一个支持注解的版本。 

Spring 3.0 发布于 2009 年。它完全利用了 Java5 中的改进,并为 JEE6 提供了支 持 

Spring 4.0 发布于 2013 年。这是第一个完全支持 JAVA8 的版本。

Spring 5.0 发布于 2017 年。 Spring Framework 5.0的最大特点之一是响应式编程(Reactive Programming)。

响应式编程核心功能和对响应式endpoints的支持可通过Spring Framework 5.0中获得。 

  
2、什么是 Spring Framework? 

 

Spring 是一个开源应用框架,旨在降低应用程序开发的复杂度。它是轻量级、松散耦合的。

它具有分层体系结构,允许用户选择组件,同时还为 J2EE 应用程序开发提供了一个有凝聚力的框架。

它可以集成其他框架,如 Structs、Hibernate、EJB 等,所以又称为框架的框架。 


3、列举 Spring Framework 的优点。 

 

由于 Spring Frameworks 的分层架构,用户可以*选择自己需要的组件。

Spring Framework 支持 POJO(Plain Old Java Object) 编程,从而具备持续集成和可测试性。

由于依赖注入和控制反转,JDBC得以简化。它是开源免费的。 
 

4、Spring Framework 有哪些不同的功能? 

 

轻量级 - Spring 在代码量和透明度方面都很轻便。

IOC - 控制反转 AOP - 面向切面编程可以将应用业务逻辑和系统服务分离,以实现高内聚。

容器 - Spring 负责创建和管理对象(Bean)的生命周期和配置。

MVC - 对 web 应用提供了高度可配置性,其他框架的集成也十分方便。

事务管理 - 提供了用于事务管理的通用抽象层。Spring 的事务支持也可用于容器较少的环境。

JDBC 异常 - Spring的 JDBC 抽象层提供了一个异常层次结构,简化了错误处理策略。 

  

5、Spring Framework 中有多少个模块,它们分别是什么? 


Spring 核心容器 - 该层基本上是 Spring Framework 的核心。

它包含以下模块: 
_ Spring Core 
_ Spring Bean 
_ SpEL (Spring Expression Language) 
_ Spring Context 

数据访问/集成 - 该层提供与数据库交互的支持。

它包含以下模块: 
_ JDBC (Java DataBase Connectivity) 
_ ORM (Object Relational Mapping) 
_ OXM (Object XML Mappers) 
_ JMS (Java Messaging Service) 
_ Transaction 

 Web - 该层提供了创建 Web 应用程序的支持。

它包含以下模块: 


Web 

Web - Servlet 
Web - Socket 
Web - Portlet 

AOP 

该层支持面向切面编程 

Instrumentation 

该层为类检测和类加载器实现提供支持。 

Test 


该层为使用 JUnit 和 TestNG 进行测试提供支持。 

几个杂项模块: 

Messaging - 该模块为 STOMP 提供支持。

它还支持注解编程模型,该模型用于从 WebSocket 客户端路由和处理 STOMP 消息。

Aspects - 该模块为与 AspectJ 的集成提供支持。 

  

6、什么是 Spring 配置文件? 

 

Spring 配置文件是 XML 文件。该文件主要包含类信息。

它描述了这些类是如何配置以及相互引入的。 

但是,XML 配置文件冗长且更加干净。

如果没有正确规划和编写,那么在大项目中管理变得非常困难。

  

7、Spring 应用程序有哪些不同组件? 

 

Spring 应用一般有以下组件: 
_ 接口 - 定义功能。 
_ Bean 类 - 它包含属性,setter 和 getter 方法,函数等。 
_ Spring 面向切面编程(AOP) - 提供面向切面编程的功能。 
_ Bean 配置文件 - 包含类的信息以及如何配置它们。 
_ 用户程序 - 它使用接口。 

  

8、使用 Spring 有哪些方式? 


使用 Spring 有以下方式: 

_ 作为一个成熟的 Spring Web 应用程序。 

_ 作为第三方 Web 框架,使用 Spring Frameworks 中间层。 

_ 用于远程使用。 

_ 作为企业级 Java Bean,它可以包装现有的 POJO(Plain Old Java Objects)。 

  

9、什么是 Spring IOC 容器? 

 

Spring 框架的核心是 Spring 容器。

容器创建对象,将它们装配在一起,配置它们并管理它们的完整生命周期。

Spring 容器使用依赖注入来管理组成应用程序的组件。

容器通过读取提供的配置元数据来接收对象进行实例化,配置和组装的指令。

该元数据可以通过 XML,Java 注解或 Java 代码提供。 

  

10、什么是依赖注入? 

 

在依赖注入中,不必创建对象,但必须描述如何创建它们。

不是直接在代码中将组件和服务连接在一起,而是描述配置文件中哪些组件需要哪些服务。

由 IoC容器将它们装配在一起。 
 
 
  

11、可以通过多少种方式完成依赖注入?

 

通常,依赖注入可以通过三种方式完成,即: 
_ 构造函数注入 
_ setter 注入 
_ 接口注入 
在 Spring Framework 中,仅使用构造函数和 setter 注入。 

  

12、区分构造函数注入和 setter 注入 

 

构造函数注入 

没有部分注入 

不会覆盖 setter 属性 

任意修改都会创建一个新实例 

适用于设置很多属性


setter 注入 

有部分注入 

会覆盖 setter 属性 

任意修改不会创建一个新实例 

适用于设置少量属性 
  

13、spring 中有多少种 IOC 容器? 

 

BeanFactory - BeanFactory 就像一个包含 bean 集合的工厂类。

它会在客户端要求时实例化 bean。 

ApplicationContext - ApplicationContext 接口扩展了 BeanFactory 接口。

它在 BeanFactory 基础上提供了一些额外的功能。 

  

14、区分 BeanFactory 和 ApplicationContext。 

 

BeanFactory 

它使用懒加载 

它使用语法显式提供资源对象 

不支持国际化 

不支持基于依赖的注解 

ApplicationContext 

它使用即时加载 

它自己创建和管理资源对象 

支持国际化 

支持基于依赖的注解 
  

15、列举 IoC 的一些好处。 

 

IoC 的一些好处是: 
_ 它将最小化应用程序中的代码量。 
_ 它将使您的应用程序易于测试,因为它不需要单元测试用例中的任何单例或 JNDI 查找机制。 
_ 它以最小的影响和最少的侵入机制促进松耦合。 
_ 它支持即时的实例化和延迟加载服务。 

  
16、Spring IoC 的实现机制。 

 

Spring 中的 IoC 的实现原理就是工厂模式加反射机制。 

实例: 


    interface Fruit {
        public abstract void eat();
    }

    class Apple implements Fruit {
        public void eat(){
            System.out.println("Apple");
        }
    }

    class Orange implements Fruit {
        public void eat(){
            System.out.println("Orange");
        }
    }

    class Factory {
        public static Fruit getInstance(String ClassName) {
            Fruit f=null;
            try {
                f=(Fruit)Class.forName(ClassName).newInstance();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return f;
        }
    }
    class Client {
        public static void main(String[] a) {
            Fruit f=Factory.getInstance("io.github.dunwu.spring.Apple");
            if(f!=null){
                f.eat();
            }
        }
    }


  

17、什么是 spring bean? 

 

_ 它们是构成用户应用程序主干的对象。 
_ Bean 由 Spring IoC 容器管理。 
_ 它们由 Spring IoC 容器实例化,配置,装配和管理。 
_ Bean 是基于用户提供给容器的配置元数据创建。 

  

18、spring 提供了哪些配置方式? 


 
 基于 xml 配置 
bean 所需的依赖项和服务在 XML 格式的配置文件中指定。

这些配置文件通常包含许多 bean 定义和特定于应用程序的配置选项。它们通常以 bean 标签开头。

例如: 

<bean id="studentbean" class="org.edureka.firstSpring.StudentBean"> 
<property name="name" value="Edureka"></property> 
</bean> 


基于注解配置 
您可以通过在相关的类,方法或字段声明上使用注解,将 bean 配置为组件类本身,而不是使用 XML来描述 bean 装配。

默认情况下,Spring 容器中未打开注解装配。因此,您需要在使用它之前在Spring 配置文件中启用它。

例如: 

<beans> 
   <context:annotation-config/> 
   <!-- bean definitions go here --> 
</beans> 


基于 Java API 配置 
Spring 的 Java 配置是通过使用 @Bean 和 @Configuration 来实现。 
1、 @Bean 注解扮演与  元素相同的角色。 
2、 @Configuration 类允许通过简单地调用同一个类中的其他 @Bean 方法来定义 bean 间依赖关系。 

例如: 

@Configuration 
public class StudentConfig { 
   @Bean 
   public StudentBean myStudent() { 
      return new StudentBean(); 
   } 
} 

 

 19、spring 支持集中 bean scope? 

 

Spring bean 支持 5 种 scope:

Singleton - 每个 Spring IoC 容器仅有一个单实例。Prototype - 每次请求都会产生一个新的实例。 

Request - 每一次 HTTP 请求都会产生一个新的实例,并且该 bean 仅在当前 HTTP 请求内有效。 

Session - 每一次 HTTP 请求都会产生一个新的 bean,同时该 bean 仅在当前 HTTP session 内有效。 

Global-session - 类似于标准的 HTTP Session 作用域,不过它仅仅在基于portlet 的 web 应用中才有意义。

Portlet 规范定义了全局 Session 的概念,它被所有构成某个 portlet web 应用的各种不同的 portlet 所共享。

在 globalsession 作用域中定义的bean 被限定于全局 portlet Session 的生命周期范围内。

如果你在 web 中使用 global session 作用域来标识 bean,那么 web会自动当成 session 类型来使用。  

仅当用户使用支持 Web 的 ApplicationContext 时,最后三个才可用。 

  

20、spring bean 容器的生命周期是什么样的? 

 
spring bean 容器的生命周期流程如下: 

1、Spring 容器根据配置中的 bean 定义中实例化 bean。 

2、Spring 使用依赖注入填充所有属性,如 bean 中所定义的配置。 

3、如果 bean 实现BeanNameAware 接口,则工厂通过传递 bean 的 ID 来调用setBeanName()。 

4、如果 bean 实现 BeanFactoryAware 接口,工厂通过传递自身的实例来调用 setBeanFactory()。 

5、如果存在与 bean 关联的任何BeanPostProcessors,则调用 preProcessBeforeInitialization() 方法。 

6、如果为 bean 指定了 init 方法(  的 init-method 属性),那么将调用它。 

7、最后,如果存在与 bean 关联的任何 BeanPostProcessors,则将调用postProcessAfterInitialization() 方法。

8、如果 bean 实现DisposableBean 接口,当 spring 容器关闭时,会调用 destory()。 

9、如果为bean 指定了 destroy 方法(  的 destroy-method 属性),那么将调用它。 

  

21、什么是 spring 的内部 bean?

 

只有将 bean 用作另一个 bean 的属性时,才能将 bean 声明为内部 bean。

为了定义 bean,Spring 的基于 XML 的配置元数据在  或 中提供了  元素的使用。

内部 bean 总是匿名的,它们总是作为原型。 

例如,假设我们有一个 Student 类,其中引用了 Person 类。

这里我们将只创建一个 Person 类实例并在 Student 中使用它。 


Student.java 

public class Student { 
   private Person person; 
   //Setters and Getters 
} 
public class Person { 
   private String name; 
   private String address; 
   //Setters and Getters 
} 

bean.xml 

<bean id="StudentBean" class="com.edureka.Student"> 
   <property name="person"> 
        <!--This is inner bean --> 
    <bean class="com.edureka.Person"> 
           <property name="name" value="Scott"></property> 
           <property name="address" value= "Bangalore"></property>   
    </bean> 
   </property> 
</bean>

 

22、什么是 spring 装配 

 

当 bean 在 Spring 容器中组合在一起时,它被称为装配或 bean 装配。

Spring容器需要知道需要什么bean 以及容器应该如何使用依赖注入来将 bean 绑定在一起,同时装配 bean。 

  

23、自动装配有哪些方式? 

 

Spring 容器能够自动装配 bean。也就是说,可以通过检查 BeanFactory 的内容让 Spring 自动解析bean 的协作者。 

自动装配的不同模式: 
 

no - 这是默认设置,表示没有自动装配。应使用显式 bean 引用进行装配。

byName - 它根据 bean 的名称注入对象依赖项。它匹配并装配其属性与 XML文件中由相同名称定义的 bean。

byType - 它根据类型注入对象依赖项。如果属性的类型与 XML 文件中的一个 bean 名称匹配,则匹配并装配属性。

构造函数- 它通过调用类的构造函数来注入依赖项。它有大量的参数。

autodetect - 首先容器尝试通过构造函数使用 autowire 装配,如果不能,则尝试通过 byType 自动装配 。

  

24、自动装配有什么局限? 

 

覆盖的可能性 - 您始终可以使用  和  设置指定依赖项,这将覆盖自动装配。

基本元数据类型 - 简单属性 (如原数据类型,字符串和类)无法自动装配。

令人困惑的性质 - 总是喜欢使用明确的装配,因为自动装配不太精确。 

  

25、什么是基于注解的容器配置 

 

不使用 XML 来描述 bean 装配,开发人员通过在相关的类,方法或字段声明上使用注解将配置移动到组件类本身。

它可以作为 XML 设置的替代方案。

例如:Spring 的 Java 配置是通过使用 @Bean 和 @Configuration 来实现。  

@Bean 注解扮演与 元素相同的角色。

@Configuration 类允许通过简单地调用同一个类中的其他 @Bean 方法来定义 bean 间依赖关系。 


例如:

@Configuration 
public class StudentConfig { 
   @Bean 
   public StudentBean myStudent() { 
      return new StudentBean();
   } 
} 


 

26、如何在 spring 中启动注解装配? 


默认情况下,Spring 容器中未打开注解装配。

因此,要使用基于注解装配,我们必须通过配置 <context:annotation-config/> 元素在 Spring 配置文件中启用它。 

  

27、 @Component, @Controller, @Repository,@Service 有何区别? 

 

@Component :这将 java 类标记为 bean。它是任何 Spring 管理组件的通用构造型。

spring 的组件扫描机制现在可以将其拾取并将其拉入应用程序环境中。 

@Controller :这将一个类标记为 Spring Web MVC 控制器。标有它的Bean 会自动导入到 IoC 容器中。 

@Service :此注解是组件注解的特化。它不会对 @Component 注解提供任何其他行为。

您可以在服务层类中使用 @Service 而不是 @Component,因为它以更好的方式指定了意图。 

@Repository :这个注解是具有类似用途和功能的 @Component 注解的特化。

它为 DAO 提供了额外的好处。

它将 DAO 导入 IoC 容器,并使未经检查的异常有资格转换为 Spring DataAccessException。 

  

28、 @Required 注解有什么用? 

 

@Required 应用于 bean 属性 setter 方法。

此注解仅指示必须在配置时使用bean 定义中的显式属性值或使用自动装配填充受影响的 bean 属性。

如果尚未填充受影响的 bean 属性,则容器将抛出 BeanInitializationException。 

示例: 
 

public class Employee { 
   private String name; 
   @Required 
   public void setName(String name){ 
      this.name=name; 
   } 

   public string getName(){ 
     return name; 
   } 
} 

  

29、 @Autowired 注解有什么用? 

 

@Autowired 可以更准确地控制应该在何处以及如何进行自动装配。

此注解用于在 setter 方法,构造函数,具有任意名称或多个参数的属性或方法上自动装配bean。

默认情况下,它是类型驱动的注入。 

public class Employee { 
   private String name; 
   @Autowired 
   public void setName(String name) { 
      this.name=name; 
   } 

   public string getName(){ 
        return name; 
   } 
} 


  

30、 @Qualifier 注解有什么用? 


当您创建多个相同类型的 bean 并希望仅使用属性装配其中一个 bean 时,

您可以使用 @Qualifier 注解 和 @Autowired 通过指定应该装配哪个确切的 bean 来消除歧义。 

例如,这里我们分别有两个类,Employee 和 EmpAccount。在 EmpAccount中,

使用 @Qualifier 指定了必须装配 id 为 emp1 的 bean。 

Employee.java 

public class Employee { 
   private String name; 
   @Autowired 
   public void setName(String name) { 
      this.name=name; 
   } 

   public string getName() { 
      return name; 
   } 
} 

EmpAccount.java 

public class EmpAccount { 
   private Employee emp; 
   @Autowired 
   @Qualifier(emp1) 
   public void showName() { 
     System.out.println("Employee name : "+emp.getName); 
   } 
} 

  

 

31、 @RequestMapping 注解有什么用? 

 

@RequestMapping 注解用于将特定 HTTP 请求方法映射到将处理相应请求的控制器中的特定类/方法。

此注释可应用于两个级别: 

类级别:映射请求的 URL

方法级别:映射 URL 以及 HTTP 请求方法 

  

32、spring DAO 有什么用? 

 

Spring DAO 使得 JDBC,Hibernate 或 JDO 这样的数据访问技术更容易以一种统一的方式工作。

这使得用户容易在持久性技术之间切换。

它还允许您在编写代码时,无需考虑捕获每种技术不同的异常。 

  
33、列举 Spring DAO 抛出的异常。 
 
 

【温故而知新】Java Spring回顾(十一)


  

34、spring JDBC API 中存在哪些类? 

 

_ JdbcTemplate 

_ SimpleJdbcTemplate 

_ NamedParameterJdbcTemplate 

_ SimpleJdbcInsert 

_ SimpleJdbcCall 


35、使用 Spring 访问 Hibernate 的方法有哪些? 


我们可以通过两种方式使用 Spring 访问 Hibernate: 

1、 使用 Hibernate 模板和回调进行控制反转 

2、 扩展 HibernateDAOSupport 并应用 AOP 拦截器节点 


36、列举 spring 支持的事务管理类型 

 

Spring 支持两种类型的事务管理: 

1、 程序化事务管理:在此过程中,在编程的帮助下管理事务。它为您提供极大的灵活性,但维护起来非常困难。 

2、 声明式事务管理:在此,事务管理与业务代码分离。仅使用注解或基于 XML的配置来管理事务。 

  

37、spring 支持哪些 ORM 框架 

 

_ Hibernate 
_ iBatis 
_ JPA 
_ JDO 
_ OJB 

  

38、什么是 AOP? 

 

AOP(Aspect-Oriented Programming), 即面向切面编程,

它与OOP( Object-Oriented Programming, 面向对象编程) 相辅相成,

提供了与OOP 不同的抽象软件结构的视角. 在 OOP 中,

我们以类(class)作为我们的基本单元, 而 AOP 中的基本单元是 Aspect(切面) 

  

39、什么是 Aspect? 

 

aspect 由 pointcount 和 advice 组成, 它既包含了横切逻辑的定义, 也包括了连接点的定义.

Spring AOP 就是负责实施切面的框架, 它将切面所定义的横切逻辑编织到切面所指定的连接点中.

AOP 的工作重心在于如何将增强编织目标对象的连接点上,

这里包含两个工作: 


1、如何通过 pointcut 和 advice 定位到特定的 joinpoint 上 

2、如何在advice 中编写切面代码.以简单地认为, 使用 @Aspect 注解的类就是切面. 

  

40、什么是切点(JoinPoint) 

 

程序运行中的一些时间点, 例如一个方法的执行, 或者是一个异常的处理.

在 Spring AOP 中, join point 总是方法的执行点。 
 
 
  

41、什么是通知(Advice)? 

 

特定 JoinPoint 处的 Aspect 所采取的动作称为 Advice。

Spring AOP 使用一个 Advice 作为拦截器,在 JoinPoint "周围"维护一系列的拦截器。 

  

42、有哪些类型的通知(Advice)? 

 

_ Before - 这些类型的 Advice 在 joinpoint 方法之前执行,并使用 @Before 注解标记进行配置。 

_ After Returning - 这些类型的 Advice 在连接点方法正常执行后执行,并使用 @AfterReturning 注解标记进行配置。 

_ After Throwing - 这些类型的 Advice 仅在 joinpoint 方法通过抛出异常退出并使用 @AfterThrowing注解标记配置时执行。 

_ After (finally) - 这些类型的 Advice 在连接点方法之后执行,无论方法退出是正常还是异常返回,

   并使用 @After 注解标记进行配置。 

_ Around - 这些类型的 Advice 在连接点之前和之后执行,并使用 @Around 注解标记进行配置。 

  

43、指出在 spring aop 中 concern 和 cross-cuttingconcern 的不同之处。 

 

concern 是我们想要在应用程序的特定模块中定义的行为 。 它可以定义为我们想要实现的功能。 

cross-cutting concern 是一个适用于整个应用的行为 ,这会影响整个应用程序。

例如 ,日志记录,安全性和数据传输是应用程序几乎每个模块都需要关注的问题,因此它们是跨领域的问题。

  

44、AOP 有哪些实现方式? 


实现 AOP 的技术 ,主要分为两大类 : 

静态代理 

指使用 AOP 框架提供的命令进行编译,从而在编译阶段就可生成 AOP 代理类,因此也称为编译时增强; 
_ 编译时编织(特殊编译器实现) 
_ 类加载时编织(特殊的类加载器实现)。 

动态代理 

在运行时在内存中"临时"生成 AOP 动态代理类,因此也被称为运行时增强。 
_ JDK 动态代理 
_ CGLIB 
  

45、Spring AOP and AspectJ AOP 有什么区别?

 

Spring AOP 基于动态代理方式实现;

AspectJ 基于静态代理方式实现。

SpringAOP 仅支持方法级别的PointCut;

提供了完全的 AOP 支持,它还支持属性级别的 PointCut。 

  
 
 
46、如何理解 Spring 中的代理? 

 

将 Advice 应用于目标对象后创建的对象称为代理。

在客户端对象的情况下,目标对象和代理对象是相同的。 

Advice + Target Object = Proxy 

  

47、什么是编织(Weaving)? 

 

为了创建一个 advice 对象而链接一个 aspect 和其它应用类型或对象,称为编织(Weaving)。

在Spring AOP中,编织在运行时执行。


48、Spring MVC 框架有什么用? 

 

Spring Web MVC 框架提供 模型-视图-控制器 架构和随时可用的组件,用于开发灵活且松散耦合的Web 应用程序。

MVC 模式有助于分离应用程序的不同方面,如输入逻辑,业务逻辑和 UI 逻辑,

同时在所有这些元素之间提供松散耦合。 

  
49、描述一下 DispatcherServlet 的工作流程 

 

DispatcherServlet 的工作流程可以用一幅图来说明: 
 

【温故而知新】Java Spring回顾(十一)


 
1、向服务器发送 HTTP 请求,请求被前端控制器 DispatcherServlet 捕获。 

2、 DispatcherServlet 根据 -servlet.xml 中的配置对请求的 URL 进行解析,得到请求资源标识符(URI)。

然后根据该 URI,调用 HandlerMapping获得该 Handler 配置的所有相关的对象(包括 Handler 对象以及 Handler 对象对应的拦截器),最后以 HandlerExecutionChain 对象的形式返回。 

3、 DispatcherServlet 根据获得的 Handler,选择一个合适的HandlerAdapter。

(附注:如果成功获得 HandlerAdapter 后,此时将开始执行拦截器的 preHandler(...)方法)。 

4、提取 Request 中的模型数据,填充 Handler 入参,开始执行 Handler( Controller)。

     在填充Handler 的入参过程中,根据你的配置,

Spring 将帮你做一些额外的工作: 

_ HttpMessageConveter:将请求消息(如 Json、xml 等数据)转换成一个对象,将对象转换为指定的响应信息。  
_ 数据转换:对请求消息进行数据转换。如 String 转换成 Integer、Double 等。 
_ 数据根式化:对请求消息进行数据格式化。如将字符串转换成格式化数字或格式化日期等。 
_ 数据验证:验证数据的有效性(长度、格式等),验证结果存储到BindingResult 或 Error 中。 

5、Handler(Controller)执行完成后,向 DispatcherServlet 返回一个ModelAndView 对象; 

6、根据返回的 ModelAndView,选择一个适合的 ViewResolver(必须是已经注册到 Spring 容器中的ViewResolver) 返回给               DispatcherServlet。 

7、 ViewResolver 结合 Model 和 View,来渲染视图。 

8、视图负责将渲染结果返回给客户端。 


50、介绍一下 WebApplicationContext 


WebApplicationContext 是 ApplicationContext 的扩展。

它具有 Web 应用程序所需的一些额外功能。

它与普通的 ApplicationContext 在解析主题和决定与哪个 servlet 关联的能力方面有所不同。 

  

51、什么是 spring? 

 
Spring 是个 java 企业级应用的开源开发框架。

Spring 主要用来开发 Java 应用,但是有些扩展是针对构建 J2EE 平台的 web 应用。

Spring 框架目标是简化 Java企业级应用开发,并通过 POJO 为基础的编程模型促进良好的编程习惯。 

  

52、使用 Spring 框架的好处是什么? 

 

_ 轻量:Spring 是轻量的,基本的版本大约 2MB。 

_ 控制反转:Spring 通过控制反转实现了松散耦合,对象们给出它们的依赖,而不是创建或查找依赖的对象们。 

_ 面向切面的编程(AOP):Spring 支持面向切面的编程,并且把应用业务逻辑和系统服务分开。 

_ 容器:Spring 包含并管理应用中对象的生命周期和配置。 

_ MVC 框架:Spring 的 WEB 框架是个精心设计的框架,是 Web 框架的一个很好的替代品。 

_ 事务管理:Spring 提供一个持续的事务管理接口,可以扩展到上至本地事务下至全局事务(JTA)。 

_ 异常处理:Spring 提供方便的API把具体技术相关的异常

(比如由JDBC,Hibernate or JDO 抛出的)转化为一致的 unchecked 异常。 

  

53、Spring 由哪些模块组成? 

 

以下是 Spring 框架的基本模块: 

_ Core module 

_ Bean module 

_ Context module 

_ Expression Language module 

_ JDBC module 

_ ORM module 

_ OXM module 

_ Java Messaging Service(JMS) module 

_ Transaction module 

_ Web module 

_ Web-Servlet module 

_ Web-Struts module 

_ Web-Portlet module 

  

54、Spring的IOC和AOP机制

 

我们是在使用Spring框架的过程中,其实就是为了使用IOC:依赖注入,和AOP:面向切面编程,这两个是Spring的灵魂。 

主要用到的设计模式有工厂模式和代理模式。 
IOC就是典型的工厂模式,通过sessionfactory去注入实例。 

AOP就是典型的代理模式的体现。 

代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,

代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。

代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,

代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务 
 
 spring的IoC容器是spring的核心,spring AOP是spring框架的重要组成部分。 

在传统的程序设计中,当调用者需要被调用者的协助时,通常由调用者来创建被调用者的实例。

但在spring里创建被调用者的工作不再由调用者来完成,因此控制反转(IoC);

创建被调用者实例的工作通常由spring容器来完成,然后注入调用者,因此也被称为依赖注入(DI),依赖注入和控制反转是同一个概念。 

面向方面编程(AOP)是以另一个角度来考虑程序结构,通过分析程序结构的关注点来完善面向对象编程(OOP)。

OOP将应用程序分解成各个层次的对象,而AOP将程序分解成多个切面。

spring AOP 只实现了方法级别的连接点,在J2EE应用中,AOP拦截到方法级别的操作就已经足够。

在spring中,未来使IoC方便地使用健壮、灵活的企业服务,需要利用spring AOP实现为IoC和企业服务之间建立联系。 

IOC: 控制反转也叫依赖注入。

利用了工厂模式 
将对象交给容器管理,你只需要在spring配置文件总配置相应的bean,以及设置相关的属性,

让spring容器来生成类的实例对象以及管理对象。在spring容器启动的时候,

spring会把你在配置文件中配置的bean都初始化好,然后在你需要调用的时候,

就把它已经初始化好的那些bean分配给你需要调用这些bean的类(假设这个类名是A),

分配的方法就是调用A的setter方法来注入,而不需要你在A里面new这些bean了。 

AOP:面向切面编程。(Aspect-Oriented Programming) 

AOP可以说是对OOP的补充和完善。

OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。

当我们需要为分散的对象引入公共行为的时候,OOP则显得无能为力。 

也就是说,OOP允许你定义从上到下的关系,但并不适合定义从左到右的关系。

例如日志功能。日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系。

在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。

将程序中的交叉业务逻辑(比如安全,日志,事务等),封装成一个切面,然后注入到目标对象(具体业务逻辑)中去。 

实现AOP的技术,

主要分为两大类:

一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;

二是采用静态织入的方式,引入特定的语法创建"方面",从而使得编译器可以在编译期间织入有关"方面"的代码. 

简单点解释,比方说你想在你的biz层所有类中都加上一个打印'你好'的功能,这时就可以用aop思想来做. 

你先写个类写个类方法,方法经实现打印'你好',

然后Ioc这个类 ref="biz.*"让每个类都注入即可实现

 

55、Spring中Autowired和Resource关键字的区别 

 

@Resource和 @Autowired都是做bean的注入时使用,其实 @Resource并不是Spring的注解,

它的包是javax.annotation.Resource,需要导入,但是Spring支持该注解的注入。

 1、共同点 
       两者都可以写在字段和setter方法上。两者如果都写在字段上,那么就不需要再写setter方法。 
2、不同点 
   (1) @Autowired 

             @Autowired为Spring提供的注解,需要导入包 org.springframework.beans.factory.annotation.Autowired;

              只按照byType注入 
 

public class TestServiceImpl { 
   //   下面两种 @Autowired只要使用一种即可 
   @Autowired 
   private UserDao userDao; //   用于字段上 
   @Autowired 
   public void setUserDao(UserDao userDao) { //   用于属性的方法上 
     this.userDao = userDao; 
   } 
} 

@Autowired注解是按照类型(byType)装配依赖对象,默认情况下它要求依赖对象必须存在,

如果允许null值,可以设置它的required属性为false。

如果我们想使用按照名称(byName)来装配,

可以结合 @Qualifier注解一起使用。如下:

public class TestServiceImpl { 
   @Autowired 
   @Qualifier("userDao") 
   private UserDao userDao; 
} 


(2) @Resource 

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

 @Resource 有两个重要的属性:name和type,而Spring将 @Resource注解的name属性解析为bean的名字,

而type属性则解析为bean的类型。

所以,如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。

如果既不制定name也不制定type属性,这时将通过反射机制使用byName自动注入策略
 

public class TestServiceImpl { 
   //   下面两种 @Resource只要使用一种即可 
   @Resource(name="userDao") 
   private UserDao userDao; //   用于字段上 
   @Resource(name="userDao") 
   public void setUserDao(UserDao userDao) { //   用于属性的setter方法上 
       this.userDao = userDao; 
   }

}

注:最好是将 @Resource放在setter方法上,因为这样更符合面向对象的思想,

通过set、get去操作属性,而不是直接去操作属性。 

@Resource装配顺序: 

①如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常。 

②如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常。 

③如果指定了type,则从上下文中找到类似匹配的唯一bean进行装配,找不到或是找到多个,都会抛出异常 

④如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配。

@Resource的作用相当于 @Autowired,只不过@Autowired按照byType自动注入 

  

 
 
56、依赖注入的方式有几种,各是什么? 

 

一、构造器注入 


将被依赖对象通过构造函数的参数注入给依赖对象,并且在初始化对象的时候注入。 


优点: 

对象初始化完成后便可获得可使用的对象。 

缺点: 

当需要注入的对象很多时,构造器参数列表将会很长;不够灵活。若有多种注入方式,

每种方式只需注入指定几个依赖,那么就需要提供多个重载的构造函数,麻烦。 


二、setter方法注入 


IoC Service Provider通过调用成员变量提供的setter函数将被依赖对象注入给依赖类。 


优点: 

灵活。可以选择性地注入需要的对象。 

缺点: 

依赖对象初始化完成后由于尚未注入被依赖对象,因此还不能使用。

 
三、接口注入 


依赖类必须要实现指定的接口,然后实现该接口中的一个函数,该函数就是用于依赖注入。

该函数的参数就是要注入的对象 

优点 

接口注入中,接口的名字、函数的名字都不重要,只要保证函数的参数是要注入的对象类型即可。 

缺点: 

侵入行太强,不建议使用。 

PS:什么是侵入行? 

如果类A要使用别人提供的一个功能,若为了使用这功能,需要在自己的类中增加额外的代码,这就是侵入性 

  

57、讲一下什么是Spring 

 

Spring是一个轻量级的IoC和AOP容器框架。

是为Java应用程序提供基础性服务的一套框架,目的是用于简化企业应用程序的开发,它使得开发者只需要关心业务需求。

常见的配置方式有三种:基于XML的 配置、基于注解的配置、基于Java的配置。 


主要由以下几个模块组成: 

Spring Core:核心类库,提供IOC服务

Spring Context:提供框架式的Bean访问方式,以及企业级功能(JNDI、定时任务等)

Spring AOP:AOP服务

Spring DAO:对JDBC的抽象,简化了数据访问异常的处理

Spring ORM:对现有的ORM框架的支持; 

Spring Web:提供了基本的面向Web的综合特性,例如多方文件上传; 

Spring MVC:提供面向Web应用的Model-View-Controller实现。 

  
58、Spring MVC流程 

 

1、 用户发送请求至前端控制器DispatcherServlet。 

2、 DispatcherServlet收到请求调用HandlerMapping处理器映射器。 

3、 处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),

生成处理器对象及处理器拦截器 (如果有则生成)一并返回给DispatcherServlet。 

4、 DispatcherServlet调用HandlerAdapter处理器适配器。 

5、 HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。 

6、 Controller执行完成返回ModelAndView。 

7、 HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。 

8、 DispatcherServlet将ModelAndView传给ViewReslover视图解析器。 

9、 ViewReslover解析后返回具体View。 

10、DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。 

11、 DispatcherServlet响应用户 

组件说明: 

以下组件通常使用框架提供实现: 
DispatcherServlet:作为前端控制器,整个流程控制的中心,控制其它组件执行,统一调度,

降低组件之间的耦合性,提高每个组件的扩展性 

HandlerMapping:通过扩展处理器映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。

 HandlAdapter:通过扩展处理器适配器,支持更多类型的处理器。 

ViewResolver:通过扩展视图解析器,支持更多类型的视图解析,例如:jsp、freemarker、pdf、excel等。 

组件: 


1、前端控制器DispatcherServlet(不需要工程师开发),

由框架提供作用:接收请求,响应结果,相当于转发器,*处理器。有了dispatcherServlet减少了其它组件之间的耦合度。 

用户请求到达前端控制器,它就相当于mvc模式中的c,dispatcherServlet是整个流程控制的中心,

由它调用其它组件处理用户的请求,dispatcherServlet的存在降低了组件之间的耦合性。 

2、处理器映射器HandlerMapping(不需要工程师开发),由框架提供 

作用:根据请求的url查找Handler 

HandlerMapping负责根据用户请求找到Handler即处理器,

springmvc提供了不同的映射器实现不同的映射方式,

例如:配置文件方式,实现接口方式,注解方式等。 

3、处理器适配器HandlerAdapter 

作用:按照特定规则(HandlerAdapter要求的规则)去执行Handler 通过HandlerAdapter对处理器进行执行,

这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。 

4、处理器Handler(需要工程师开发) 

注意:编写Handler时按照HandlerAdapter的要求去做,这样适配器才可以去正确执行Handler 

Handler 是继DispatcherServlet前端控制器的后端控制器,

在DispatcherServlet的控制下Handler对具体的用户请求进行处理。 

由于Handler涉及到具体的用户业务请求,所以一般情况需要工程师根据业务需求开发Handler。 

5、视图解析器View resolver(不需要工程师开发),由框架提供 

作用:进行视图解析,根据逻辑视图名解析成真正的视图(view) 

View Resolver负责将处理结果生成View视图,

View Resolver首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成View视图对象,

最后对View进行渲染将处理结果通过页面展示给用户。 

springmvc框架提供了很多的View视图类型,包括:jstlView、freemarkerView、pdfView等。

一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展示给用户,

需要由工程师根据业务需求开发具体的页面。 

6、视图View(需要工程师开发jsp...) 

View是一个接口,实现类支持不同的View类型(jsp、freemarker、pdf...)

核心架构的具体流程步骤如下: 

1、首先用户发送请求——>DispatcherServlet,前端控制器收到请求后自己不进行处理,

而是委托给其他的解析器进行处理,作为统一访问点,进行全局的流程控制; 
 
2、DispatcherServlet——>HandlerMapping,

HandlerMapping 将会把请求映射为 HandlerExecutionChain 对象

(包含一个Handler 处理器(页面控制器)对象、多个HandlerInterceptor 拦截器)对象,

通过这种策略模式,很容易添加新的映射策略; 

3、DispatcherServlet——>HandlerAdapter,HandlerAdapter 将会把处理器包装为适配器,

从而支持多种类型的处理器,即适配器设计模式的应用,从而很容易支持很多类型的处理器; 

4、HandlerAdapter——>处理器功能处理方法的调用,HandlerAdapter 将会根据适配的结果调用真正的处理器的功能处理方法,完成功能处理;并返回一个ModelAndView 对象(包含模型数据、逻辑视图名); 

5、ModelAndView的逻辑视图名——> ViewResolver,

ViewResolver 将把逻辑视图名解析为具体的View,通过这种策略模式,很容易更换其他视图技术; 

6、View——>渲染,View会根据传进来的Model模型数据进行渲染,此处的Model实际是一个Map数据结构,

因此很容易支持其他视图技术; 

7、返回控制权给DispatcherServlet,由DispatcherServlet返回响应给用户,到此一个流程结束。

下边两个组件通常情况下需要开发: 

Handler:处理器,即后端控制器用controller表示。 

View:视图,即展示给用户的界面,视图中通常需要标签语言展示模型数据。 

  

59、springMVC是什么 

 

springMVC是一个MVC的开源框架,springMVC=struts2+spring,

springMVC就相当于是Struts2加上 sring的整合,但是这里有一个疑惑就是,

springMVC和spring是什么样的关系呢?

这个在百度百科上有一个很好的解释:意思是说,springMVC是spring的一个后续产品,

其实就是spring在原有基础上,又提供了web应用的MVC模块,

可以简单的把springMVC理解为是spring的一个模块(类似AOP,IOC这样的模块),

网络上经常会说springMVC和spring无缝集成,

其实springMVC就是spring的一个子模块,所以根本不需要同spring进行整合 

  

60、SpringMVC怎么样设定重定向和转发的? 

 

OOP面向对象,允许开发者定义纵向的关系,但并适用于定义横向的关系,

导致了大量代码的重复,而不利于各个模块的重用。 

AOP,一般称为面向切面,作为面向对象的一种补充,用于将那些与业务无关,

但却对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块,

这个模块被命名为"切面"(Aspect),减少系统中的重复代码,降低了模块间的耦合度,

同时提高了系统的可维护性。可用于权限认证、日志、事务 


( 1)转发:在返回值前面加"forward:",譬如"forward:user.do?name=method


( 2)重定向:在返回值前面加"redirect:",譬如"redirect:http://www.baidu.com" 

 

61、SpringMVC常用的注解有哪些 

 

@RequestMapping:用于处理请求 url 映射的注解,可用于类或方法上。

用于类上,则表示类中的所有响应请求的方法都是以该地址作为父路径。 

@RequestBody:注解实现接收http请求的json数据,将json转换为java对象。 

@ResponseBody:注解实现将conreoller方法返回对象转化为json对象响应给客户 

  
 62、Spring的AOP理解 


 OOP面向对象,允许开发者定义纵向的关系,

但并适用于定义横向的关系,导致了大量代码的重复,而不利于各个模块的重用。 


AOP,一般称为面向切面,作为面向对象的一种补充,用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块,

这个模块被命名为"切面"(Aspect),减少系统中的重复代码,降低了模块间的耦合度,同时提高了系统的可维护性。

可用于权限认证、日志、事务处理。 

AOP实现的关键在于代理模式,AOP代理主要分为静态代理和动态代理。

静态代理的代表为AspectJ; 

动态代理则以Spring AOP为代表。 

 

 (1)AspectJ是静态代理的增强,所谓静态代理,就是AOP框架会在编译阶段生成AOP代理类,因此也称为编译时增强,他会在编译阶段将AspectJ(切面)织入到Java字节码中,运行的时候就是增强之后的AOP对象。

 (2)Spring AOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改字节码,而是每次运行时在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。 

Spring AOP中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理 : 

①JDK动态代理只提供接口的代理,不支持类的代理。核心InvocationHandler接口和Proxy类, 

InvocationHandler 通过invoke()方法反射来调用目标类中的代码,动态地将横切逻辑和业务编织在一起;

接着,Proxy利用 InvocationHandler动态创建一个符合某一接口的的实例, 生成目标类的代理对象。 

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

CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动态的生成指定类的一个子类对象,

并覆盖其中特定方法并添加增强代码,从而实现AOP。CGLIB是通过继承的方式做的动态代理,

因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的

(3) 静态代理与动态代理区别在于生成AOP代理对象的时机不同,相对来说AspectJ的静态代理方式具有更好的性能,

但是AspectJ需要特定的编译器进行处理,而Spring AOP则无需特定的编译器处理。 

 

 

 

  
 

相关标签: JAVA