Question

    • 需要下载jar包?- 是的
    • context 命名空间的作用?(context 命名空间在使用启动注解的时候要用到)
    • aop 命名空间

    • beans, core, context, expression
    • 什么是xml文件

    IOC (Inversion of Control)

    • ICO底层原理:xml解析,工厂模式,反射
    • Bean管理
      • 创建对象 和 注入属性
      • 基于xml配置文件实现
        • xml配置文件的创建对象
          • Bean 标签中的属性:id,class
          • scope = “singleton” / “prototype” (单实例还是多实例)
          • init-method,初始化时会调用的方法
          • destroy-method,销毁时会调用的方法
          • 自动装配:autowire = “byName” / “byType” (不过实际中一般由注解来实现)
        • xml配置文件的注入属性:
          • set方法注入属性 标签
          • 有参构造输入属性 标签
          • 内部 bean & 外部 bean 注入对象属性
          • 联级赋值,向对象属性的属性赋值
          • 注入集合属性:数组、list、set、map -> 在集合中添加对象类型值
      • 基于注解方式实现
        • 开启注解 bean 管理的步骤
          • 引入 context 命名空间
          • 开启组建扫描
          • 创建类,在类上添加对象注解
        • @Autowired, @Qualifier, @Resource, @Value
      • 工厂 bean,FactoryBean
        • 编写类实现 FactoryBean<> 接口
        • 重写当中的 getObject, getObjectType & isSingleton 方法
        • 调用 FactoryBean 时得到的是在 getObject 中定义的类实例
      • bean 生命周期
        • Bean 容器通过配置文件找到该 bean 的定义
        • 通过构造器创建 bean 实例
        • 为 bean 的属性设置值以及对其他 bean 引用
        • 把 bean 实例传递到 bean 后置处理器 BeanPostProcessor中 的 postProcessBeanBeforeInitialization() 方法
        • 调用 bean 的初始化方法,由 bean 标签中的 init-method 属性定义
        • 把 bean 实例传递到 bean 后置处理器 BeanPostProcessor 中的 postProcessBeanAfterInitialization() 方法,在这里进行Aop
        • 获得对象
        • 当容器销毁时,调用 bean 的销毁方法,用 bean 标签中的 destroy-method 定义
        • note:后置处理器实现 BeanPostProcessor 接口,同样需要放到 bean 容器中才会起作用;如果 bean 容器中没有后置处理器,那么就没有上述步骤的中的第3和第5步
    • Spring 实现IOC容器的两个方式
      • BeanFactory -> BeanFactory在加载配置文件时不会创建对象,只有在获取对象时才会去创建对象
      • ApplicationContext
        • ClassPathXmlApplicationContext

    notes:

    AOP (Aspect Oriented Programming)

    • 底层原理:动态代理
      • JDK 动态代理,创建接口实现类代理对象
      • CGLIB 动态代理,创建子类的代理对象
    • concepts:连接点、切入点、通知(前置、后置、环绕、异常、最终)、切面
      • 前置通知,@Before ( Value = “切入表达式” )
      • 后置通知,@AfterReturning
      • 最终通知,@After
      • 异常通知,@AfterThrowing
      • 环绕通知,@Around
    • 切入点表达式
      • execution ( [限权修饰符] [返回类型] [类全路径] [方法名称] ( [参数列表] ) )
      • 可以用 “..” 来代替参数列表,表示任意参数
      • 可以用 “*” 来代替其他的元素,表示任意的值
    • 相同切入点抽取
    • 增强类:增强逻辑(通知)所在的类
      • @Component
      • @Aspect
      • @Order()

    Spring 事务管理


    @RestController & @Controller

    • 传统Spring MVC
      • 单独使用@Controller,一般情况下(不使用@ResponseBody)返回一个视图,前后端不分离
    • @RestController
      • 直接返回 JSON 或者 XML 对象,交由前段独自去处理返回的数据,前后端分离
      • @RestController 一定意义上就是省去将 @Responseody 补充到方法中去
    • @Controller + @ResponseBody
      • 将 @ResponseBody 将在方法的返回值前,指定将返回的数据转换为指定的格式
      • @Controller + @ResponseBody = @RestController

    注解:@Component,@Service,@Repository,@Controller,@Bean

    • @Component,@Service,@Repository,@Controller
      • 直接作用在类上 - @Target({ElementType.TYPE})
      • 标注了那些需要被装配到 bean 容器中的对象
      • 其中:
        • @Component - 通用的注解
        • @Service - 对应服务层
        • @Repository - 对应DAO层
        • @Controller - 对应 Spring MVC 控制层
    • @Beam
      • 标注了那些产生了需要被装配到 bean 容器中对象的方法
      • 方法本省不是被装配到容器中,方法产生的对象才是装配的目标
      • @Bean 比 @Component 的自定性更强

    Spring MVC 工作原理

    流程说明(重要):

    1. 客户端(浏览器)发送请求,直接请求到 DispatcherServlet。
    2. DispatcherServlet 根据请求信息调用 HandlerMapping,解析请求对应的 Handler。
    3. 解析到对应的 Handler(也就是我们平常说的 Controller 控制器)后,开始由 HandlerAdapter 适配器处理。
    4. HandlerAdapter 会根据 Handler 来调用真正的处理器来处理请求,并处理相应的业务逻辑。
    5. 处理器处理完业务后,会返回一个 ModelAndView 对象,Model 是返回的数据对象,View 是个逻辑上的 View。
    6. ViewResolver 会根据逻辑 View 查找实际的 View。
    7. DispaterServlet 把返回的 Model 传给 View(视图渲染)。
    8. 把 View 返回给请求者(浏览器)

    面试问题准备:
    什么是Spring?

    • Spring 是一个 java 编程领域的轻量级开源框架,它的核心思想是通过工厂模式来管理所有在开发过程中所用到的 bean 对象。我们只需要将用到的工具通过注解或者在 xml 中注册到 IoC 容器中即可,在用到的时候再从容器中调用即可。

    Spring 框架的优点

    • 方便解耦,简化开发

    IoC 和 DI

    • IoC (Inversion of Control),就是将对于对象实例的控制权交由 spring 来管理,那么我们只要配置好 xml 文件或者注解就行。IoC 容器来负责管理这些对象以及它们的整个生命周期。
    • DI (Dependency Inject),当我们要在一个类中调用另一个类的非静态方法,一般的做法都是在该类内部创建一个被调用类的实例,这样子就造成了两个类之间的依赖关系太强了(高耦合)。DI 就是指将底层类作为参数传入到上层类中,从而降低两者之间的依赖程度。而无论是底层类还是上层类都是由 spring 来帮我们管理,在容器中它们都是以独立的 bean 实例存在的
    • 不同的依赖注入方法:
      • setter 注入
      • 构造器注入
      • 静态工厂的方法注入
      • 实例工厂的方法注入

    完全注解开发

    • @Configuration
    • @ComponentScan (basePackages = “” )

    BeanFactory 和 ApplicationContext 的区别

    • 两者都是 spring 中常用的 IoC 容器,它们之间的主要是 BeanFactory 作为最底层的接口,采用的是延迟加载的模式,只有当 bean 对象被调用的时候才会去创建。而 ApplicationContext 不同的是它会在容器启动的时候,一次过将所有 bean 都创建了,那么在之后运行的过程中用到的时候再调用。因为 ApplicationContext 的 bean 是已经创建好的,所以它在运行的时候速度会比较快,不过这也导致了它在启动的时候会较慢点。而且如果某些bean的配置有错的话,在启动的时候就能立刻发现;而如果是BeanFactory,在之后的运行中该出错的bean被调用而创建的时候才会有可能发现错误。

    bean 的作用域

    • 比较常用的作用域:singleton(单实例) & prototype(多实例),默认值为单实例
    • 如果 bean 的作用域是 singleton 的话,那么在容器创建的时候就会一并创建唯一的实例,之后每次调用都会返回该例;如果是 prototype 的话,那么就会在对象被调用的时候再创建对象,每次返回的对象都是不同的
    • 通过 xml 文件创建 bean 的话,就在 bean 标签内的 scope 属性选择 bean 的作用域
    • 通过注解创建 bean 的话,就在注解的 scope 属性选择
    • 其他的作用域:request,session,global-session

    bean 单实例的线程安全问题

    • 因为容器中一般情况下都是单实例,那么当多个线程对同一个实例进行操作时,就会对其成员属性的读写就会产生线程安全问题。解决这个问题可以将有需要的成员属性改为 ThreadLocal 对象,或者直接将该对象改为 prototype,那么每次请求都会产生一个新的实例,读写操作时的都是不同的对象,自然就不存在线程安全问题
    • 一般情况下,我们使用的 Controller、Service、Dao 这些 bean 都是无状态的,不会保存数据,所以也就是线程安全的

    bean 的生命周期

    @Component 和 @Bean 之间的区别是什么?

    • 首先 @Component 是作用于类的,而 @Bean 是作用于方法的
    • @Bean 注解的自定义性要比 @Component 强;有某些情况下,例如当我们需要引用第三方库中的类时,就只能通过 @Bean 来实现

    spring 管理事务的方式有几种?

    • 编程式事务和声明式事务,其中声明式事务又具体分为基于 xml 以及基于注解的声明式事务
    • @Transactional,及其属性
      • propagation,定义事务传播行为
      • isolation,事务隔离级别
      • timeout,超时时间
      • readonly,是否只读
      • rollbackFor,设置要进行回滚的异常类型
      • noRollbackFor,设置不需要进行回滚的异常类型
    • 完全注解声明式事务管理
      • 在配置类加上 @EnableTransactionManagement 注解
      • 创建事务管理器

    AOP JDK 代理和 CGLIB 代理的不同

    解释一下AOP

    • AOP 的核心思想就是将可重用的模块封装起来,然后拼接到程序的切面上去

    unsolved:

    • Spring 中 Bean 的生命周期
    • Spring 框架中的设计模式 … …
    • Spring 事务
    • Spring JPA

    一些面试题:

    references: