Spring重点面题总结

1 什么是Spring:

  • 概念: 一个轻量级开源的java框架,提供开发中提供一站式轻量级开发平台,目标是开发高内聚低耦合的系统
  • 核心思想:①IOC控制反转,由IOC容器负责对象和资源的创建及管理,应用程序只需要依赖IOC容器即可,这样在程序运行期间IOC容器可通过DI技术动态给应用程序提供运行时所需的对象,实现解耦,这意味着有之前的主动创建变成了被动接收②AOP:面向切面编程,也就是在程序运行期间,将指定的代码(四类通知方法)动态的插入到方法的指定位置(方法运行前,方法异常,方法返回时,finally块),这种设计具有高重用性和扩展性
  • 采取的策略:四种基本策略①基于POJO低侵入式编程②ioc控制反转+面向接口编程实现低耦合③基于切面和管理进行声明式编程④模板和切面减少重复

2 Spring依赖注入DI和IOC容器
最易懂的Spring IOC原理讲解

3 spring优点

  • 基于POJO低侵入式编程
  • ioc控制反转+面向接口编程实现低耦合
  • 不排斥其它优秀框架
  • 声明式事物管理,只需要一个注解即可完成事物
  • 支持junit4,方法测试
  • 降低java开发难度
    缺点:①大量使用注解使得程序运行效率低②难度大

4 bena组件的各个属性

  • id:唯一标识一个组件
  • class:组件所对应的类
  • scope:bean的作用域是通过scope进行声明的,有五种,如下
1 单实例模式singleton:是scope的默认值,在容器初始化时就已经加载并实例化了所有组件(如果是懒加载,也就是在类上标注了@Lazy后,那么就在获取对象时加载这个组件),
之后程序中使用组件直接去容器中拿,无论调用多少次最终拿到的都是同一个对象,当容器关闭时则销毁里面的组件,可以理解为组件的单例模式,但同一个类多个组件,同一组件
无论获取多少次只能获取一个组件,不同组件还是可以拿到不同的对象的

2 原型模式prototype:容器初始化时不实例化组件,之后每次从容器中通过getBean()获取组件时再实例化对象,所以每次调用都是获取到的都是不同的对象

# 以下两种只适合于webApplicationContext环境下
3 request:每次http请求都会创建一个新的bean对象,不同的请求对应不同的bean对象
4 session:同一个session域共享一个bean,不同session对应不同的bean
  • name:可忽略
  • autowired:通过ref相当于手动为引用类型的属性赋值,而autowired则相当于让该组件自动去容器中找对应的组件,完成自动装配,装配策略如下
案例:Book类中有一个属性private Car car
byName:通过名字来寻找,也就是以属性名作为id,去容器中寻找,相当于ioc.getBean('car'),
byType:以类型为依据去容器中寻找,相当于ioc.getBean(Car.class),如果容器有多个这种类型的组件就会报错
constructor:以构造器参数为依据类型去寻找,找不到返回null,找到了多个按参数名进行匹配返回
  • lazy-init:懒加载,单例模式下会在容器启动时加载组件,懒加载则是在获取组件对象时再加载
  • parent:表示配置信息继承于xxx组件
  • depend-on:表示依赖哪个组件,被依赖的组件和依赖的组件之间不考虑代码位置顺序,一定是被依赖组件先被创建
  • factory-method:工厂方法名,通过这个组件class来标识一个工厂类,相当于通过这个工厂的静态方法直接来创建对象,适用于静态工厂
  • factory-bean:指定工程类,和factory-method搭配使用
  • init-method:组件初始化方法,该方法必须位于pojo类中,顺序参考下文。
  • init-destory:组件销毁方法,该方法必须位于pojo类中,顺序参考下文。

补充:
① bean组件配置的子标签property是属性标签,组件就指默认调用setter方法来进行赋值,property有以下属性:

  • name代表属性名:这是由setter/getter方法决定的,如setLastName,那么这个bean的名称就叫lastName
  • ref:如果这个属性是个pojo类型的属性,那么通过情况在这个bean的外部定义一个bean,用ref引用外部这个bean
  • value是为这个属性赋的值;

② bean组件的子标签constructor,则是代表使用有参构造器来为属性赋值,name和value与property标签中的作用相同

5 bean组件的依赖关系

