Spring 面试问题 TOP 50

1. 一般问题

 

1.1. 不同版本的 Spring Framework 有哪些主要功能?

 

 

1.2. 什么是 Spring Framework?

 

  • Spring 是一个开源应用框架,旨在降低应用程序开发的复杂度。

  • 它是轻量级、松散耦合的。

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

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

 

1.3. 列举 Spring Framework 的优点。

 

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

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

  • 由于依赖注入和控制反转,JDBC 得以简化。

  • 它是开源免费的。

 

1.4. Spring Framework 有哪些不同的功能?

 

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

  • IOC - 控制反转

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

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

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

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

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

 

1.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 的集成提供支持。

 

1.6. 什么是 Spring 配置文件?

 

Spring 配置文件是 XML 文件。该文件主要包含类信息。它描述了这些类是如何配置以及相互引入的。但是,XML 配置文件冗长且更加干净。如果没有正确规划和编写,那么在大项目中管理变得非常困难。

 

1.7. Spring 应用程序有哪些不同组件?

 

Spring 应用一般有以下组件:

 

  • 接口 - 定义功能。

  • Bean 类 - 它包含属性,setter 和 getter 方法,函数等。

  • Spring 面向切面编程(AOP) - 提供面向切面编程的功能。

  • Bean 配置文件 - 包含类的信息以及如何配置它们。

  • 用户程序 - 它使用接口。

 

1.8. 使用 Spring 有哪些方式?

 

使用 Spring 有以下方式:

 

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

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

  • 用于远程使用。

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

 

2. 依赖注入(Ioc)

 

2.1. 什么是 Spring IOC 容器?

 

Spring 框架的核心是 Spring 容器。容器创建对象,将它们装配在一起,配置它们并管理它们的完整生命周期。Spring 容器使用依赖注入来管理组成应用程序的组件。容器通过读取提供的配置元数据来接收对象进行实例化,配置和组装的指令。该元数据可以通过 XML,Java 注解或 Java 代码提供。

 

2.2. 什么是依赖注入?

 

在依赖注入中,您不必创建对象,但必须描述如何创建它们。您不是直接在代码中将组件和服务连接在一起,而是描述配置文件中哪些组件需要哪些服务。由 IoC 容器将它们装配在一起。

 

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

 

通常,依赖注入可以通过三种方式完成,即:

 

  • 构造函数注入

  • setter 注入

  • 接口注入

 

在 Spring Framework 中,仅使用构造函数和 setter 注入。

 

2.4. 区分构造函数注入和 setter 注入。

 

 

2.5. spring 中有多少种 IOC 容器?

 

  • BeanFactory - BeanFactory 就像一个包含 bean 集合的工厂类。它会在客户端要求时实例化 bean。

  • ApplicationContext - ApplicationContext 接口扩展了 BeanFactory 接口。它在 BeanFactory 基础上提供了一些额外的功能。

 

2.6. 区分 BeanFactory 和 ApplicationContext。

 

 

2.7. 列举 IoC 的一些好处。

 

IoC 的一些好处是:

 

  • 它将最小化应用程序中的代码量。

  • 它将使您的应用程序易于测试,因为它不需要单元测试用例中的任何单例或 JNDI 查找机制。

  • 它以最小的影响和最少的侵入机制促进松耦合。

  • 它支持即时的实例化和延迟加载服务。

 

2.8. 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();

        }

    }

}

 

3. Beans

 

3.1. 什么是 spring bean?

 

  • 它们是构成用户应用程序主干的对象。

  • Bean 由 Spring IoC 容器管理。

  • 它们由 Spring IoC 容器实例化,配置,装配和管理。

  • Bean 是基于用户提供给容器的配置元数据创建。

 

3.2. 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 注解扮演与 <bean /> 元素相同的角色。

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

 

例如:

 

@Configuration

public class StudentConfig {

    @Bean

    public StudentBean myStudent() {

        return new StudentBean();

    }

}

 

3.3. 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 所共享。在 global session 作用域中定义的 bean 被限定于全局 portlet Session 的生命周期范围内。如果你在 web 中使用 global session 作用域来标识 bean,那么 web 会自动当成 session 类型来使用。

 

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

 

3.4. 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 方法(<bean> 的 init-method 属性),那么将调用它。

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

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

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

 

 

3.5. 什么是 spring 的内部 bean?

 

只有将 bean 用作另一个 bean 的属性时,才能将 bean 声明为内部 bean。为了定义 bean,Spring 的基于 XML 的配置元数据在 <property> 或 <constructor-arg> 中提供了 <bean> 元素的使用。内部 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>

 

3.6. 什么是 spring 装配

 

当 bean 在 Spring 容器中组合在一起时,它被称为装配或 bean 装配。 Spring 容器需要知道需要什么 bean 以及容器应该如何使用依赖注入来将 bean 绑定在一起,同时装配 bean。

 

3.7. 自动装配有哪些方式?

 

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

 

自动装配的不同模式:

 

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

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

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

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

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

 

3.8. 自动装配有什么局限?

 

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

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

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

 

4. 注解

 

4.1. 什么是基于注解的容器配置

 

不使用 XML 来描述 bean 装配,开发人员通过在相关的类,方法或字段声明上使用注解将配置移动到组件类本身。它可以作为 XML 设置的替代方案。例如:

 

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

 

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

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

 

例如:

 

@Configuration

public class StudentConfig {

    @Bean

    public StudentBean myStudent() {

        return new StudentBean();

    }

}

 

4.2. 如何在 spring 中启动注解装配?

 

默认情况下,Spring 容器中未打开注解装配。因此,要使用基于注解装配,我们必须通过配置<context:annotation-config /> 元素在 Spring 配置文件中启用它。

 

4.3. @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。

 

4.4. @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;

    }

}

 

4.5. @Autowired 注解有什么用?

 

@Autowired 可以更准确地控制应该在何处以及如何进行自动装配。此注解用于在 setter 方法,构造函数,具有任意名称或多个参数的属性或方法上自动装配 bean。默认情况下,它是类型驱动的注入。

 

public class Employee {

    private String name;

    @Autowired

    public void setName(String name) {

        this.name=name;

    }

    public string getName(){

        return name;

    }

}

 

4.6. @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);

    }

}

 

4.7. @RequestMapping 注解有什么用?

 

@RequestMapping 注解用于将特定 HTTP 请求方法映射到将处理相应请求的控制器中的特定类/方法。此注释可应用于两个级别:

 

  • 类级别:映射请求的 URL

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

 

5. 数据访问

 

5.1. spring DAO 有什么用?

 

Spring DAO 使得 JDBC,Hibernate 或 JDO 这样的数据访问技术更容易以一种统一的方式工作。这使得用户容易在持久性技术之间切换。它还允许您在编写代码时,无需考虑捕获每种技术不同的异常。

 

5.2. 列举 Spring DAO 抛出的异常。

 

 

5.3. spring JDBC API 中存在哪些类?

 

  • JdbcTemplate

  • SimpleJdbcTemplate

  • NamedParameterJdbcTemplate

  • SimpleJdbcInsert

  • SimpleJdbcCall

 

5.4. 使用 Spring 访问 Hibernate 的方法有哪些?

 

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

 

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

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

 

5.5. 列举 spring 支持的事务管理类型

 

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

 

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

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

 

5.6. spring 支持哪些 ORM 框架

 

  • Hibernate

  • iBatis

  • JPA

  • JDO

  • OJB

 

6. AOP

 

6.1. 什么是 AOP?

 

AOP(Aspect-Oriented Programming), 即 面向切面编程, 它与 OOP( Object-Oriented Programming, 面向对象编程) 相辅相成, 提供了与 OOP 不同的抽象软件结构的视角.

 

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

 

6.2. 什么是 Aspect?

 

aspect 由 pointcount 和 advice 组成, 它既包含了横切逻辑的定义, 也包括了连接点的定义. Spring AOP 就是负责实施切面的框架, 它将切面所定义的横切逻辑编织到切面所指定的连接点中.

AOP 的工作重心在于如何将增强编织目标对象的连接点上, 这里包含两个工作:

 

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

  2. 如何在 advice 中编写切面代码.

 

可以简单地认为, 使用 @Aspect 注解的类就是切面.

 

 

6.3. 什么是切点(JoinPoint)

 

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

 

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

 

6.4. 什么是通知(Advice)?

 

特定 JoinPoint 处的 Aspect 所采取的动作称为 Advice。Spring AOP 使用一个 Advice 作为拦截器,在 JoinPoint “周围”维护一系列的拦截器。

 

