web开发——Spring(纯八股)

一、Spring简介

Spring是一个分层的Java SE/EE应用一站式的轻量级开源框架Spring的核心是IOC和AOP

Spring的优点

  1. 方便解耦,简化开发
  2. AOP编程的支持,方便进行面向切面编程
  3. 声明式事务的支持,灵活进行事务的管理,提高开发效率和质量
  4. 方便程序的测试,可以用非容器依赖的编程方式进行几乎所有测试工作。
  5. 方便集成各种优秀框架

二、Spring体系结构

如图所示Spring框架按照功能划分为五个主要模块,几乎为企业应用提供了所需的一切,从持久层、业务层到表现层都有相应的支持,这也时为什么Spring被称为一站式框架。
Spring体系架构

2.1 核心模块(Core Container)

  1. 实现了IoC的功能。由IoC容器负责类的创建、管理、获取等,降低了类与类之间的耦合性,方便测试和程序复用,使程序体系非常灵活。BeanFactory是Spring框架的核心接口,实现了很多核心功能
  2. Context模块扩展了BeanFactory的功能。ApplicationContext是Context模块的核心接口
  3. 表达式语言是统一表达式语言的一个扩展,支持设置和获取对象属性,调用对象方法,操作数组、集合等。使用它可以很方便的通过表达式和Spring IoC容器进行交互。

2.2 AOP模块

Spring AOP模块实现AOP

2.3 数据访问集成模块

包括了JDBC、ORM、OXM、JMS和事务管理:

  • 事务管理: 用于Spring管理事务,无需在代码中管理事务,而且支持编程和声明性的事务管理
  • JDBC模块:消除冗长的JDBC编码和必须的事务管理
  • ORM模块:提供于流行的对象-关系映射框架的无缝集成,包括JPA、MyBatis等。且可以用事务管理
  • OXM模块:提供了Object/XML映射实现。包括JAXB、XStream等
  • JMS模块:用于JMS(Java messaging service),提供一套消息生产者、消息消费者模板。

2.4 Web模块

建立在Application Context模块上,提供了Web应用的功能,比如文件上传等。
Spring可以整合Struts2等MVC框架,此外自己也提供了MVC框架Spring MVC

2.5 测试模块

可以用非容器依赖的编程方式进行几乎所有测试工作,支持JUnit和TestNG等测试框架。

三、Spring 容器

Spring主要提供了两种类型的容器:BeanFactoryApplicationContext

3.1 BeanFactory

本质是一个工厂类(接口),负责生产和管理bean。
在Spring中,BeanFactory是IoC容器的核心接口,职责包括:实例化、定位、配置应用程序中的对象即建立这些对象间的依赖

  • 是最基础的IoC容器,提供完整的IoC服务支持。如果没有特殊指定,默认采用延迟初始化策略。只有当某个对象要访问容器中的某个受管对象是,才对改受管对象初始化以及依赖注入。
  • 容器启动初期速度较快,需要资源有限。

3.2 ApplicationContext

由于原始的BeanFactory无法支持Spring的许多插件,比如AOP功能、Web应用等,派生了ApplicationContext接口(现多使用此接口)

Application所管理的对象,在容器启动后,默认全部初始化并绑定完成。所以相对于BeanFactory来说,要求更多的系统资源
在系统资源充足、要求更多功能的场景更适合。

四、IOC控制反转

4.1 IOC

Inversion of Control 控制反转,是一种面向对象编程的设计思想

谁控制谁,控制什么:

  • 传统Java SE程序设计直接在对象内部通过new创建对象,程序主动去创建依赖对象;
  • IoC有专门的一个容器来创建这些对象。
  • 谁控制谁由IoC容器控制对象
  • 控制什么主要控制了外部资源获取(不只是对象、包括文件等)

为什么是反转,哪些方面反转了

  • 正转:传统应用程序由自己在对象中主动控制去直接获取依赖对象
  • 反转: 由容器帮忙创建及注入依赖对象,对象只是被动的接受依赖对象
  • 哪些方面反转了依赖对象的获取反转了

传统应用程序示意图:
传统应用程序示意图
有IOC和DI容器后程序结构示意图:
有IOC和DI容器后程序结构示意图
IOC的优点:

  • 传统应用程序在类内部主动创建依赖对象,导致类与类之间高耦合,难以测试
  • IoC将创建和查找依赖对象的控制权交给容器,由容器进行注入对象,所以对象和对象之间是松散耦合,方便测试与功能复用,使得程序的体系结构非常灵活

4.2 Bean

4.2.1 Spring如何管理Bean

Spring通过IoC容器管理Bean,可以通过XML配置或者注解配置指导IoC容器对Bean的管理。