6 从对象创建的角度深入分析

单实例对象:构造方法 -> setter方法(如果bean组件有propertiy标签时) 
->后置器BeanPostProcessor处理的before方法 -> 初始化方法init-method,此时对象初始化工作完毕
-> AOP ->获取代理类对象xxxProxy
-> 后置处理器的After方法 -> 容器关闭接着调用销毁方法 destory-method
  • 解析类(通过ComponentScan解析那种被@Controller等注解修饰的类)得到BeanDefination
  • 推断类的构造器,通过构造器初始化对象
  • 对@AutoWired修饰的属性进行对象填充
  • 回调Aware,比如BeanNameAware,相当于让创建好的bean组件知道自己的名字等属性
  • 执行BeanPostProcessor的前置方法
  • 执行初始化init-method方法
  • 通过AOP获取代理类对象
  • 执行beanProcessor的前置的后置方法,至此组件创建工作基本完毕,如果时单例模式那么需要将创建好的bean放入到单例池中
  • 使用bean
  • ioc容器关闭,调用destory-method

2 spring的事物传播属性

事物的传播行为:事物主要是在service层中,当前一个方法运行在一个开启事物的方法中是,是选择使用事物方法原有的事物,还是选择自己开启一个新事物
REQUIRE_NEW: 不管什么情况,都需要创建一个新的独立事物,如果当前所在方法中存在事物,那么要关挂起事务
REQUIRE:默认值,m1调用m2,如果m1中有事物,m2直接使用m1中的事物,如果m1没有事物,m2在创建自己的事物,这样保证整体的原子性
REQUIRE_NEVER:以非实物方法运行,有事物则报错
REQUIRE_SUPPORT:支持当前事物,没有的话就以非事物方法运行

参考文章:事务的三种并发问题及四种隔离级别

3 spring如何解决中文乱码
GET请求乱码问题在tomcat的配置文件夹下的server.xml文件中配置,如果是tomcat8及以上版本就不需要这一步在这里插入图片描述

<!--    配置一个字符编码过滤器,此类过滤器一般都在其他Filter之前,因为POST请求编码设置需要在请求发起前进行编码设置-->
<!--    而HiddenHttpMethodFilter的工作机制是先发起请求,这样的话put和delete请依然会存在乱码问题-->
    <filter>
        <filter-name>characterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!--        针对全部的POST请求的乱码解决方式(GET请求乱码问题在tomcat的配置文件夹下的server.xml文件中配置)-->
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
<!--        forceEncoding顺手解决响应乱码问题,但只是设置了 -->
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
<!--        按以上字符编码规则过滤所有的请求和响应-->
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

扩展

<!--    #javaweb中:post请求乱码解决如下-->
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=utf-8");

8 spring的组成
spring core:包含IOC和DI功能的核心包
spring aop:AOP功能的核心包
spring test:juint4测试包
spring jdbc:简化jdbc操作
spring web :简化web层操作
spring beans:提供了BeanFactory,是工厂模式的一个经典实现,Spring将管理对象称为Bean。
spring context:构建于 core 封装包基础上的 context 封装包,提供了一种框架式的对象访问方法。

9 spring中用到的设计模式

  • 工厂模式
  • 动态代理
  • 建造者模式
  • 单例模式
  • 观察者模式

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

11 BeanFactory 和 ApplicationContext有什么区别?
ApplicationContext是BeanFactory的子接口,BeanFactory是Spring最底层的接口,主要任务是赋值实例的初始化,懒加载,依赖管理,生命周期;ApplicationContext在其基础上还支持国际化,配置文件夹加载…

12 ApplicationContext通常的实现是什么?

  • FileSystemXmlApplicationContext :此容器从一个XML文件中加载beans的定义,XML Bean 配置文件的全路径名必须提供给它的构造函数。

  • ClassPathXmlApplicationContext:此容器也从一个XML文件中加载beans的定义,这里,你需要正确设置classpath因为这个容器将在classpath里找bean配置。

  • WebXmlApplicationContext:此容器加载一个XML文件,此文件定义了一个WEB应用的所有bean。

14 IoC 和 DI 的关系
IoC 是 Spring 中一个极为重要的概念,而 DI 则是实现 IoC 的方法和手段。DI的实现方式如下

  • 构造器注入