6.5. 有哪些类型的通知(Advice)?

 

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

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

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

  • After (finally) - 这些类型的 Advice 在连接点方法之后执行,无论方法退出是正常还是异常返回,并使用 @After 注解标记进行配置。

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

 

6.6. 指出在 spring aop 中 concern 和 cross-cutting concern 的不同之处。

 

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

 

cross-cutting concern 是一个适用于整个应用的行为,这会影响整个应用程序。例如,日志记录,安全性和数据传输是应用程序几乎每个模块都需要关注的问题,因此它们是跨领域的问题。

 

6.7. AOP 有哪些实现方式?

 

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

 

静态代理 - 指使用 AOP 框架提供的命令进行编译,从而在编译阶段就可生成 AOP 代理类,因此也称为编译时增强;

 

  • 编译时编织(特殊编译器实现)

  • 类加载时编织(特殊的类加载器实现)。

 

动态代理 - 在运行时在内存中“临时”生成 AOP 动态代理类,因此也被称为运行时增强。

 

  • JDK 动态代理

  • CGLIB

 

6.8. Spring AOP and AspectJ AOP 有什么区别?

 

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

Spring AOP 仅支持方法级别的 PointCut;提供了完全的 AOP 支持,它还支持属性级别的 PointCut。

 

6.9. 如何理解 Spring 中的代理?

 

将 Advice 应用于目标对象后创建的对象称为代理。在客户端对象的情况下,目标对象和代理对象是相同的。

 

Advice + Target Object = Proxy

 

6.10. 什么是编织(Weaving)?

 

为了创建一个 advice 对象而链接一个 aspect 和其它应用类型或对象,称为编织(Weaving)。在 Spring AOP 中,编织在运行时执行。请参考下图:

 

 

7. MVC

 

7.1. Spring MVC 框架有什么用?

 

Spring Web MVC 框架提供 模型-视图-控制器 架构和随时可用的组件,用于开发灵活且松散耦合的 Web 应用程序。 MVC 模式有助于分离应用程序的不同方面,如输入逻辑,业务逻辑和 UI 逻辑,同时在所有这些元素之间提供松散耦合。

 

7.2. 描述一下 DispatcherServlet 的工作流程

 

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

 

 

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. 视图负责将渲染结果返回给客户端。

 

7.3. 介绍一下 WebApplicationContext

 

WebApplicationContext 是 ApplicationContext 的扩展。它具有 Web 应用程序所需的一些额外功能。它与普通的 ApplicationContext 在解析主题和决定与哪个 servlet 关联的能力方面有所不同。

