spring

1、IOC

1.IOC

        也叫控制反转,在使用对象时,由主动new产生对象转换为由外部提供对象,此过程中对象创建控制权由程序转移到外部,而IOC 的主要作用是实现了对象的管理,也就是我们不把设计好的对象交给了IOC 容器控制,然后在需要用到目标对象的时候,直接从容器中去获取,有了IOC容器来管理Bean以后,相当于把创建和查找依赖对象的控制权交给了容器,使对象与对象之间是一种松耦合状态,极大提高代码复用性,此思想被称为控制反转

2.spring和IOC关系是

        spring技术对IOC思想进行了实现,spring提供了一个容器,称为IOC容器,用来充当IOC思想中的"外部",

3.IOC容器的作用以及内部存放的是什么

        IOC容器负责对象的创建,初始化等一系列工作。其中包含了数据层和业务层的类对象,被创建或者管理的对象在IOC容器中称为Bean对象

4.有哪几种方法创建IOC容器的

new ClassPathXmlApplicationContext(配置文件名)

new FileSystemXmlApplicationContext(配置文件全路径)

new ClassPathResource(配置文件名)返回resource对象 new XmlBeanFactory(resource)

new AnnotationConfigApplicationContext(SpringConfig.class);[配置类的字节码文件]

5.注入有哪几种方式

        构造器注入

        setter注入

        接口注入

6.IOC优点和缺点

#优点:

        组件之间的解耦,提高程序可维护性,灵活性

#缺点:

        创建对象步骤复杂,有一定学习成本

        利用反射创建对象,效率上有损(这点损耗对于spring开发带来的方便不算什么)

2、DI

1.什么是DI

        DI也叫依赖注入,在IOC容器中建立bean与bean之间的依赖关系的整个过程,称为依赖注入

2.一般哪些bean需要建议依赖关系

        需要自己根据业务需求提前建立好关系,比如service和dao层就要建立依赖关系

3.注入有哪几种方式

        构造器注入

        setter注入

        自动装配(配置文件/注解)

 3、Bean

1.生命周期

bean的实例化

bean的赋值

bean初始化

bean销毁

2.bean的获取传参

通过bean的名字获取

通过bean的名字加上所在类的字节码文件

直接通过字节码文件

3.bean的实例化

构造方法

静态工厂

实例工厂

实现接口FactoryBean接口

4.两次前后取得同一个Bean地址是否一样

在Spring框架中,如果这个Bean的作用域是默认的(单例singleton),那么你得到的实例会是同一个。这是因为单例Bean在Spring容器中只会被创建一次,之后会被缓存起来,所以每次获取都是相同的实例

5.Bean 是不是线程安全的

        多例Bean每次都会新创建新实例,也就是说线程之间不存在Bean共享的问题。因此,多例Bean是不存在线程安全问题的。

        而单例Bean是所有线程共享一个实例,因此,就可能会存在线程安全问题。但是单例Bean又分为无状态Bean和有状态Bean。在多线程操作中只会对Bean的成员变量进行查询操作,不会修改成员变量的值,这样的Bean称之为无状态Bean。所以,可想而知,无状态的单例Bean是不存在线程安全问题的。但是,在多线程操作中如果需要对Bean中的成员变量进行数据更新操作,这样的Bean称之为有状态Bean,所以,有状态的单例Bean就可能存在线程安全问题。

        所以,最终我们得出结论,在Spring中,只有有状态的单例Bean才会存在线程安全问题

6.如何解决Spring Bean的线程安全问题?

  1. 将Bean的作用域由 “singleton” 单例 改为 “prototype” 多例。
  2. 在类中定义 ThreadLocal 的成员变量,并将需要的可变成员变量保存在 ThreadLocal 中,ThreadLocal 本身就具备线程隔离的特性,这就相当于为每个线程提供了一个独立的变量副本,每个线程只需要操作自己的线程副本变量,从而解决线程安全问题

 @Resource 和 @Autowired 的区别

作用:
        @Resource 和@Autowired 这两个注解的作用都是在 Spring 生态里面去实现 Bean
的依赖注入
@Autowired:
         @Autowired 是 Spring 里面提供的一个注解,默认是根据类型来实现
Bean 的依赖注入。 @Autowired 注解里面有一个 required 属性默认值是 true,表示强制要求 bean 实例 的注入, 在应用启动的时候,如果 IOC 容器里面不存在对应类型的 Bean,就会报错。 当然,如果不希望自动注入,可以把这个属性设置成 false。
         如果在 Spring IOC 容器里面存在多个相同类型的 Bean 实例。由于@Autowired 注解是根据类型来注入 Bean 实例的, 会提示一个错误,大概意思原本只能注入一个单实
例 Bean, 但是在 IOC 容器里面却发现有多个,导致注入失败
         当然,针对这个问题,我们可以使用 @Primary 或者@Qualifier 这两个注解来解决。
@Primary 表示主要的 bean,当存在多个相同类型的 Bean 的时候,优先使用声明了 @Primary 的 Bean。 @Qualifier 的作用类似于条件筛选,它可以根据 Bean 的名字找到需要装配的目标 Bean
 @Resource
         @Resource 是 JDK 提供的注解,只是 Spring 在实现上提供了这个注解的功能支持。
