JAVA面试题--Spring

介绍一下Spring

Spring是一个开源的轻量级控制反转和面向切面编程的容器框架。轻量级是说它开发使用简单,功能强大。控制反转是指将对象的创建,销毁控制交给ioc容器,方便解耦合,降低维护难度,面向切面编程是指将相同的逻辑横向抽取出来,可以对一些通用业务如事务,日志进行集中管理

说下Spring框架的组成
  1. CoreContain核心容器模块:

    1. spring-core:提供框架的基本组成部分,包括 IoC 和依赖注入功能

    2. spring-beans:提供 BeanFactory,工厂模式

    3. context:提供国际化,事件传播,资源加载等功能

    4. spring-ExpressionLanguage:提供表达式语言

  2. Web模块

    1. Web:提供面向web的基本功能和面向web的应用上下文

    2. Web-MVC:为web应用提供模型视图控制(MVC)

    3. Web-Socket:在 web 应用程序中提供客户端和服务器端之间通信的方式

    4. Web-Portlet:模块提供了用于Portlet环境的MVC实现

  3. 数据/集成模块

    1. JDBC:包含了Spring对JDBC数据访问进行封装的所有类

    2. ORM:为对象-关系映射提供交互层

    3. OXM:提供对Object/XML映射实现的抽象层

    4. JMS:主要包含了一些制造、消费和消息的功能

    5. Transaction:为实现特殊接口类以及所有的 POJO 支持编程式和声明式的事务管理

  4. 其他模块

    1. AOP:提供了面向切面编程相关实现

    2. Aspects:模块提供了与AspectJ的集成,是一个功能强大的AOP框架

    3. Instrumentation:提供了class instrumentation 的支持和类加载器classloader的实现

    4. Messaging:为 STOMP 提供支持

    5. Test:支持使用JUnit和TestNG对Spring组件进行测试

什么是Spirng的IOC

IOC控制反转,把对象的创建,属性设置,初始化,销毁等工作交给Spirng的IOC容器去管理,解放程序员的劳动力。

对象被注册到Spring的IOC容器中,使用的时候从容器中获取即可,非常方便。

它通过依赖注入,将需要的外部资源注入到组件中,使用IOC使得对象之间的耦合度降低,资源变得容易管理,从而使得代码更加优雅

你对AOP的理解

AOP,Aspect Oriented Programming 英文首字母缩写,意为面向切面编程,是Spring的核心思想之一

AOP是对OOP(面向对象编程)的一种补充,能够做到很多面向对象无法做到的事情,比如需要在所有方法执行前开启事务,打印日志,如果使用面向对象来编程,将会产生大量重复代码,而使用AOP,可以将那些与业务无关,却为业务模块所共同调用的逻辑封装起来,一次解决这些问题。而这些重复的代码,一般统称为横切逻辑代码

使用AOP,在不改变原有业务逻辑的情况下,实现解耦合,避免横切逻辑代码重复

AOP的使用场景包括日志记录,性能统计,安全控制,事务处理,异常处理等等

它是基于动态代理实现的,分为JDK动态代理和CGLIB动态代理。JDK动态代理只支持实现了接口的类 ,CGLIB支持没有实现接口的类。Spring默认使用JDK动态代理,如果被代理类没有实现接口,会选择CGLIB动态代理

Spring的Bean懒加载和非懒加载有什么区别

懒加载:需要使用对象的时候才创建,节省资源,但不利于提前发现错误

非懒加载,也叫迫切加载,容器启动时就创建对象,消耗资源,但有利于提前发现错误

spring中默认时迫切加载,即在项目启动时,spring会扫描符合条件的所有bean并将其初始化

如果需要懒加载,可以使用@Lazy注释或者xml中配置属性default-lazy-init="true"

Spring的依赖注入方式有哪些

方式一:setter方式注入,通过反射调用无参构造方法生成对象,再通过对于的setter方法注入配置的值,支持注解和xml两种实现方式

方式二:构造器方式注入,通过反射调用有参构造方法生成对象,支持注解和xml两种实现方式

注解实现方式:@Autowired,它是默认按类型匹配的、@Resource,它是默认按名字匹配的

@Autowired和@Rescource区别:

@Autowired是Spring框架提供的,@Rescource是JDK提供的(只是提供,并没有实现,只是一个规范,Spring框架实现了这个规范); 相比于@Autowired,@Rescource支持更多参数的设置,例如name设置,可以根据名称来获取Bean。

说一下定义切面相关的注解

@Aspect:定义切面

@Pointcut:定义切点 = cn.xx.service.*

@Before:前置通知,在目标方法运行之前运行

@After:后置通知,在目标方法运行结束之后运行(无论方法正常结束还是异常结束)

@AfterReturning:返回通知,在目标方法正常返回之后运行

@AfterThrowing:异常通知,在目标方法出现异常以后运行

@Around:动态代理,手动推进目标方法运行

Bean的四种注册方式

方式一:普通注册方式,直接通过class注册

方式二:简单静态工厂方式注册

方式三:简单实例工厂方式注册

方式四:FactoryBean方式注册

注册Bean的注解有哪些

@Controller/@RestController 一般用于定义控制层的类

@Service 一般用于定义服务层的类

@Repository 一般用于定义持久层类

@Component 定义一般类

@Configuration 定义配置类

IOC的启动流程有了解过吗

当Spring启动时,IOC容器会加载Spring的配置文件,包括XML配置或者注解,然后解析这些Bean并把相关定义信息封装成BeanDefinition对象,通过Bean注册器BeanDefinitionRegistry注册到IOC容器,也就是一个ConcurrentHashMap中

此时会找出所有的单例且非惰性加载的bean,根据其BeanDefinition进行Bean的实例化,它会判断如果bean中有方法覆盖,就使用JDK反射创建Bean,否则使用CGLIB方式生成代理。然后把实例化好的Bean缓存到一个ConcurrentHashMap中

Bean的生命周期讲一下

从宏观的角度来说就是:实例化 ,属性注入,初始化,使用,销毁。更细的生命周期如下

  1. 实例化:如果是单例且迫切加载的bean,在Spring容器启动时就会根据BeanDefinition进行实例化,如果时设置了懒加载或者多例模式的bean,在用的时候才会实例化

  2. 属性赋值:通过BeanDeifinition找到当前Bean所依赖的其他Bean,如果容器中有就直接拿过来,如果没有就根据创建流程区创建依赖的bean,然后通过反射给依赖的字段注入值

  3. 然后会调用BeanPostProcessor的前置处理器,对于@Autowired和@Transcational就是基于BeanPostProcessor来实现的。

  4. 接着会看Bean是否实现InitializingBean ,如果有会触发其afterPropertiesSet方法的调用

  5. 接着是调用我们自定义的bean的init-method方法,此时会调用执行

  6. 然后是调用BeanPostProcessor的后置处理

  7. 容器正常关闭,Bean进行销毁,会先调用实现了DisposableBean的destory方法。

  8. 接着调用我们指定的bean的destroy-method方法,此时会调用执行

单例多例的区别

单例和多例属于对象模式,单例模式指对象在整个系统中只存在一份,多例模式则可以有多个实例。

在spring的ioc容器中的bean默认都是单例的,如果需要使用多例,可以通过修改scope属性:scope="prototype"

如果一个bean是单例模式的,在处理多次请求的时候,在ioc容器中只实例化一个bean,这个对象会被保存在一个map中,当有请求来的时候,会先从map中查看,如果有就直接使用这个对象,没有才会实例化新的对象。

如果是多例(prototype)模式的bean,每次请求来的时候,会直接实例化新的bean,没有map缓存的过程。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值