1. 说说你对spring的理解
Spring有两大特性:控制反转IOC 和 面向切面编程AOP,解决了传统代码的高耦合性与代码不可复用的问题,能很方便的整合各种开源框架,是一个非侵入式的,高效的开源框架。
IOC:控制反转,将创建对象的权利交给Spring,由Spring帮我们管理Bean。在面向对象的编程过程中,要想使用某个对象,就需要先实例化这个对象,需要我们用new XXX(),若该对象不存在就会报错。而在Spring中,我们不需要显式的去new,解决了代码的高耦合性。
AOP:面向切面编程,它是一种思想,是横向的。OOP:面向对象编程,是纵向的。先说说纵向的编程思想,举例:在JAVA中,有一个类A有一个方法,类B也想使用,那么怎么解决呢,就需要类B去继承类A,如果类C也想使用,那么需要去继承类A或类B。而横向编程的思想就是:将类A的公共方法提取出来,哪些类需要,就横切穿插进去,这就是AOP面向切面的横向编程思想,解决了代码的不可复用性。
2. 说说Spring的核心容器
Spring的主要功能是通过其核心容器来实现的。Spring提供了两种核心容器,分别为BeanFactory与ApplicationContext。
BeanFactory:是基础类型的IOC容器,提供了完整的IOC服务支持。简单来说,就是一个管理Bean的工厂,主要负责初始化各种Bean,并调用他们的生命周期方法。
采用延迟加载策略来初始化Bean,即在真正用到Bean(调用getBean())的时候才去实例化Bean,减小了服务器的压力,但是若Bean的某一属性并没有注入成功或Bean配置错误等,那么真正用到这个Bean时才报错,这不便于我们及时发现错误。
ApplicationContext:是BeanFactory的子接口,也被称为应用上下文。它不仅包含了BeanFactory的所有功能,还添加了对国际化,资源访问,事件传播等方面的支持。
在项目初始化启动的时候,就去实例化所有Bean,相当于一来就来了次自检,这样便于我们及时发现错误。
3. Bean的实例化方式有哪些
Bean:需要被Spring容器管理的对象。
实例化方式:
1. 构造器实例化 通过对Bean的构造方法来实例化。<bean id = "userService" class = "com.lihao.service.impl.UserServiceImpl">
2. 静态工厂实例化 要求开发者创建一个静态工厂的方法来创建Bean的实例,其Bean配置中的class属性所指定的不再是Bean实例的实现类,而是静态工厂类,同时还需要使用factpry-methond属性来指定所创建的静态工厂方法。
3. 实例工厂实例化 要求开发者创建一个工厂类,工厂类用普通方法创建Bean实例,同时Bean配置中不再是通过class属性指向实例化类,而是通过factory-bean属性指向配置的实例工厂,然后用factory-method属性指定工厂中创建实例的那个方法。
4. 注解实例化 @Controller @Service @Repository @Component[可作用于任何层次]
4. Bean的作用域
Spring中Bean的实例定义了七种作用域。
1. singleton 默认作用域,无论多少个Bean引用它,都会指向同一个实例对象。
2. prototype 每次获取的实例对象都是一个新实例。
3. request
4. session
5. globalSession
6. application
7. websocket
5. Bean依赖注入的方式有哪些
依赖注入:将一个Bean注入到另一个对象中。
注入方式:
基于XML:
构造器注入 在实例化Bean时,使用<bean>的子标签<constructor-arg>来定义构造方法的参数。
setter注入 在实例化Bean是,使用<bean>的子标签<property>来为各个属性进行注入值。【需要为被注入的属性提供setter方法】
基于注解
@Autowired 默认按照类型进行注入
@Resource 默认按照实例名注入,有两个属性,name和type。可以自己按需指定。
@Qualifier 与Autowired配合使用,会将默认的按类型注入改为按实例名注入,实例名由@Qualifier的参数指定。【一般用于由多个同类型Bean时】
@AutoWired与@Qualifier的理解:https://blog.csdn.net/weixin_43351375/article/details/101014896
6. 说说你对SpringAop的理解
AOP:面向切面编程,是对OOP的一种补充。AOP采用横向抽取机制,将分散在各个方法中的重复代码抽取出来,然后在程序编译或运行时,再将这些抽取的代码应用到需要的地方。这就是AOP横向编程思想。
虽然传统的OOP通过继承或组合的方式也能达到代码的重用,但如果需要实现某个功能(如日志记录),需要将代码编写到各个方法中,一旦想关闭或对其修改,就需要对所有相关方法进行修改。
目前常用的AOP框架有 SpringAOP与AspectJ。
SpringAOP:纯Java代码实现,在运行期间通过代理方式向目标类织入增强的代码。
AspectJ:一个基于Java语言的AOP框架。
SpringAOP:
Spring中的AOP代理,可以是JDK动态代理(默认),也可以是CGLIB动态代理。
JDK动态代理:
通过Proxy类来实现,通过调用其newProxyInstance()方法来创建代理对象。对于使用业务接口的类,Spring默认会使用JDK动态代理。
newProxyInstance():参数1:当前类加载器 参数2:被代理后的对象 参数3:代理类本身
代理类需要实现InvocationHandler接口,并编写代理方法invoke()。
invoke():参数1:被代理后的对象 参数2:将要被执行的方法 参数3:执行方法时需要的参数
JDK动态代理的实现:
https://blog.csdn.net/jiankunking/article/details/52143504
=================================================
CGLIB动态代理:
JDK动态代理有一定的局限性————使用动态代理的对象必须实现一个或多个接口。
对于没有实现接口的类进行代理,那么可以使用CGLIB代理。
底层采用字节码技术,对指定的目标类生成一个子类,通过对子类进行增强,从而达到对目标对象的增强。
代理类需要实现MethodInterceptor接口,并实现方法intercept()。
intercept():参数1:指定父类生成的代理对象 参数2:拦截的方法 参数3:拦截方法的参数数组 参数4:方法的代理对象,用于执行父类的方法
CGLIB动态代理的实现:
https://www.cnblogs.com/leifei/p/8263448.html
//////////////////////////////////
Spring种的AOP代理默认就是使用JDK动态代理的方式来实现的。具体就不贴代码了。
----------------------------------
Spring种的通知类型:
前置通知
后置通知
环绕通知
异常通知
最终通知
7. AspectJ
AspectJ:一个AOP框架,实现AOP的方式有两种,基于XML方式与基于注解的方式。【这里只介绍注解,XML用的太少了】
@Aspect
@Pointcut
@Before
@AfterReturning
@Around
@AfterThrowing
@After
@DeclareParents
AspectJ做AOP日志管理:https://www.cnblogs.com/jelly12345/p/14950731.html
8. Spring对于事物的管理
Spring提供了专门的API做事物处理,简化了传统的事物管理流程,在一定程度上减少了开发者的工作量。
Spring中的事物管理分为两种方式,传统的编程式事物管理与声明式事务管理。【编程式事务管理就是编写代码来管理事务,需要定义事物的开始,提交和异常时的回滚,这里不讲解此种】
声明式事物管理:
是通过AOP实现的,主要思想就是将事物管理作为一个切面代码单独编写,然后通过AOP技术横切织入到代码中。
实现方式:
1. 基于XML
2. 基于注解【这里只讲注解方式】
注解方式:
@Transational()
常用参数说明:
isolation:指定事物的隔离级别
propagation:指定事物的传播行为
read-only:指定事物是否只读
rollbackFor:指定事物遇到特定异常时强制回滚
timeout:指定事物的超时时长
9. Spring对于事物管理中的传播行为
传播行为:指当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行。【说得通俗一点就是多个具有事务控制的service的相互调用时所形成的复杂的事务边界控制】
传播行为详解:https://blog.csdn.net/weixin_39625809/article/details/80707695
10. Spring对于事物管理中的隔离级别
在mysql中,隔离级别主要是:1. 读未提交 2. 读已提交 3. 可重复度 4. 串行化
而在Spring中,多了一种隔离级别:default(默认)
default:意思是使用数据库本身使用的隔离级别。 Spring建议的是使用DEFAULT,就是数据库本身的隔离级别,配置好数据库本身的隔离级别,无论在哪个框架中读写数据都不用操心了。
Mybatis的mapper中如何传递多个参数
方法1:xml里面用#{0},#{1}....
方法2:@Param注解
方法3:封装成Map对象
方法4:封装成JavaBean对象
<foreach常用属性
collection
open
close
speparator
index 指定一个名称,用于标识当前迭代次数
item
<delete id="deleteBatch">
delete from user where id in
<foreach collection="array" item="id" index="index" open="(" close=")" separator=",">
#{id}
</foreach>
</delete>
SpringMVC工作流程
1)用户发送请求至前端控制器 DispatcherServlet。
2)DispatcherServlet 收到请求调用 HandlerMapping 处理器映射器。
3)处理器映射器找到具体的处理器(可以根据 xml 配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给 DispatcherServlet。
4)DispatcherServlet 调用 HandlerAdapter 处理器适配器。
5)HandlerAdapter 经过适配调用具体的处理器(Controller,也叫后端控制器)。
6)Controller 执行完成返回 ModelAndView
SpringMvc 的控制器是不是单例模式,如果是,有什么问题,怎么解决
是单例模式,所以在多线程访问的时候有线程安全问题。
解决方法:
1)不要再成员位置定义成员变量
2)如果非要定义成员变量,在类上用@Scope("prototype")=========================每次获取Bean的时候会有一个新的实例,当请求数越多,性能会降低,因为每次回创建新的实例。
3)使用ThreadLocal
SpringBoot怎么整合拦截器与过滤器 【拦截器与过滤器的区别】 注意这里不讲解 SpringMVC整合拦截器,只讲SpringBoot整合拦截器与过滤器
SpringBoot整合拦截器:
(1)实现HandlerInterceptor,重写如下方法
preHandle(HttpServletRequest request, HttpServletResponse response, java.lang.Object handler) 方法前执行
post(HttpServletRequest request, HttpServletResponse response, java.lang.Object handler, ModelAndView modelAndView) 方法后执行,视图解析之前
afterCompletion(HttpServletRequest request, HttpServletResponse response, java.lang.Object handler, java.lang.Exception ex) 整个请求完成之后执行
(2)编写拦截器配置类
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {
@Autowired
private LogInterceptor logInterceptor;
//配置拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
//指定拦截器,指定拦截路径
registry.addInterceptor(logInterceptor).addPathPatterns("/**");
}
}
================================
SpringBoot整合过滤器:
https://blog.csdn.net/m0_37989911/article/details/99241066
********************************
过滤器与拦截器的区别:
①拦截器是基于java的反射机制的,而过滤器是基于函数回调。
②拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
③拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
④拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
⑤在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
⑥拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。
SpringBoot自动装配原理与一些相关面试题
https://www.cnblogs.com/itlihao/p/14973077.html