1、IOC(控制反转)
将对象的创建、管理的控制权交给spring的IOC容器,通过xml或注解的方式把IOC管理的类进行bean的注册。需要类时创建对应的bean即可。
DI:依赖注入,spring会自动将bean依赖的另一个bean进行注入。
2、AOP理解、原理
理解:面向切面编程,将不同类中共同代码提出来,然后通过动态代理的方式将这些公共代码作用到多个对象中。目的:减少系统重复代码、降低模块耦合度。
原理:底层采用动态代理实现,在运行时期动态的为某个类生成代理类以达到增强代码的目的。
动态代理:JDK:要求原始类需要实现至少一个接口。
CGLIB:基于继承进行代理,原生类可以不实现接口。
3、切面相关注解
@Aspect //切面类注解
@Pointcut //定义切点
@Before 前置通知
@AfterReturning 方法正常返回通知
@AfterThrowing 异常通知
@After 后置通知,运行结束
@Around 环绕通知,调用方法前后来分别完成的一些具体任务。
4、注册bean的注解
@Service通常作用在业务层,但是目前该功能与 @Component 相同
@Controller通常作用在控制层,但是目前该功能与 @Component 相同。
@Component是一个泛化的概念,仅仅表示一个组件 (Bean) ,可以作用在任何层次。
@configrution,定义配置类
5、单例、多例的区别
单例:整个系统只有一个,每次请求获取的都是同一个对象,构造方法私有。
多例:防止并发,系统中可以有多个,构造方法私有。
6、Bean被指定为prototype和singleton的区别。
singleton:容器创建对象,每次获取的对象相同。且对象的引用相同。
prototype:每次获取的对象是全新的。
7、BeanFactory和ApplicationContext有什么区别
BeanFactory:Spring最底层接口,提供了最简单的容器的功能,负责生产和管理Bean,启动的时候不会去实例化Bean,需要从容器中获取Bean的时候才去实例化(懒加载)。
ApplicationContext:实现BeanFactory接口,是一种更高级的容器,提供了更多可用的功能:国际化、资源访问、载入多个上下文、消息发送、AOP。启动时就把所有Bean实例化了,也可以通过配置lazy-init=true来实现懒加载。
8、BeanFactory和FactoryBean的区别
BeanFactory:是IOC容器或对象工厂。在spring中所有的bean都是由它来管理。
FactoryBean:能生产和修饰对象的工厂Bean,可以通过实现它来创建实例化过程比较复杂的Bean。
9、Spring框架的组成
Core Container:spring的核心容器,是启动spring的最基本条件。包括spring-core、spring-beans、context、spring-expressionLanguage、DATA ACCESS/Integration(数据访问/集成)、事务处理模块。
Web:由web、web-mvc、web-socket和web-portlet组成。
AOP与Aspects:AOP提供面向切面编程,Aspects是面向切面编程的框架。
Instrumentation:在一定的应用服务器中提供了类Instrumentation的支持和类加载器的实现。
Messaging:为了STOMP提供支持,作为WebSocket子协议的使用。
Test:该模块提供spring的测试内容。
10、Bean的懒加载和非懒加载的区别
懒加载:bean使用的时候才去创建实例。节约资源,但不利于提前发现错误。
非懒加载:容器启动时创建实例。消耗资源,但利于提前发现错误。
默认:非懒加载
11、spring依赖注入方式
setter方式:通过反射调用无参构造生成对象,在通过对应的setter方法注入配置值。
构造器方式:通过反射调用有参构造生成对象。
注解实现方式:@Autowired:默认按类型匹配。@Resource默认按名字匹配。
12、springBoot与spring的关系
SpringBoot基于Spring,简化配置、打包、maven,内嵌tomcat、管理了大量基础依赖。
13、@SpringBootApplication注解的含义
目的开启自动配置,表示当前类是启动类。包含三个子标签。
@SpringBootConfiguration:表示当前类是一个配置类,可以在这个类中通过@Bean注解来自定义Bean、依赖关系等。
@EnableAutoConfiguration:借助@Import注解将所有符合自动配置条件的bean加载到IOC容器。
@ComponentScan:自动扫描注解,可定义扫描包范围,加载到IOC容器中。
14、spring-boot-starter-parent的作用
引入父pom里面的依赖
设置Java版本为、编码格式、资源引用描述
插件管理和资源过滤
15、spring-boot-starter-web的作用
提供web开发所需的地产所有依赖(tomcat、json、spring、springMVC、日志)
16、SpringBoot读取配置文件的方式
@Value:使用在对应变量上面。
@ConfigurationProperties:使用在对应类中。
17、日志级别
trace<debug<info<warn<error
如果设置warn,则低于warn的信息不会输出
默认:info
18、SpringBoot中如何管理事务
首先使用注解@EnableTransactionManagement开启事务支持,在对用方法上注解@Transactional即可。
19、Bean的生命周期
初始化:如果定义了init-method方法,此时会调用
实例化:如果是单例且迫切加载的bean,在spring容器启动时就会根据BeanDefinitoion进行实
例化,如果是懒加载或多例模式的bean,在要用的时候才会实例化
属性赋值:通过beanDefinition找到当前bean所依赖的其他bean,如果容器中有就直接拿过
来,没有就创建依赖的bean,然后通过反射给依赖的字段注入值。
销毁:如果定义了destroy-method方法此时会调用。
20、SpringMVC怎样设定重定向和转发。
控制器方法返回字符串类型的值会被当成逻辑视图名处理。如果返回的字符串中带有forward或redirect前缀时,SpringMVC会对他们进行特殊处理。forward和redirect当成指示符,其后的字符串作为URL来处理。
21、SpringMVC如何对时间格式的参数进行格式化。
入参:@DateTimeFormat(pattern="yyyy-MM-dd")
出参:@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
22、SpringMVC常用注解那些
controller:负责处理dispatchServlet分发请求。把用户请求的数据经过业务层处理后封装成一个model,然后把model返回给对应的view展示。
RequestMapping:用来处理请求地址映射的注解,可以用于类或方法上。用于类上就是此类所有响应请求的方法的父路径。controller只定义了控制器类,RequestMapping才是真正处理请求的处理器。
Autowired:做bean注入时使用。
PathVariable:将请求URL中的模板变量映射到功能处理方法的参数上,就是取出URL中的变量作为参数。
ResponseBody:用于controller的方法返回的对象。
23、如何定义SpringMVC的拦截器
1、创建拦截器类,实现HandlerInterceptor接口,重写preHandler、postHandler、afterHandler三个方法。一般在前置拦截器(preHandler)中写逻辑,这是在controller前执行。
2、注册拦截器。配置要拦截和不拦截的路径(xml)、mapping拦截、exclude-mapping不拦截
24、SpringMVC的执行原理
1、客户端将一个请求提交到DispatcheServlet
2、DispatcheServlet将请求交给HandlerMapping进行请求映射,匹配该请求的Handler
3、DispatcheServlet在请求HandlerAdapter调用相应的Handler处理请求,并向前端控制器返回一个ModelAndView对象。
4、DispatcheServlet将ModleAndView对象交给ViewResoler视图解析器处理,返回指定的视图(view)
5、DispatcheServlet对view进行渲染。
6、DispatcheServlet将页面响应给用户。
25、SpringMVC的Controller是单例还是多例,有没有并发安全问题,如和解决。
controller默认单例,不要使用非静态的成员变量,否则会发生数据逻辑混乱。
正因为单例所以线程不安全。
解决方案:不要在controller中定义成员变量。
定义非静态成员变量,在类上打注解@Scope(“prototype”)
在controller中使用ThreadLocal变量
26、SpringBoot如何做全局异常处理。
自定义枚举类:枚举包含错误码和错误描述。
自定义异常类:继承RuntimeException,包含字段错误码、错误信息、错误类型。
自定义返回的数据格式类:包含字段响应代码、响应信息、响应体(Object)。
自定义全局异常处理类:自定义一些业务异常。
其他可能报错异常的地方则使用异常处理类处理。
27、IOC的启动流程。
当Spring启动时,IOC容器会加载Spring的配置文件,包括XML配置或者注解,然后解析这些Bean并把相关定义信息封装成BeanDefinition对象,通过Bean注册器BeanDefinitionRegistry注册到IOC容器,也就是一个ConcurrentHashMap中
此时会找出所有的单例且没有配置为多例模式的bean,根据其BeanDefinition进行Bean的实例化,它会判断如果bean中有方法覆盖,就使用JDK反射创建Bean,否则使用CGLIB方式生成代理。然后把实例化好的Bean缓存到一个ConcurrentHashMap中
28、IOC容器是如何保证Bean的单例的
IOC容器会将单例模式的bean放入一个ConcurrentHashMap中,需要这个bean时直接到这个map中获取,如果没有找到才会实例化这个bean。而ConcurrentHashMap本身时线程安全的,也就保证了Bean是单例的
29、Spring如何解决Bean的循环依赖
循环依赖分为三种,构造器注入循环依赖 ,setter方式注入循环依赖,多例模式Bean的循环依赖。而Spring解决了单例bean的setter注入循环依赖
setter循环依赖的解决主要使用了三级缓存
一级缓存,用来缓存已经实例化好的bean
二级缓存,用来缓存正在创建的bean
三级缓存,用来缓存创建bean的实例工厂
假设有两个bean,A依赖B,B依赖A
当创建A实例时,会先将正在创建的A实例,放入二级缓存,同时将A的实例工厂放入三级缓存,然后A属性注入时发现依赖了B,此时B的实例还没有创建,就会去创建B的实例,同样的也会把正在创建的B的实例放入二级缓存,B的实例工厂放入三级缓存。此时发现B依赖了A,就会去三级缓存中,找到A的创建工厂,通过反射的方式调用A的无参构造创建A实例,并注入到B中。此时B就初始化好了,然后将B实例放入一级缓存。最后将B实例注入到A中,A也就创建好了
30、Spring的IOC的容器工厂类
BeanFactory:IOC容器顶层接口,提供了Bean获取的基础方法
DefaultListableBeanFactory:是整个 bean 加载的核心部分,Spring 注册及加载Bean 的默认实现
ApplicationContext:除了实现IOC基本功能外,还扩展了国际化支持,资源访问,事件发布
ClasspathXmlApplicationContext:从classpath中获取XML配置
31、@Autowired自动注入原理
自动注入是通过BeanPostProcessor 后置处理器完成的。容器刷新过程中,向容器注册了后置处理器。在Bean实例化过程中,触发了AutowiredAnnotationBeanPostProcessor的postProcessPropertyValues方法的调用执行,它就会扫描当前类中是否有@Autowired注解,然后通过反射得到自动注入的字段所以来的bean,调用BeanFactory得到依赖的bean实例,最后使用反射进行字段赋值
32、@Transcational注解的实现原理
首先TxNamespaceHandler中注册了AnnotationDrivenBeanDefinitionParser,用来解析事务注解配置
在bean实例化的过程中,解析bean是否有@Transactional注解,从而判断是否需要创建代理然后会判断切点,是否需要对这个bean做增强,并解析方法上的@Transactional,如果找到了就用一个map缓存起来,如果没有找到就到类上面找,或者父类的方法和类上找,如果都没找到,就说明这个类不需要事务增强
当我们调用开启了事务的目标方法时,会通过TransactionInterceptor来拦截请求,并实现事务增强
33、