1.Spring有哪些重要的模块
- spring JDBC:数据库连接
- Spring AOP:面向切面编程
- Spring Core:几乎所有功能来自这个模块,提供IOC依赖注入功能
- Spirng web:web应用程序
- Spring Test:提供JUnit和TestUG
2.@RestController 和@Controller区别
前者返回的Json形式的数据,前后端分离
后者返回的是一个视图页面,前后端不分离
@ResponseBody的主要作用是将Controller方法返回的对象以Json,写入到httpResponse对象的body中
3.Spring IOC和AOP
IOC
ioc是一种设计思想,将原本需要手动创建对象的权利,交给了Spring容器,Ioc容器实际上是一个Map,map中存放的是各种对象
当我们需要用到某些对象的时候,只需要配置或注解即可,不用手动创建,也不用考虑对象是怎么被闯将出来的
AOP
将那些与业务无关,但是又在每个业务逻辑中共同用到的方法抽象出来(如事务处理,日志管理,权限控制)减少系统的重复代码,利于代码的可拓展性和可维护性
4.SpringAOP和AspectJ的区别
首先,SpringAOP已经集成了AspectJ。
- SpringAOP不完备,而AspectAOP是完备的AOP实现方案。当切面比较多的时候,首选AspectJ
- SpringAOP是在运行阶段织入;而AspectJ是在编译阶段织入,具体分为编译期织入;编译后织入;加载时织入
- AspectJ功能强大,支持方法调用,构造方法调用,属性调用等;而SpringAOP只支持在连接点执行方法。
Spring Bean
1. Spring中的Bean作用域有哪些?
首先来说,Spring中的Bean都是默认单例的。
作用域一共有五个:
request,session,和globalSession只能用于web应用
1.Singleton:单例类型,在创建容器的时候就创建了对象,不管是否用
2.Prototype: 这种Bean在创建容器的时候没有初始化,每当我们获取Bean 的时候就新建一个实例,每次获得的对象不同
3.request:每个http请求都会有各自的bean实例,并且bean仅在当前请求有效
4.Session:仅在一个 httpSession中有效
5.globalSession:仅在基于protlet context作用域有效
2. Spring中的单例Bean存在的线程安全问题
这种线程安全问题主要发生在多线程的环境下,当多个线程同时访问一个Bean中的非静态成员变量时,并且操作为写的时候,会存在安全问题。
解决方法:
1.避免定义可变的成员变量(不现实)
2.在类中定义一个ThreaLocal成员变量,将那些可变的成员变量保存在ThreadLocal中
3. @Component和@Bean有什么区别
首先来说,@Component是标注在类的上面的,而@Bean标注在方法的上面。@Bean一般与@Configuration连用
@Component以及@Service,@Repository等都是根据类路径自动扫描并装配到Spring容器中的,这种方式的逻辑控制能力有限
而@Bean是显示声明单个Bean,它将类的定义与bean的装配分割开,精准的创建和配置bean
当我们在第三方需要装配bean的时候,@Component无法做到,而@Bean可以
4.将一个类声明为Bean的注解有哪些?
- @Component
- @Repository
- @Service
- @Controller
5. bean的生命周期
1. bean的容器,找到spring配置的bean定义
2.bean容器利用反射机制创建bean实例对象
3. bean容器为实例化的对象属性赋值
在初始化前,需要实现很多Aware接口
4.如果实现了 beanNameAware接口,就执行setbeanname方法
5.如果实现了beanClassLoadeAware接口,就执行setbeanclassloader方法
5.如果实现了beanFactoryAware接口,就执行set。。方法
。。。等等Aware接口
6.如果定义了初始化方法,就按初始化方法初始化bean
最后要做的是销毁实例对象
4. 销毁对象时,如果bean实现了DisposableBean接口,执行destroy方法;若自定义了销毁方法,则执行自定义的销毁方法
说一说Spring MVC的理解
为什么会有SpringMVC?
首先在springMVC应用广泛之前,Model11时代 web应用都是由JSP组成的。这种模式下,JSP既是控制层,又是视图层,导致代码耦合性太高,代码复用性低,前后端相互依赖严重。
在Model12时代 web应用由 java Bean+JSP+servlet实现,这就是早期的 java webMVC开发模式
这种开发模式解决了代码复用性低的问题,但是 这种模式的抽象和封装程度不够,无法避免重复造轮子的,大大降低了开发效率,并且程序的复用性和可维护性低。
于是 产生了 springMVC框架,以及Struts2等框架。
springMVC实现过程
- 首先用户发起请求到Controller层(接受请求,调用业务层,派发页面),将请求交给业务层处理,业务层与DAO层交互,并处理业务,返回处理结果给Controller层,Controller层将结果显示到View视图层
springMVC原理
- i请求发送交给DispatcherServlet(前端控制器)
- 前端控制器请求HandlerMapping(解析地址)获取具体的Handler
- HandlerMapping将具体的Handler返回给DispatcherServlet
- DIspatcherServlet将获得的Handler交给HandlerAdatper
- HandlerAdapter执行Handler,Handler也就是Controller,Handler执行结束返回一个ModelandView对象给HandlerAdapter
- HandlerAdapter将ModelandView对象返回给DispatcherServlet
- DispatcherServlet请求视图解析器(viewResolver)处理视图,并返回一个view对象
- DispatcherServlet根据view进行渲染视图
springMVC中用到了哪些设计模式
- 工厂模式:BeanFactory,ApplicationContext创建Bean对象
- 代理模式:SpringAOP的实现
- 单例模式:spring中的Bean默认是单例的
- 包装器模式:项目连接多个数据库,根据请求的不同,访问不同的数据源
- 观察者模式:Spring事件驱动模型是观察者模式的应用
- 适配器模式:SpringMVC的Controller用到了适配器模式
spring的事务
spring管理事务的方式
分为两种,编程式事务和声明式事务。声明式事务用的比较多,在配置未见中配置,或用注解声明推荐使用。
声明式事务又分为两种,xml配置和注解实现
spring中事务的隔离级别
- 默认隔离(default):使用数据库默认的隔离级别,Mysql默认可重复度级别,oracle默认读已提交级别
- 读未提交:最低的隔离级别,能读到未提交数据
- 读已提交:允许读取并发事务已提交的数据
- 可重复读:对一段数据多次读到的数据一致
- 序列化:完全服从ACID隔离级别,但是会严重影响性能
spring的事务传播行为
什么是事务的传播行为?
两个事务方法之间,才能发生传播行为。事务的传播是指,当事务方法A调用事务方法B的时候,事务方法B会怎么执行?,是按照事务A的方法执行还是开启新的事务呢?这些不确定性都是由事务方法B的事务传播行为决定的
@Transactional(rollbackFor=Exception.class)了解么?
首先 @Transactional用于注解在类上的,可以让该类的所有方法都具有事务性
如果不配置rollbackFor=Exception.class,就会在运行时异常回滚,而配置后会在运行时和非运行时异常都回滚。
怎么使用JAP非持久化一个数据
JAP是Java持久化的一个API
四种方法非持久化一个数据:
针对 String s:
static String s;
final String s;
transient String s;
@Transient
String s;
后两种用的较多。
非持久化指的是,这个字段不被数据库存储