Spring相关面试题2

14、Spring框架中的Bean的作用域

singleton:Spring只会为该bean对象创建唯一实例,Spring中的bean默认都是单例

prototype:每次获取bean,Spring会创建一个新的实例

requset:每一次HTTP请求,Spring会创建一个新的bean实例

session:不同的HTTP会话,Spring会创建不同的的bean实例

通过XML方式设置bean的作用域

<bean id="demoDaoBean" class="com.apesource.dao.DemoDAOImpl" scope="singleton"/>

通过注解方式设置bean的作用域

@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class DemoDAOImpl implements IDemoDAO{ }

15、Spring框架中Bean的线程安全

  • 对于 prototype 作用域的 Bean,每次都创建一个新对象 ,也就是线程之间不存在Bean共享,因此不会有线程安全问题
  • ·对于 singleton 作用域的 Bean,所以的线程都共享一个单例状态的Bean,存在资源竞争,因此时存在线程安全的
  • 解决办法

1、对于 singleton 作用域的单例Bean,他的线程安全问题,有常见的两种解决办法

1.1、在bean 中尽量避免定义可变的成员变量(用于保存数据的成员变量);
1.2、在类中定义一个ThreadLocal成员变量,将需要可变的成员变量保存在ThreadLocal中;

16、Spring框架中的Bean声生命周期

Spring Bean的生命周期总体分为四个阶段:实例化=>属性化=>初始化=>销毁

1、实例化Bean:

根据配置文件中Bean的定义,利用Java Reflection反射技术创建Bean的实例

2、注入对象的属性值(或对象)
3、处理各种Aware接口:
  • Spring会检测Bean是否实现了xxxAware接口,通过Aware类型的接口,可以让Spring框架为当前Bean注入响应的内容
  • 如果 Bean 实现 BeanNameAware 接口,会调用它实现的 setBeanName(String beanId)方法,注入 Bean 的名字;
  • 如果 Bean 实现 BeanClassLoaderAware 接口,调用 setBeanClassLoader()方法,注入ClassLoader 对象的实例;
  • 如果 Bean 实现 BeanFactoryAware 接口,会调用它实现的setBeanFactory()方法,注入的是 Spring 工厂;
  • 如果 Bean 实现 ApplicationContextAware 接口,会调用 setApplicationContext()方法,注入 Spring 上下文;
4 、执行BeanPostProcessor前置处理:

 如果想对 Bean进行一些自定义的前置处理,那么可以让 Bean 实现了 BeanPostProcessor 接口,将会在该阶段调用 postProcessBeforeInitialization(Object obj, String s)方法。

5、 执行InitializingBean初始化方法:

如果 Bean 实现了InitializingBean 接口,执行 afeterPropertiesSet()方法。

6、执行init-method自定义初始化方法:

如果 Bean 在 Spring 配置文件中配置了 init-method 属性,则会自动调用其配置的初始化方法。

7、执行BeanPostProcessor后置处理:

如果这个 Bean 实现了BeanPostProcessor接口,将会调用 postProcessAfterInitialization(Object obj,String s)方法,由于这个方法是在 Bean初始化结束后调用

8、执行DisposableBean销毁Bean:

当 Bean 不再需要时,会经过清理阶段,如果 Bean 实现了 DisposableBean 这个接口,会调用其实现的destroy()方法执行销毁;

9、执行destroy-method自定义销毁方法:

如果这个Bean的Spring 配置中配置了 destroy-method 属性,会自动调用其配置的自定义销毁方法。

17、Sprng框架如何解决循环依赖

循环依赖问题是指:类与类之间的依赖关系形成了闭环,就会导致循环依赖问题的产生。例如A类依赖了B类,B类依赖了C类,而最后C类又依赖了A类,这样就形成了循环依赖问题;

为了解决循环依赖问题,Spring容器采用了以下几种策略:

  1. 三级缓存:Spring容器使用三级缓存来解决属性循环依赖。第一级缓存是SingletonObjects,用于存储完全初始化的bean;第二级缓存是earlySingletonObjects,用于存储已经创建但尚未初始化的bean;第三级缓存是singletonFactories,用于存储用于创建bean的ObjectFatory  当容器遇到循环依赖时,它会尝试从第二级或第三级缓存中获取bean,而不是直接实例化它。

  2. 延迟初始化:Spring容器允许延迟初始化bean,这意味着在需要时才创建和初始化bean。这有助于避免在循环依赖的情况下过早地实例化bean。

  3. 代理对象:对于通过AOP增强的bean,Spring容器会创建一个代理对象来替代原始bean。这个代理对象负责处理循环依赖,同时保留原始bean的行为。

 18、Spring框架中有那些注解

  • 用于声明的注解:

@Component:通用Bean的注解,可标注任意类为Bean如果一个Bean不知道属于哪个层,可以使用@Component注解标注。

@Repository:定义数据访问层Bean的注解。

@Service:定义业务层Bean的注解。

@Controller:定义控制器Bean的注解。

  • 用于注入的注解:

@Autowired:按类型自动注入

@Qualifier::按名称自动注入

  • 声明配置、扫描、启用特性的注解:

@Configuration:声明配置类

@ComponentScan:组件扫描

@EnableScheduling:任务调度

@EnableAspectJAutoProxy:启动自动代理工程、