public class UserController {
    private UserService userService;
    public UserController(UserService userService){
        this.userService = userService;
    }
}

<bean name="userController" class="com.learning.controller.UserController">  
    <!-- 依赖注入 -->  
    <constructor-arg ref="userService"></constructor-arg>  
</bean>  
<bean name="userService" class="com.learning.dao.impl.UserServiceImpl"></bean>  

  • setter注入,参考案例如下
public class UserController {
    // 注入 UserService 对象
    private UserService userService;
    public void setUserService(UserService userService){
        this.userService = userService;
    }
}
<bean name="userController" class="com.learning.controller.UserController">  
    <!-- 依赖注入 -->  
    <property name="userService" ref="userService"></property>  
</bean>  
<bean name="userService" class="com.learning.dao.impl.UserServiceImpl"></bean>

  • 注解注入
@Controller
public class UserController {
    // 使用注解自动注入
    @Autowired()
    private UserService userService;
    // do something
}

// 创建依赖对象
@Service
public class UserService {
   // do something 
}

15 AOP
16 五大通知方法
参考:https://blog.csdn.net/wwwwwww31311/article/details/113577090

17 @Value 注解的作用是什么?

答:基于 @Value 的注解可以读取 properties 配置文件,使用如下:

@Component 和 @Bean 有什么区别

  • 前者是作用于类上,表示动态的侦测并装配该类路径下的对象资源
  • 后者作用于配置类的配置方法上,配置类@Configuration修饰,等价于spring.xml,相当于Spring中的ioc容器,@Bean修饰的方法等于xml配置文件中的bean组件,相当于告诉spring这是某个类的实例,当我需要这个对象资源时就把它给我,因此它的作用域比前者更广,例如某些第三方类库就可以通过@Bean装配都IOC容器中

Spring中如何实现事物

  • 声明式事务管理:Spring的AOP原理,这意味着你可以将业务代码和事务管理分离,你只需用注解和XML配置来管理事务。优点是低侵入式编程,方便维护和管理,灵活性低,体现在配置上必须统一配置,范围只能作用在方法范围
  • 编程式事务管理:这意味你通过编程的方式管理事务,给你带来极大的灵活性,但是难维护。

15.Spring 中的 Bean 是线程安全的吗?

答:Spring 中的 Bean 默认是单例模式,Spring 框架并没有对单例 Bean 进行多线程的封装处理,因此默认的情况 Bean 并非是安全的,最简单保证 Bean 安全的举措就是设置 Bean 的作用域为 Prototype(原型)模式,这样每次请求都会新建一个 Bean。

详细参考:https://blog.csdn.net/wwwwwww31311/article/details/115296736

16.Spring 声明式事务无效可能的原因有哪些?

  • MySQL 使用的是 MyISAM 引擎,而 MyISAM 是不支持事务的;
  • @Transactional 使用在非 public 方法上,@Transactional 注解只能支持 public 级别,其他类型声明的事务不会生效,或者@Transactional 在同一个类中无事务方法 A() 内部调用有事务方法 B(),那么此时 B() 事物不会生效。
  • 方法的调用者并非是aop创建的代理类对象,比如使用了this,而没有通过自动装配来获取到组件

15.Spring 中的 Bean 是线程安全的吗?

答:Spring 中的 Bean 默认是单例模式,Spring 框架并没有对单例 Bean 进行多线程的封装处理,因此默认的情况 Bean 并非是安全的,最简单保证 Bean 安全的举措就是设置 Bean 的作用域为 Prototype(原型)模式,这样每次请求都会新建一个 Bean。

16 组件的生命周期
1 容器启动时实例化组件
2 依赖注入,通过构造器,setter,组件,工厂模式…
3 后置处理器的before方法
4 初始化方法init
5 后置处理器的after方法
6 容器关闭时调用destory方法

class => 推断构造方法,利用反射进行对象实例化,此后的两步相当于对实例化对象的加工 =>
 通过DI依赖注入属性填充 => init-method,执行完这一步可以获得完整的bean => 
 判断是否受AOP切面影响,AOP动态代理获取bean的代理类对象 => bean 

17 什么是Spring beans?
Spring beans 是那些形成Spring应用的主干的java对象。它们被Spring IOC容器初始化,装配,和管理。这些beans通过容器中配置的元数据创建。比如,以XML文件中 的形式定义。