spring 的优点? 1.降低了组件之间的耦合性 ,实现了软件各层之间的解耦 2.可以使用容易提供的众多服务,如事务管理,消息服务等 3.容器提供单例模式支持 4.容器提供了AOP技术,利用它很容易实现如权限拦截,运行期监控等功能 5.容器提供了众多的辅助类,能加快应用的开发 6.spring对于主流的应用框架提供了集成支持,如hibernate,JPA,Struts等 7.spring属于低侵入式设计,代码的污染极低 8.独立于各种应用服务器 9.spring的DI机制降低了业务对象替换的复杂性 10.Spring的高度开放性,并不强制应用完全依赖于Spring,开发者可以自由选择spring的部分或全部 什么是DI机制? 依赖注入(Dependecy Injection)和控制反转(Inversion of Control)是同一个概念,具体的讲:当某个角色 需要另外一个角色协助的时候,在传统的程序设计过程中,通常由调用者来创建被调用者的实例。但在spring中 创建被调用者的工作不再由调用者来完成,因此称为控制反转。创建被调用者的工作由spring来完成,然后注入调用者 因此也称为依赖注入。 spring以动态灵活的方式来管理对象 , 注入的两种方式,设置注入和构造注入。 设置注入的优点:直观,自然 构造注入的优点:可以在构造器中决定依赖关系的顺序。 什么是AOP? 面向切面编程(AOP)完善spring的依赖注入(DI),面向切面编程在spring中主要表现为两个方面 1.面向切面编程提供声明式事务管理 2.spring支持用户自定义的切面 面向切面编程(aop)是对面向对象编程(oop)的补充, 面向对象编程将程序分解成各个层次的对象,面向切面编程将程序运行过程分解成各个切面。 AOP从程序运行角度考虑程序的结构,提取业务处理过程的切面,oop是静态的抽象,aop是动态的抽象, 是对应用执行过程中的步骤进行抽象,,从而获得步骤之间的逻辑划分。 aop框架具有的两个特征: 1.各个步骤之间的良好隔离性 2.源代码无关性 Hibernate工作原理及为什么要用? 原理: 1.读取并解析配置文件 2.读取并解析映射信息,创建SessionFactory 3.打开Sesssion 4.创建事务Transation 5.持久化操作 6.提交事务 7.关闭Session 8.关闭SesstionFactory 为什么要用: 1. 对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码。 2. Hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM实现。他很大程度的简化DAO层的编码工作 3. hibernate使用Java反射机制,而不是字节码增强程序来实现透明性。 4. hibernate的性能非常好,因为它是个轻量级框架。映射的灵活性很出色。它支持各种关系数据库,从一对一到多对多的各种复杂关系。 2. Hibernate是如何延迟加载? 1. Hibernate2延迟加载实现:a)实体对象 b)集合(Collection) 2. Hibernate3 提供了属性的延迟加载功能 当Hibernate在查询数据的时候,数据并没有存在与内存中,当程序真正对数据的操作时,对象才存在与内存中,就实现了延迟加载,他节省了服务器的内存开销,从而提高了服务器的性能。 3.Hibernate中怎样实现类之间的关系?(如:一对多、多对多的关系) 类与类之间的关系主要体现在表与表之间的关系进行操作,它们都市对对象进行操作,我们程序中把所有的表与类都映射在一起,它们通过配置文件中的many-to-one、one-to-many、many-to-many、 4. 说下Hibernate的缓存机制 1. 内部缓存存在Hibernate中又叫一级缓存,属于应用事物级缓存 2. 二级缓存: a) 应用及缓存 b) 分布式缓存 条件:数据不会被第三方修改、数据大小在可接受范围、数据更新频率低、同一数据被系统频繁使用、非 关键数据 c) 第三方缓存的实现 5. Hibernate的查询方式 Sql、Criteria,object comptosition Hql: 1、 属性查询 2、 参数查询、命名参数查询 3、 关联查询 4、 分页查询 5、 统计函数 6. 如何优化Hibernate? 1.使用双向一对多关联,不使用单向一对多 2.灵活使用单向一对多关联 3.不用一对一,用多对一取代 4.配置对象缓存,不使用集合缓存 5.一对多集合使用Bag,多对多集合使用Set 6. 继承类使用显式多态 7. 表字段要少,表关联不要怕多,有二级缓存撑腰 7. Struts工作机制?为什么要使用Struts? 工作机制: Struts的工作流程: 在web应用启动时就会加载初始化ActionServlet,ActionServlet从 struts-config.xml文件中读取配置信息,把它们存放到各种配置对象 当ActionServlet接收到一个客户请求时,将执行如下流程. -(1)检索和用户请求匹配的ActionMapping实例,如果不存在,就返回请求路径无效信息; -(2)如果ActionForm实例不存在,就创建一个ActionForm对象,把客户提交的表单数据保存到ActionForm对象中; -(3)根据配置信息决定是否需要表单验证.如果需要验证,就调用ActionForm的validate()方法; -(4)如果ActionForm的validate()方法返回null或返回一个不包含ActionMessage的ActuibErrors对象, 就表示表单验证成功; -(5)ActionServlet根据ActionMapping所包含的映射信息决定将请求转发给哪个Action,如果相应的 Action实例不存在,就先创建这个实例,然后调用Action的execute()方法; -(6)Action的execute()方法返回一个ActionForward对象,ActionServlet在把客户请求转发给 ActionForward对象指向的JSP组件; -(7)ActionForward对象指向JSP组件生成动态网页,返回给客户; 为什么要用: JSP、Servlet、JavaBean技术的出现给我们构建强大的企业应用系统提供了可能。但用这些技术构建的系统非常的繁乱,所以在此之上,我们需要一个规则、一个把这些技术组织起来的规则,这就是框架,Struts便应运而生。 基于Struts开发的应用由3类组件构成:控制器组件、模型组件、视图组件 8. Struts的validate框架是如何验证的? 在struts配置文件中配置具体的错误提示,再在FormBean中的validate()方法具体调用。 9. 说下Struts的设计模式 MVC模式: web应用程序启动时就会加载并初始化ActionServler。用户提交表单时,一个配置好的ActionForm对象被创建,并被填入表单相应的数据,ActionServler根据Struts-config.xml文件配置好的设置决定是否需要表单验证,如果需要就调用ActionForm的 Validate()验证后选择将请求发送到哪个Action,如果Action不存在,ActionServlet会先创建这个对象,然后调用 Action的execute()方法。Execute()从ActionForm对象中获取数据,完成业务逻辑,返回一个ActionForward对象,ActionServlet再把客户请求转发给ActionForward对象指定的jsp组件,ActionForward对象指定的jsp生成动态的网页,返回给客户。 10. spring工作机制及为什么要用? 1.spring mvc请所有的请求都提交给DispatcherServlet,它会委托应用系统的其他模块负责负责对请求进行真正的处理工作。 2.DispatcherServlet查询一个或多个HandlerMapping,找到处理请求的Controller. 3.DispatcherServlet请请求提交到目标Controller 4.Controller进行业务逻辑处理后,会返回一个ModelAndView 5.Dispathcher查询一个或多个ViewResolver视图解析器,找到ModelAndView对象指定的视图对象 6.视图对象负责渲染返回给客户端。 为什么用: {AOP 让开发人员可以创建非行为性的关注点,称为横切关注点,并将它们插入到应用程序代码中。使用 AOP 后,公共服务 (比如日志、持久性、事务等)就可以分解成方面并应用到域对象上,同时不会增加域对象的对象模型的复杂性。 IOC 允许创建一个可以构造对象的应用环境,然后向这些对象传递它们的协作对象。正如单词 倒置 所表明的,IOC 就像反 过来的 JNDI。没有使用一堆抽象工厂、服务定位器、单元素(singleton)和直接构造(straight construction),每一个对象都是用其协作对象构造的。因此是由容器管理协作对象(collaborator)。 Spring即使一个AOP框架,也是一IOC容器。 Spring 最好的地方是它有助于您替换对象。有了 Spring,只要用 JavaBean 属性和配置文件加入依赖性(协作对象)。然后可以很容易地在需要时替换具有类似接口的协作对象。} Spring 框架是一个分层架构,由 7 个定义良好的模块组成。Spring 模块构建在核心容器之上,核心容器定义了创建、配置和管理 bean 的方式,如图 1 所示。 组成 Spring 框架的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现。每个模块的功能如下: ☆ 核心容器:核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转 (IOC)模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。 ☆ Spring 上下文:Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。 ☆ Spring AOP:通过配置管理特性,Spring AOP 模块直接将面向方面的编程功能集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理的任何对象支持 AOP。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖 EJB 组件,就可以将声明性事务管理集成到应用程序中。 ☆ Spring DAO:JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。 ☆ Spring ORM:Spring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。 ☆ Spring Web 模块:Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以,Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。 ☆ Spring MVC 框架:MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText 和 POI。 Spring 框架的功能可以用在任何 J2EE 服务器中,大多数功能也适用于不受管理的环境。Spring 的核心要点是:支持不绑定到特定 J2EE 服务的可重用业务和数据访问对象。毫无疑问,这样的对象可以在不同 J2EE 环境 (Web 或 EJB)、独立应用程序、测试环境之间重用。 IOC 和 AOP 控制反转模式(也称作依赖性介入)的基本概念是:不创建对象,但是描述创建它们的方式。在代码中不直接与对象和服务连接,但在配置文件中描述哪一个组件需要哪一项服务。容器(在 Spring 框架中是 IOC 容器) 负责将这些联系在一起。 在典型的 IOC 场景中,容器创建了所有对象,并设置必要的属性将它们连接在一起,决定什么时间调用方法。下表列出了 IOC 的一个实现模式。 Spring 框架的 IOC 容器采用类型 2 和类型3 实现。 面向方面的编程 面向方面的编程,即 AOP,是一种编程技术,它允许程序员对横切关注点或横切典型的职责分界线的行为(例如日志和事务管理)进行模块化。AOP 的核心构造是方面,它将那些影响多个类的行为封装到可重用的模块中。 AOP 和 IOC 是补充性的技术,它们都运用模块化方式解决企业应用程序开发中的复杂问题。在典型的面向对象开发方式中,可能要将日志记录语句放在所有方法和 Java 类中才能实现日志功能。在 AOP 方式中,可以反过来将日志服务模块化,并以声明的方式将它们应用到需要日志的组件上。当然,优势就是 Java 类不需要知道日志服务的存在,也不需要考虑相关的代码。所以,用 Spring AOP 编写的应用程序代码是松散耦合的。 AOP 的功能完全集成到了 Spring 事务管理、日志和其他各种特性的上下文中。 IOC 容器 Spring 设计的核心是 org.springframework.beans 包,它的设计目标是与 JavaBean 组件一起使用。这个包通常不是由用户直接使用,而是由服务器将其用作其他多数功能的底层中介。下一个最高级抽象是 BeanFactory 接口,它是工厂设计模式的实现,允许通过名称创建和检索对象。BeanFactory 也可以管理对象之间的关系。 BeanFactory 支持两个对象模型。 □ 单态 模型提供了具有特定名称的对象的共享实例,可以在查询时对其进行检索。Singleton 是默认的也是最常用的对象模型。对于无状态服务对象很理想。 □ 原型 模型确保每次检索都会创建单独的对象。在每个用户都需要自己的对象时,原型模型最适合。 bean 工厂的概念是 Spring 作为 IOC 容器的基础。IOC 将处理事情的责任从应用程序代码转移到框架。正如我将在下一个示例中演示的那样,Spring 框架使用 JavaBean 属性和配置数据来指出必须设置的依赖关系。 BeanFactory 接口 因为 org.springframework.beans.factory.BeanFactory 是一个简单接口,所以可以针对各种底层存储方法实现。最常用的 BeanFactory 定义是 XmlBeanFactory,它根据 XML 文件中的定义装入 bean,如清单 1 所示。 清单 1. XmlBeanFactory BeanFactory factory = new XMLBeanFactory(new FileInputSteam("mybean.xml")); 在 XML 文件中定义的 Bean 是被消极加载的,这意味在需要 bean 之前,bean 本身不会被初始化。要从 BeanFactory 检索 bean,只需调用 getBean() 方法,传入将要检索的 bean 的名称即可,如清单 2 所示。 清单 2. getBean() MyBean mybean = (MyBean) factory.getBean("mybean"); 每个 bean 的定义都可以是 POJO (用类名和 JavaBean 初始化属性定义) 或 FactoryBean。FactoryBean 接口为使用 Spring 框架构建的应用程序添加了一个间接的级别。 IOC 示例 理解控制反转最简单的方式就是看它的实际应用。在对由三部分组成的 Spring 系列 的第 1 部分进行总结时,我使用了一个示例,演示了如何通过 Spring IOC 容器注入应用程序的依赖关系(而不是将它们构建进来)。 我用开启在线信用帐户的用例作为起点。对于该实现,开启信用帐户要求用户与以下服务进行交互: ☆ 信用级别评定服务,查询用户的信用历史信息。 ☆ 远程信息链接服务,插入客户信息,将客户信息与信用卡和银行信息连接起来,以进行自动借记(如果需要的话)。 ☆ 电子邮件服务,向用户发送有关信用卡状态的电子邮件。 三个接口 对于这个示例,我假设服务已经存在,理想的情况是用松散耦合的方式把它们集成在一起。以下清单显示了三个服务的应用程序接口。 清单 3. CreditRatingInterface public interface CreditRatingInterface { public boolean getUserCreditHistoryInformation(ICustomer iCustomer); } 清单 3 所示的信用级别评定接口提供了信用历史信息。它需要一个包含客户信息的 Customer 对象。该接口的实现是由 CreditRating 类提供的。 清单 4. CreditLinkingInterface public interface CreditLinkingInterface { public String getUrl(); public void setUrl(String url); public void linkCreditBankAccount() throws Exception ; } 信用链接接口将信用历史信息与银行信息(如果需要的话)连接在一起,并插入用户的信用卡信息。信用链接接口是一个远程服务,它的查询是通过 getUrl() 方法进行的。URL 由 Spring 框架的 bean 配置机制设置,我稍后会讨论它。该接口的实现是由 CreditLinking 类提供的。 清单 5. EmailInterface public interface EmailInterface { public void sendEmail(ICustomer iCustomer); public String getFromEmail(); public void setFromEmail(String fromEmail) ; public String getPassword(); public void setPassword(String password) ; public String getSmtpHost() ; public void setSmtpHost(String smtpHost); public String getUserId() ; public void setUserId(String userId);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值