它的使用方式和@Autowired 完全相同,(如图)最大的差异于@Resource 可以支持
ByName 和 ByType 两种注入方式
         如果使用 name,Spring 就根据 bean 的名字进行依赖注入,如果使用 type,Spring
就根据类型实现依赖注入。 如果两个属性都没配置,就先根据定义的属性名字去匹配,如果没匹配成功,再根据类型匹配。两个都没匹配到,就报错
区别:
  • @Autowired 是根据 type 来匹配,@Resource 可以根据 name 和 type 来匹配,
    默认是 name 匹配
  • @Autowired 是 Spring 定义的注解,@Resource 是 JSR 250 规范里面定义的注 解,而 Spring 对 JSR 250 规范提供了支持。
  • @Autowired 如果需要支持 name 匹配,就需要配合@Primary 或者@Qualifier来实现。

 Spring 中,有两个 id 相同的 bean,会报错吗,如果会报错,在哪个阶段报错

        在3.0X ,同一个xml 配置文件里面,不能存在id 相同的两个 Bean ,否则 spring 容器启动的时候会报错,因为 id 这个属性表示一个 Bean 的唯一标志符号,所以 spring 在启动的时候会去验证 id 的唯一性,一旦发现重复就会报错,这错误发生对 spring 对xml 文件进行解析转化为 BeanDefinition 的阶段,但是在两个不同的 spring 配置文件里面,可以存在id相同的两个Bean 。IOC容器在加载Bean的时候,默认会多个相同id的bean进行覆盖。

        在spring3.X版本以后,提供了@Configuration注解声明一个配置类,然后使用@Bean注解实现Bean的声明,这种完全取代了XML,在这种情况下,如果声明多个相同名字的bean,在Spring IOC容器中只会注册第一个声明的Bean的实例,后续重复名字的 Bean就不会在注册了。

        如果使用@Autowired注解根据类型实现依赖注入,只有第一个Bean实例,没有第二个实例(比如User1的Bean是user而User2的bean也是user那么只会有User1的实例)。

        如果使用@Resource注解根据名词实现依赖注入,在IOC容器里面得到的实例对象是User1于是会把User这个实例赋值给User2,就会提示类型不匹配错误,这个错误,是在spring IOC容器里面的Bean初始化之后的依赖注入阶段发生的

 spring里面的事务是什么

在spring 里面并没有提供事务,它只是提供了对数据库事务管理的封装,通过声明式的事务配置,使得开发人员可以从一些复杂的事务处理中得到解脱,我们不需要关心连接的获取,连接的关闭,事务提交,事务回滚这些操作。

所以,spring里面的事务,本质上就说数据库层面的事务,这种事务的管理,主要是针对单个数据库里面多个数据表操作的,去满足事务的ACID特性

4.AOP&事务

 1.什么是AOP

AOP是面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术

2.切面有几种类型的通知

        前置通知:目标方法被调用之前调用通知功能

        后置通知:目标方法完成之后调用通知功能

        返回通知:目标方法成功执行之后调用通知

        异常通知:目标方法抛出异常后调用通知

        环绕通知:在被通知的方法调用之前和之后执行自定义的行为

3.几个点

#什么是连接点

        连接点是在应用执行中能够插入切面的一个点(可能需要被增强的方法)

#什么是切点

        连接点可能有一个或者是几个,我们通常实现明确的类和方法名称,或者利用正则表达式定义所匹配的类和方法名称来指定这些切点,(需要被增强的方法为切点)

#什么是通知

       将被增强的内容抽取到一个方法中,也叫存放共性功能的方法 

#什么是切面

切面是通知和切点的结合,通知和切点共同定义了切面的内容

4.事务

也就事务管理,在程序运行时如果抛出异常后面的代码将不会执行,比如在转账处理的时候,如果执行转出之后抛出异常后面代码将不会在执行,此时数据库的数据只能减少不能增加导致数据不一致,事务管理就是为了防止数据不一致的问题

5、事务和AOP主要可以干嘛 

  • 日志记录:通过 AOP 可以在方法执行前后记录日志,方便跟踪和调试应用程序
  • 事务管理:AOP 可以在方法执行前后进行事务的开启、提交或回滚,简化了事务管理的代码。
  • 安全性控制:通过 AOP 可以在方法执行前进行权限验证,确保只有具有相应权限的用户才能访问敏感数据或执行敏感操作。
  • 性能监控:AOP 可以在方法执行前后进行性能监控,如记录方法的执行时间、调用次数等,用于性能优化和瓶颈分析
  • 异常处理:AOP 可以在方法执行过程中捕获异常,并进行统一的异常处理和错误日志记录。
  • 缓存管理:AOP 可以在方法执行前后进行缓存的读取和更新,提高系统的响应速度和性能。
  • 验证和校验:AOP 可以在方法执行前进行参数的验证和校验,确保输入的数据符合要求。
  • 消息通知:AOP 可以在方法执行前后发送消息通知,如发送邮件、短信等。

 为什么使用Spring框架