4.2.2 常见注解

  1. @ComponentScan:定义扫描的路径从中找出需要装配(@Component、@Service、@Controller)的类自动装配到容器
  2. @Component、@Repository、@Service、@Controller:用于声明Bean,作用一样,语义不一样。
    • @Component:通用
    • @Repository:DAO层的Bean
    • @Service:业务层的Bean
    • @Controller:视图层的控制器Bean
  3. @Autowired、@Qualifier用于注入Bean,告诉容器应该为当前属性注入哪个Bean。
    • @Autowired按照Bean类型匹配。
    • @Qualifier如果这个属性的类型具有多个Bean,通过@Qualifier指定Bean的名称,消除歧义 @Qualifier消除歧义例子
  4. @Scope:是调节Ioc容器中的作用域,在Spring IoC容器中主要有以下五种作用域:基本作用域:singleton(单例)、prototype(多例);Web 作用域(reqeust、session、globalsession),自定义作用域。
    • 单例:(默认是单例),饿汉模式加载(容器启动实例就创建好了),
      在容器中仅存在一个实例
    • 多例:懒汉模式加载(IoC容器启动时,并不会创建对象,在第一次使用时才会创建)
      – 每次调用getBean()都会执行new操作,返回一个新的实例
    • request: 每次Http请求都会创建一个新的Bean。
    • session:每一个HTTP Session共享一个Bean,不同的HTTP Session使用不同的Bean
    • globalSession: 同一个全局的Session共享一个Bean,一般用于Portlet环境
  5. @PostConstruct、@PreDestroy:声明Bean的声明周期。其中,被@PostConstruct修饰的方法将在Bean实例化后被调用,@PreDestroy修饰的方法将在容器销毁前被调用。

@Autowired与@Resource注解的区别
@Resource注解用法

  1. Autowired是Spring提供的注解,@Resource是JDK提供的注解
  2. Autowired:按类型注入;
    Resource:默认按名称注入,也支持按类型注入
  3. Autowired按类型装配依赖对象,默认情况下要求依赖对象必须存在。
    – 如果想要按名称装配,结合Qualifier注解一起使用
    – 如果允许null值则是指required属性为false;
    resource中国有两个重要的属性:name和type。
    –name属性指定byName,如果没有指定name属性:当注解标注在字段上,即默认取字段的名称作为bean名称寻找依赖对象;当注解标注在属性的setter方法上,即默认取属性名作为bean名称寻找依赖对象。如果Resource没有指定name属性,并且按照默认名称找不到依赖对象时,会回退到按类型装配;但一旦指定了name属性,就只能按名称装配。

4.2.3 Bean的生命周期

Bean的声明周期
这个过程是由Spring容器自动管理的,其中有两个环节我们可以进行干预。

  • 我们可以自定义初始化方法,并在该方法前增加@PostConstruct注解,届时Spring容器将在调用SetBeanFactory方法之后调用该方法。

  • 我们可以自定义销毁方法,并在该方法前增加@PreDestroy注解,届时Spring容器将在自身销毁前,调用这个方法。

4.2.4 Spring的单例模式是线程安全的吗

一、单例模式非安全模式

Spring的Bean默认是单例模式,在同一个容器中,所有对该Bean的请求都会返回相同的实例。非线程安全,在多线程同时访问时可能出现并发问题。

如果单例的Bean是一个无状态的Bean,即线程中的操作不会对Bean的成员执行查询以外的操作,那么这个单例的Bean是线程安全的。

  • 有状态的bean就是有数据存储功能。
  • 无状态的bean就是不会保存数据。
二、如何确保Spring单例Bean的线程安全
  1. 更改Bean的作用域
    作用域改为原型(多例模式),避免多线程共享一个实例
  2. 线程安全同步机制(加锁)
    一般来说使用synchronized、Reentrantlock等关键字或锁对象来同步存取共享状态的代码。
  3. 使用ThreadLocalThreadLocal使用说明
    将成员变量包装为TreadLocal(实际上只能解决线程隔离,而不能解决线程安全)
  4. 使用并发集合类
    Java并发包中提供了很多线程安全的Concurrent类,例如ConcurrentHashMap、CopyOnWriteArrayList等。这些类内部实现了各种同步机制,可以保证多线程下的正确性。所以,在处理多线程环境下的共享Bean时,也可以使用这些线程安全类来替代普通的集合类,从而避免多个线程访问同一个Bean实例时产生的并发问题。

4.3 DI

Dependency Injection 依赖注入,是IoC的实现方式
常见的几种注入方法

  • 使用有参构造方法注入
public class  User{
    private String name;
    public User(String name){
        this.name=name;
    }
} 

User user=new User("tom");
  • 使用属性注入
public class  User{
    private String name;
    public void setName(String name){
        this.name=name;
    }
}
User user=new User();
user.setName("jack");
  • 使用接口注入(不流行)