18 ①Spring定义bean的几种方式

  • Set方法注入;
  • 构造器注入;
  • 静态工厂注入;
  • 实例工厂;
  • 基于注解@Controller,@Service,@Component

②依赖注入的几种方式

  • 通过@Autowired自动装配,进行构造器注入,setter注入,方法参数注入,接口实现类对象注入
  • 通过setter注入
  • 通过constructor注入
  • 通过静态工厂注入
  • 通过实例工厂注入

19 如何给Spring 容器提供配置元数据?Spring有几种配置方式

  • XML配置文件。
  • 基于注解的配置。
  • 基于java的配置。

20 @Autowired注解
本质:容器会在自动包扫描路线下扫描带有这个注解的属性,一单发现这个组件就要去容器中找到相应的组件并进入注入,相当于给这个属性赋值
功能:用于给指定字段(field,setter,constructor,method’s param)注入所需的外部资源,完成自动装配,默认是①byType,如果同一类型有多个组件再以byName的方式寻找,可以通过@Qualifier和@AutoWired进行指定组件名称的查找②如果没找到会报错,只有设置required=false才可以

21 @Autowired注解和@Resource区别

  • 作用范围不相同(field,setter,constructor,method’s param)
@Autowired作用域:@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})

@Resource作用域:@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
  • 策略不同,前者默认按类型操作,如果找到多个再按组件名字查找,或者通过@Qualifier判断,后者默认按名字查找,即使没有指定名字也会安装注解作用的对象名来匹配,按默认组件名没有查找到再按类型查找

22 java对象,javaben,springbean区别

  • java对象是java类的对象,如String对象,Integer对象,Map对象…
  • javabean,特殊的java对象,自定义类,属性全为private,对外提供getter和setter方法
  • springbean:在spring容器中定义bean组件,在应用程序中通过主动获取或者

23 spring常见的设计模式

  • 简单工厂模式,通过BeanFactory的getBean方法,传入一个对象名即可获取到对象
  • 工厂模式:一些实现了factorybean并重写getObject方法的对象,再次通过getBean加载对象时获取的不是这个bean,而是调用这个bean中重写的getObject方法获取到对象
  • 适配器模式:通过请求到handlerMapping中获取到handler后根据handlerAdaptor获取到该handler的适配器,并根据适配器调用hander中的方法进行处理
  • 观察者模式:Spring的事件驱动组件,如listerner的实现
  • 代理模式:①aop获取代理类对象②sql映射文件对象
  • 单例模式:加载beanFacory,也就是加载ioc容器时保证只加载一份

24 spring的事物实现方式
①编程式,手动编写事物

try{
    connection.setAutoCommit(false); //aop前置方法,关闭自动提交
    operation sql   //执行sql语句,aop主方法
    connection.commit()  //aop后置方法,手动提交
}catch(Exception e){
    connection.rollback();//aop异常方法,出现异常回滚
}finally{
    connection.close();//aop结束方法,归还连接到连接池
}

②声明式,通过@Transactional注解来,被该组件修饰的类最终被加载到ioc容器的不失原生的bean,而是通过aop的cglib生成的代理类对象,同时将通知方法(关闭自动提交,回滚,手动提交,关闭资源)切入到了核心方法(sql操作语句)中,通过代理类对象执行的就是事物方法

25 sping事物无效

  • 事物本身时通过AOP机制,获取到service的代理类对象,由代理类对象执行的才是事物方法,所有,如果我们使用this来调用就相当于普通的调用,解决方式通过@Autowired将service对象注入进来
  • 事物方法是非public
  • 当前service并未注册到ioc容器中
  • 方法中的异常被try-catch处理了
  • 数据库本身不支持事物

在这里插入图片描述
26 实现一个IOC容器

  • 配置自动包扫描路径
  • 使用注解,如@mapper,@service,@controller在被扫描的路径下定义相关的类
  • 反射期间获取这些类的.class文件,存储在一个Set集合中
  • 遍历Set集合,如主要是通过反射期间调用构造器构造这些对象,并用一个安全的map集合进行存储,期间还要判断对象中是否还依赖其它的实例,是的话就递归注入
  • 如果有@Autowired修饰的属性按照@Autowiired为他们注入相关的对象
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值