spring是一个轻量级应用框架,他提供了IOC和AOP 这两个核心的功能,它的核心是为了简化企业级应用程序的开发,使得开发者只需要关心业务需求,不需要关心Bean的管理,以及通过切面增强功能减少代码的侵入性。

  • Spring 是轻量的 ,基本的版本大约 2mb
  • IOC/DI:Spring 通过IOC容器实现了 Bean 的生命周期管理,以及通过 DI 实现依赖注入,从而实现了对象依赖的松藕合管理
  • 面向切面的编程(AOP): Spring 支持面向切面的编程,从而把应用业务逻辑和系统服务分开
  • MVC 框架: Spring MVC 提供了功能更加强大且更加灵活的WEB 框架支持
  • 事务管理:Spring 通过AOP实现了事务的统一管理 ,对应开发中的事务处理提供了非常灵活的支持

spring 从第一个版本发布到现在,它是生态已经非常庞大了,在业务开发领域,spring生态几乎提供了,非常完善的支持,技术成熟度非常高

 BeanFactory和FactoryBean的区别

Spring 里面的核心功能是IOC 容器,所谓IOC容器呢。本质上就是一个Bean的容器或者是一个Bean的工厂

它能够根据xml里声明的Bean配置进行Bean的加载和初始化,然后BeanFactory 来生产我们需要的各种各样的 Bean

BeanFactory:

  • BeanFactory 是所有 Spring Bean 容器的顶级接口 ,它为Spring 的容器定义了一套规范,并提供像GetBean 这样的方法从容器中获取指定的 Bean实例
  • BeanFactory 在产生 Bean 的同时,还提供了解决 Bean 之间的依赖注入的能力(DI)

FactoryBean:

  • FactoryBean是一个工厂 Bean ,它是一个接口,主要功能是动态生成某一个类型的Bean 实例,也就是说,我们可以自定义一个 Bean 并且加载到 IOC容器里面,通过getObject() 方法,这个方法里面就是用来实现动态构建 Bean 的过程
  • 在Spring Cloud 里面的 OpenFeign 组件,客服端的代理类,就是使用了FactoryBean来实现的

 循环依赖

  • 相互依赖,A依赖B,B又依赖A,它们之间形成了循环依赖
  • 三者之间依赖,A依赖B,B依赖于C,C又依赖A,形成了循环依赖
  • A依赖A形成了循环依赖

解决办法:

        Spring 中设计了三级缓存来解决循环依赖问题,当我们去调用 getBean()方法的时
候,Spring 会先从一级缓存中去找到目标 Bean,如果发现一级缓存中没有便会去二级
缓存中去找,而如果一、二级缓存中都没有找到,意味着该目标 Bean 还没有实例化。
于是,Spring 容器会实例化目标 Bean(PS:刚初始化的 Bean 称为早期 Bean) 。
        然 后,将目标 Bean 放入到二级缓存中,同时,加上标记是否存在循环依赖。如果不存在循环依赖便会将目标 Bean 存入到二级缓存,否则,便会标记该 Bean 存在循环依赖,
然后将等待下一次轮询赋值,也就是解析@Autowired 注解。等@Autowired 注解赋
值完成后(PS:完成赋值的 Bean 称为成熟 Bean) ,会将目标 Bean 存入到一级缓存。
        Spring 一级缓存中存放所有的成熟 Bean, 二级缓存中存放所有的早期 Bean,先取一级缓存,再去二级缓存

三级缓存的作用是什么

        三级缓存是用来存储代理 Bean,当调用 getBean()方法时,发现目标 Bean 需要通过
代理工厂来创建,此时会将创建好的实例保存到三级缓存,最终也会将赋值好的 Bean
同步到一级缓存中。

Spring 中哪些情况下,不能解决循环依赖问题

        1.多例 Bean 通过 setter 注入的情况,不能解决循环依赖问题
        2.构造器注入的 Bean 的情况,不能解决循环依赖问题
        3.单例的代理 Bean 通过 Setter 注入的情况,不能解决循环依赖问题
        4.设置了@DependsOn 的 Bean 的情况,不能解决循环依赖问题

SpringMvc

什么是MVC框架

MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。
MVC被独特的发展起来用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中。 

 Spring MVC 的执行流程

Spring MVC 的工作流程可以分为几个步骤
        1. 用户发起请求,请求先被 Servlet 拦截转发给 Spring MVC 框架
        2. Spring MVC 里面的 DispatcherSerlvet 核心控制器,会接收到请求并转发给 HandlerMapping
        3. HandlerMapping 负责解析请求,根据请求信息和配置信息找到匹配的 Controller 类,不过这里如果有配置拦截器,就会按照顺序执行拦截器里面的 preHandle 方法
        4. 找到匹配的 Controller 以后,把请求参数传递给 Controller 里面的方法
        5. Controller 中的方法执行完以后,会返回一个 ModeAndView,这里面会包括视图名称和需要传递给视图的模型数据
        6. 视图解析器根据名称找到视图,然后把数据模型填充到视图里面再渲染成 Html 内容返回给客户端
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值