1.Spring的两大核心理解
Spring的两大核心是IOC(控制反转)和AOP(面向切面编程)。
IOC控制反转:其实就是将管理对象的权利移交给了Spring,以前需要对象的创建主动去哪和时机是自己把控的,现在是将这个权利转移到了Spring容器,由Spring容器根据配置文件去创建实例和管理各个实例之间的依赖关系,对象之间的松散耦合,也利于重复利用功能。直白点就是说,IOC让对象的创建不用去NEW了,可以由Spring根据我们提供的配置文件自动生产,我们需要对象的时候直接从容器里面获取就可以了。
Spring配置文件里面配置了类的字节码位置和信息,容器生成的时候会去加载配置文件识别字节码信息,通过反射创建类的对象。
IOC的注入方式:setter方式、构造器、注解方式
AOP面向切面编程:其实就是把那些将业务无关,但是却对多个对象产生影响的公共行为和逻辑抽取封装成一个可重用的模块,这个模块其实就是切面。比如:日志管理等。SpringAOP使用的是动态代理,动态代理就是说AOP框架不会修改字节码,而是在每次运行时候在内存里面临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。
2.Spring支持bean的几种作用域
(1)singleton:默认是单例bean,一个容器里面只有一个bean
(2)propotype:每实例化一个对象就会创建一个bean
(3)request:一个request请求创建一个bean,在请求结束后垃圾回收容器会将其进行回收
(4)session:和request类似,一个会话共享一个bean,在会话或session关闭后bean将会被回收
(5)global-session:全局作用域,所有的会话共享一个实例。如果想要声明一个让所有会话共享的存储变量,就可以让改全局变量存储在global-session中。
3.BeanFactory和ApplicationContext的区别
beanFactory是Spring的最高接口,它实现了Spring容器的一些基本功能,调用起来非常麻烦,一般是面向Spring自身使用的。在项目启动时候,bean不会立马实例化,只有在调用的时候才会被实例化。
applicationContext是beanFactory的子接口,扩展了一些功能。它在项目一启动后,就会去加载bean然后放入Spring容器里面,待使用时候再获取。
4.Spring框架用到的设计模式
(1)工厂模式:里面的beanFactory使用的就是简单的工厂模式,用于bean的生产。
(2)单例模式:bean默认是单例,一个容器里面只有一个bean。
(3)代理模式:Spring里面的AOP就是通过JDK动态代理和CGLIB字节码技术实现。
(4)观察者方法:定义对象键一种一对多的依赖关系。如果一个对象的属性发生变化,其他依赖的对象都可以得到通知并被制动更新。Spring里面的Listener就是,ApplicationListener。
(5)模板方式:实现代码的重复使用,如JpaTemplate、RestTemplate。
5.Spring事务的实现方式和原理
Spring事务的本质就是数据库对事务的支持,如果数据库不支持事务,Spring也无法实现事务。数据库实现数据的提交和回滚使用的其实是binlog和relog实现的。
实现方式有:
(1)编程式事务:begintransactionManager()、commit()、rollback()等事务管理方法实现。
(2)声明式事务:通过@Transactional注解的方式实现。
6.Spring的通知类型及执行情况
(1)前置通知类型:在切点运行之前执行。
(2)后置通知类型:在切点正常运行之后执行。
(3)异常通知类型:在切点发生异常的时候执行。
(4)最终通知类型:在切点的最终执行。
(5)环绕通知类型:程序员可以通过编码的方式自己定义通知的设置,用于解决其他通知时序问题。
7.Spring对象默认单例还是多例,单例bean存不存在线程安全问题
Spring对象默认是单例的,但是可以设置为多例。
单例bean对象对应的类可能会存在可变的成员变量,里面存在线程改变成员变量的值时候,多线程会去操作该bean就会出现线程安全问题。出现的原因是:多线程操作如果改变成员变量,其他线程无法访问该bean,造成数据混乱。
可以通过在bean对象中避免设置可变成员变量、定义一个ThreadLocal变量,将里面的可变成员变量都放在该变量里面。
8.@Resource和@Autowired依赖注入的区别
@Resource它是Spring提供的注解,默认按照名称来装配,如果通过名称找不到可以通过匹配的bean则会按照类型来进行装配,如果通过名称也找不到则会报错。但是需要知道,如果执行通过name属性来制定,就只会按照名称的方式来进行装配,找不到就会报错,不会再按照类型类装配。
@Autowried它是java原生提供的,默认按照类型来装配,默认要求依赖对象必须存在,如果为空需要将required设置为false。如果想要实现通过名称来装配,需要和@Qualifier搭配一起使用指定名称。
9.@Qualifier的使用场景
必须和@Autowired一起搭配使用,不能单独使用,两者搭配实现通过名称来装配,其实就实现和@Resource一样的功能。
10.Spring的常用注解
@Component:可以用于各个层,用于对象实例化
@Controller:用于控制层,用于对象实例化
@Serveice:用于业务层,用于对象实例化
@Repository:用于dao层,用于对象实例化
@Value:简单属性的依赖注入
@Resource:实现对象的装配,默认按照名称进行装配,如果没找到可以按照类型去装配
@Autowried:实现对象的装配,默认按照类型进行装配,如果没找到会抛出异常
@Qualifier:和@Autowried搭配一起使用,实现按照名称进行装配
@Bean:标在方法上,告诉方法产生一个bean对象,然后将其交给Spring管理并放入容器里面
@ComponentScan:组件扫描
@Configiration:拥有该注解被认为是配置类,系统一启动,Spring会将里面需要创建的对象进行创建,放进bean容器里面,需要时候再从里面获取
@Transactional:放在方法上,具有事务管理功能
@Import:在配置类里面引入另一个配置类的内容
@PostConstruct、@PreDestory:用于设置Spring对象创建之后和销毁之前需要执行的操作
@PropertySource:用于引入其它的properties配置文件
11.Spring的事务传播行为
事务的传播行为其实说的就是当多个事务同时存在时候Spring怎么处理这些事务。
(1)propagation_requried:如果当前存在事务则加入该事务,如果不存在事务,创建新的事务。
(2)propagation_support:支持当前事务。如果当前存在事务则加入该事务,如果不存在事务则按非事务执行。
(3)propagation_not_support:以非事务执行。如果当前存在事务,则挂起事务以非事务执行。
(4)propagation_never:以非事务执行。如果存在事务,则抛出异常。
(5)propagation_requries_new:创建新事务,不管当前存不存在事务都需要创建新事务。
(6)propagation_mandatory:支持当前事务,如果当前存在事务就加入事务,如果不存在就排除异常。
(7)propagation_nested:如果当前存在事务,在嵌套事务内执行。如果没有事务,则按requried属性执行。
12.Spring中的隔离级别
(1)isolation_default:这个是PlatfromTransactionManager默认的事务隔离别,使用数据库默认隔离级别。
(2)isolation_read_uncommitted:读未提交,允许另一个事务可以看到这个事务未提交的数据。
(3)isolation_read_committed:读已提交,保证一个事务修改的数据只有在提交后才可以被另一个事务读取,而且可以看到该事务对已有记录的更新。解决脏数据的问题。
(4)isolation_repeatable_read:可重复读,保证一个事务修改的数据只有在提交后才可以被另一个事务读取,但是看不到该事务对已有记录的更新。行表。
(5)isolation_serializable:一个事务在执行的过程中完全看不到其他事务对数据库做的更新。标锁。