public interface Dao{
    public void delete(String name);
} 
public class DapIml implements Dao{
    private String name;
    public void delete(String name){
        this.name=name;
    }
}

五、AOP

面向切面编程详解
AOP动态代理技术讲解
Aspect Oriented Programing是面向切面编程思想,是对OOP的补充。
将解决共性需求的代码独立出来,然后通过配置的方式,声明这些代码在什么地方,什么时机调用,当满足调用条件时,AOP会将业务代码织入指定位置,从而统一解决问题,又不需要修改这一批组件的代码
在程序运行期间,在不修改源码的情况下对方法进行功能加强
面向切面编程

5.1AOP的术语

连接点:(Joint point)程序中明确定义的点,典型的包括方法调用,对类成员的访问,以及异常处理程序块的执行能,可以嵌套其他joint point
切点(point cut):表示一组joint point,定义了相应的advice将要发生的地方
增强(advice):定义了切点里面定义的程序点具体要做的操作,通过before、after、around来区别在每个joint point之前、之后还是代替执行的代码
切面:类似java的类声明,包含一些切点和相应的advice。
目标对象:织入advice的对象
引入:
织入:通过动态代理技术将aspect和其他对象连接起来
AOP各个概念所处的场景

5.2AOP的实现方式

  • JDK动态代理:Java提供的动态代理技术,可以在运行时创建接口的代理实例。Spring AOP默认采用这种方式,在接口的实例中织入代码。
  • CGLib动态代理:采用底层的字节码技术,在运行时创建子类代理的实例。当目标对象不存在接口是,Spring AOP就会采用这种方法,在子类实例中织入代码。

在性能方面,CGLib创建的代理对象比JDK动态代理创建的代理对象高很多,但是CGLib在创建代理对象时所花费的时间比JDK动态代理多很多。
所以对于单例的对象因为无需频繁创建代理对象,采用CGLib动态代理较合适。
对于多例的对象,需要频繁创建代理对象,采用JDK动态代理更合适。

5.3 AOP的应用场景

1. AOP解决了什么问题

问题使用SpringAOP以后
除了核心逻辑,还要关注非核心逻辑把非核心业务封装起来,只关注核心逻辑
代码重复率高(输出同样的日志格式)公共非核心的封装起来,格式在公共部分给出即可

2. 使用场景

权限管理、异常处理、操作日志、事务控制

5.4 AOP不能对哪些类进行增强

  1. Spring AOP只能对IoC容器内的Bean进行增强。
  2. 由于CGLib采用动态创建子类的方式生成代理对象,所以不能对final修饰的类进行代理

六、事务管理

Spring为事务管理提供了一致的编程模板(无论是MyBatis、HIbernate、JPA、Spring JDBC)都可以用统一的编程模型进行事务管理

6.1 编程式事务和声明式事务

1. 编程式事务

通过TransactionTemplate管理事务,并通过它执行数据库的操作

2. 声明式事务(常用)

建立在Spring AOP机制上,本质是对目标方法前后进行拦截,并在目标方法开始前创建或加入一个事务,在目标方法执行后根据执行情况提交或者回滚事务。
- 通过XML配置声明某方法的事务特征
- 通过注解声明某方法的事务特征

6.2事务传播方式

当业务方法嵌套调用时,如果两个方法都要保证事务,就需要通过Spring的事务传播机制控制当前事务如何传播到被嵌套调用的业务方法中。
Spring在TransactionDefinition接口中规定了七种类型的事务传播行为:

事务传播类型说明
PROPAGATION_REQUIRED如果当前没有事务,新建一个事务;如果存在一个事务,则加入到这个事务中。(最常见)
PROPAGATION_SUPPORTS支持当前事务,如果当前没有事务,则以非事务方式执行。
PROPAGATION_MANDATORY使用当前事务,如果没有事务,抛出异常
PROPAGATION_REQUIRES_NEW新建事务,如果存在事务,则当前事务挂起
PROPAGATION_NOT_SUPPORTED以非事务方式执行,如果存在事务,则当前事务挂起
PROPAGATION_NEVER以非事务方式执行,如果当前存在事务,则抛出异常
PROPAGATION_NESTED如果当前存在事务,则在嵌套事务内执行;如果当前没有事务,则新建一个事务。
Column 1Column 2
centered 文本居中right-aligned 文本居右

6.3 事务的配置与常用注解

事务的打开、回滚、提交交给事务管理器完成。
对于声明型事务,使用@Transaction进行标注。

  • 标注在类上:所有公共非静态方法都将启用事务功能
  • 标注在方法上:该方法启用事务功能

@Transaction注解上,可以使用isolation属性声明事务的隔离级别,propagation声明事务的传播机制。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值