Java框架-Spring相关
1. Spring模块
答:Spring是一个轻量级的IOC和AOP容器框架。目的是简化应用开发,让开发者注重业务开发。
1.1 核心模块
5.x版本中Web模块的Portlet组件被废弃,增加了异步响应的WebFlux组件。
- Spring Core:基础,Spring所有其他功能都依赖于该类库,只要提供IoC依赖注入功能。
- Spring Aspects:为与AspectsJ的集成提供支持
- Spring AOP:面向切面编程的实现
- Spring JDBC:Java数据库连接
- Spring JMS:Java消息服务
- Spring ORM:支持Hibernate等对象关系映射关系工具
- Spring Web:为创建Web应用程序提供支持
- Spring Test:提供对JUnit测试的支持
1.2 优点
答:依赖注入把对象间的依赖关系交给框架处理,减小了组件间的耦合性;AOP面向切面编程,复用性高;声明式事务;封装其他主流框架的功能。
2. AOP
答:AOP面向切面编程,指当需要在某一方法之前或之后做一些额外的操作,比如日志记录、权限判断、性能监视等。
2.1 常用术语
- Target(目标对象):代理的目标对象,即要增强的类;
- Joinpoint(连接点):类里可以被增强的方法;
- Pointcut(切入点):对哪些连接点进行拦截;
- Advice(通知/增强):拦截到连接点后要做的事;
- Weaving(织入):把增强advice应用到目标target的过程;
- Proxy(代理):一个类被AOP织入增强后,就产生一个结果代理类;
- Aspect(切面):切入点pointcut和增强advice的结合。
简单总结:target是类,连接点就是类中方法,切入点是要拓展功能的方法,增强就是指拓展功能的逻辑,切面就是把增强应用到具体方法上。
2.2 两种实现方法
2.2.1 JDK动态代理
针对实现了接口的类。原理是运行期间创建一个接口的实现类完成对目标对象的代理。
步骤:
- 定义一个实现接口InvocationHandler的类
- 通过构造函数,注入被代理类
- 实现invoke( Object proxy, Method method, Object[ ] args)方法
- 在主函数中获得被代(dai)理类的类加载器
- 使用Proxy.newProxyInstance( )产生一个代理对象
- 通过代理对象调用各种方法
2.2.2 cglib代理
针对普通类代理,对实现接口无要求。原理是对指定类生成一个子类(extends继承),覆盖其中的方法。
步骤:
- 定义一个实现了MethodInterceptor接口的类
- 实现其 intercept()方法,在其中调用proxy.invokeSuper()
2.3 Spring AOP和AspectJ AOP区别
答:SpringAOP属于运行时增强,基于代理实现。AspectJ AOP是编译时增强,基于字节码操作。
当切面太多时,AspectJ AOP的性能更好。
3. IOC
答:IOC控制反转,是一种设计思想。将创建对象的控制器由程序交给Spring框架管理。IOC容器是实现IOC的载体,内部是一个Map,存放各种对象。
3.1 IOC初始化过程
答:IOC初始化过程就是对Bean定义资源的定位、载入和注册。
- Resource定位:Resouce定位是指BeanDefinition的资源定位,也就是IOC容器找数据的过程。由ResourceLoader通过统一的Resource接口来完成定位。
- BeanDefinition的载入:载入过程就是把将用户定义好的Bean表示成IOC容器的内部数据结构BeanDefinition。IOC容器内部维护着一个BeanDefinitionMap的数据结构。
- BeanDefinition的注册:注册就是将前面的BeanDefition保存到Map中的过程,通过BeanDefinitionRegistry接口来实现注册。
总结:找数据->把Bean转为BeanDefinition->把BeanDefinition保存到Map
3.2 Bean的注入
答:ApplicationContext默认在容器启动时创建用户配置的Bean。
3.3 BeanFactory和FactoryBean的区别
答:区别为:
- BeanFactory:Bean工厂,是一个工厂,IOC的顶层接口,用来实例化配置Bean;
- FactoryBean:工厂Bean,是一个Bean,作用是产生其他Bean实例。
3.4 ApplicationContext
答:ApplicationContext是对Bean工厂的派生,增加加载多个配置文件,多个上下文等功能。
实现方式:
- FileSystemXmlApplicationContext:从XML文件中加载Bean的定义,XML Bean配置文件的全路径名必须提供给它的构造函数。
- ClassPathXmlApplicationContext:从XML文件中加载Bean的定义,在classpath里找Bean配置。
- WebXmlApplicationContext:加载XML文件,定义了一个WEB应用的所有Bean。
3.5 BeanFactory和ApplicationContext的区别
答:区别如下:
- Bean工厂采用延迟加载来注入bean。ApplicationContext在容器启动时一次性创建所有的bean。
- Bean工厂启动速度快,运行速度慢,调用对象才会产生异常错误。ApplicationContext启动速度慢,内存占用大,运行速度快。
4. Spring Bean
4.1 Bean的作用域
答:Spring支持五种Bean的作用域。
- singleton : bean实例是唯一的,默认单例。
- prototype : 一个bean定义有多个实例。
- request : 每次HTTP请求都会创建一个bean,该bean仅在当前HTTP request内有效。
- session : 每次HTTP请求都会创建一个 bean,该bean仅在当前 HTTP session 内有效。
- global-session: 全局session作用域,仅仅在基于portlet的web应用中才有意义。
4.2 单例bean的线程安全问题
答:单例bean存在线程问题,因为当多线程操作同一个对象时,对这个对象的非静态成员变量的写操作会存在线程安全问题。解决方案推荐在类中定义一个ThreadLocal保存可变成员变量。
4.3 循环依赖问题
答:A创建过程中要用到B,但B也要用到A,这就是循环依赖。这种构造器依赖无法解决,只能抛出BeanCurrentlyInCreationException异常。
4.4 @Component和@Bean区别
答:总结为:
- 作用对象:@Component作用于类,@Bean作用于方法
- @Component通过类路径扫描来检测并装配到Spring容器中,@Bean通常是在标有该注解的方法中定义产生bean,告诉Spring这是某个类的实例,在用到的时候返回
- @Bean比@Component的自定义性更强
5. Spring事务
答:Spring事务分为编程式事务管理和声明式事务管理。
- 编程式事务管理:使用Transaction Template实现;
- 声明式事务管理:基于AOP,对方法前后进行拦截,将事务处理编织到增强方法中。推荐使用这种符合Spring非侵入式开发的方式。
5.1 事务传播行为
- PROPAGATION_REQUIRED:**如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务。**默认设置。
- PROPAGATION_SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就以非事务执行。
- PROPAGATION_MANDATORY:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常。
- PROPAGATION_REQUIRES_NEW:创建新事务,无论当前存不存在事务,都创建新事务。
- PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
- PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
- PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则按REQUIRED属性执行。
5.2 事务隔离级别
答:和MySQL的事务隔离级别类似,读未提交、读已提交、可重复读和串行。
6. Spring MVC
6.1 Spring MVC的理解
答:MVC是一种设计模式,Spring MVC是一个轻量级的基于请求驱动的Web框架。一般把后端项目分为Service层(处理业务),Dao层(数据操作),Entity层(实体类),Controller层(控制层)。
6.2 Spring MVC工作原理
答:概括为:通过前端控制器DispatcherServlet来接收并且分发请求,然后通过HandlerMapping和HandlerAdapter找到具体可以处理该请求的Handler,经过逻辑处理,返回一个ModelAndView,经过ViewResolver处理,最后生成了一个View视图返回给了客户端。