19、Spring框架中用到的设计模式

工厂模式:Spring 使用工厂模式,通过 BeanFactory 或 ApplicationContext 来创建对象;

单例模式:Bean 默认作用域为单例,按照单例设计模式进行设计实现;

策略模式: Resource 的实现类,针对不同的资源文件,实现了不同方式的资源获取策略;

代理模式: Spring 的 AOP 的实现依靠动态代理(JDK的反射和CGLIB);

模板方法: Spring 提供了 JdbcTemplate,RedisTemplate 等模板对象,将相同的操作步骤进行了封装;

适配器模式:Spring AOP 的增强或通知(Advice)使用到了适配器模式, Spring MVC 中也用到了适配器模式适配 Controller;

20.Spring 框架中AOP的基本理解

关键字:AOP名词解释,AOP实现原理(动态代理)

AOP(Aspect-Oriented Programming:面向切面编程):将那些与业务无关,却为业务模块所共同调用的逻辑(例如事务处理、日志管理、权限控制等)封装抽取成一个可重用的模块,这个模块被命名为“切面”(Aspect),便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性;

Spring AOP 基于动态代理实现:

如果被代理的对象,已经实现某个接口,则 Spring AOP 会使用 JDK Proxy(反射),基于接口的方式,创建代理对象( JDK 动态代理的核心是 InvocationHandler接口和 Proxy类);

如果被代理的对象,没有实现某个接口,就无法使用 JDK Proxy去进行代理了,这时侯SpringAOP会使用使用Cglib,基于继承的方式,生成一个被代理对象的子类来作为代理(Cglib 动态代理的核心是 MethodInterceptor 接口和 Enhancer类);

21.Spring AOP和AspectJ AOP有什么区别?

关键字:增强方式的差异(运行时、编译时),实现方式的差异(动态代理、字节码操作)

Spring AOP 已经集成了 AspectJ, Aspect] 是一个 Java 技术生态系统中实现 AOP 编程思想的独立框架; AspectJ 相比于 Spring AOP 功能更加强大,但是 Spring AOP 相对来说更简单更容易;

Spring AOP 属于运行时增强,而 AspectJ是编译时增强;

Spring AOP 基于动态代理( Proxying),而 AspectJ基于字节码操作( Bytecode Manipulation );

22.Spring AOP有哪些通知类型?

关键字: 分别介绍每种通知的实现接口,执行方式

前置通知:实现 MethodBeforeAdvice 接口,在目标方法调用前,执行通知;

环绕通知:实现 MethodInterceptor 接口,是一个包围目标方法的通知。环绕通知可以在方法调用前后完成自定义的行为。

后置通知:实现 AfterReturningAdvice 接口,在在目标方法调用后,执行通知(如果方法抛出异(=常,则不执行通知);

异常通知:实现 ThrowsAdvice 接口,在方法抛出异常时,执行通知;

23.Spring 管理事务的方式有几种?

编程式事务:在代码中硬编码(不推荐使用):通过TransactionTemplate或者TransactionManager手动个管理事物实际应用中很少使用,用于理解 Spring 事务管理。

声明时事物:在 XML 配置文件或者基于注解@Transactional (推荐使用),通过 AOP实现。

24.Spring 事务中有哪几种事务传播行为?

事务传播行为是为了解决业务层方法之间互相调用时,产生事务问题。

当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。例如:方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己的事务中运行。

事务传播行为有如下分类:

1. TransactionDefinition.PROPAGATION_REQUIRED

如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。 @Transactional

注解默认使用的事物传播行为

2. TransactionDefinition.PROPAGATION_REQUIRES_NEW

创建一个新的事务,如果当前存在事务,则把当前事务挂起。也就是说不管外部方法是否开启事务,Propagation.REQUIRES_NEW修饰的内部方法会新开启自己的事务,且开启的事务相互独立,互不干扰。

3. TransactionDefinition.PROPAGATION NESTED

如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取

值等价于TransactionDefinition.PROPAGATION_REQUIRED。

 4. TransactionDefinition.PROPAGATIÓN_MANDATORY

如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。(mandatory:代表强制性)

5. TransactionDefinition.PROPAGATION_SUPPORTS

如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。

6. TransactionDefinition.PROPAGATION_NOT_SUPPORTED

以非事务方式运行,如果当前存在事务,则把当前事务挂起。

7. TransactionDefinition.PROPAGATION_NEVER

以非事务方式运行,如果当前存在事务,则抛出异常。

25.Spring 事务中有哪几种事务隔离级别?

1. TransactionDefinition.ISOLATION_DEFAULT 默认隔离级别

使用当前数据库的默认隔离级别,MySQL 默认采用的是可重复读 REPEATABLE_READ 隔离级

别。Oracle 默认采用的是读已提交 READ_COMMITTED 隔离级别.

2.TransactionDefinition.ISOLATION_READ_UNCOMMITTED 读未提交

最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读

3. TransactionDefinition.ISOLATION_READ_COMMITTED 读已提交

允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生

4. TransactionDefinition.ISOLATION_REPEATABLE_READ 可重复读

对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。

5. TransactionDefinition.ISOLATION_SERIALIZABLE 串行化

最高的隔离级别,完全服从 ACID 的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读,不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。



 


 


 

  • 11
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值