一.Spring aop的原理
Spring aop就是基于动态代理的,如果要代理的对象实现了某个接口,那么Spring aop会使用jdk proxy,去创建代理对象,而对于没有实现接口的对象,就无法使用jdk的动态代理,这时Spring aop会使用cglib动态代理,这时候Spring aop会使用cglib生成一个被代理对象的子类作为代理。
二.Spring中的bean都有哪些作用域:
-
singleton:唯一Bean实例,Spring中的Bean默认都是单例的。
-
prototype:每次请求都会创建一个新的bean实例。
-
request:每次HTTP请求都会产生一个新的Bean,该Bean仅在当前HTTP request内有效。
-
session:每次HTTP请产生一个新的Bean,该Bean仅在当前HTTP session内有效。
-
global-session:全局session作用域,仅仅在基于portlet的web应用中才有意义,Spring5已经没有了。
三.Spring中的单例Bean的线程安全问题:
- 在Bean中尽量避免定义可变的成员变量(不太现实)。
- 在类中定义一个ThreadLocal成员变量,将需要的可变成员变量保存在Threadlocal中。
四.Spring中的Bean的生命周期
-
Bean容器找到配置文件中Spring Bean的定义。
-
Bean容器利用Java反射机制创建一个Bean的实例。
-
如果涉及一些属性值,利用set()方法设置一些属性值。
-
如果Bean实现了BeanNameAware接口,调用setBeanName()方法,传入Bean的名称。
-
如果Bean实现了BeanClassLoaderAware接口,调用setBeanClassLoader()方法,传入ClassLoader对象的实例。
-
如果Bean实现了BeanFactoryAware接口,调用setBeanClassLoader()方法,传入ClassLoader对象的实例。
-
与上面类似,如果实现了其他*.Aware接口,就调用相应的方法。
-
如果有和加载这个Bean的Spring容器相关的BeaPostProcessor对象,执行postProcessBeforeInitialization()方法
-
如果Bean实现了InitializingBean接口,执行afterPropertiesSet()方法
-
如果Bean在配置文件中的定义包含init-method属性,执行指定的方法。
-
如果有和加载这个 Bean的 Spring 容器相关的 BeanPostProcessor 对象,执行postProcessAfterInitialization() 方法
-
当要销毁Bean的时候,如果 Bean 实现了 DisposableBean 接口,执行 destroy() 方法。
-
当要销毁 Bean 的时候,如果 Bean 在配置文件中的定义包含 destroy-method 属性,执行指定的方法。
五[email protected]和@Bean有什么区别 -
作用对象不同:@Component作用于类,@Bean作用于方法。
-
@Component通常是通过类路径扫描来自动侦测以及自动装配到Spring容器中(使用@ComponentScan注解定义要扫描的路径从中找出识别了需要装配的类自动装配到spring的Bean容器中)。
@Bean注解通常是在标有该注解的方法中定义产生这个bean,@Bean告诉Spring这是某个类的实例,当我需要用它的时候还给我。 -
@Bean注解比@Component注解的自定义性更强,而且很多地方只能通过@Bean注解来注册Bean,比如第三方库中的类。
六.Spring框架中用到哪些设计模式?
- 工厂设计模式:Spring使用工厂模式通过BeanFactory、ApplicationContext创建Bean对象。
- 代理设计模式:Spring AOP功能的实现。
- 单例设计模式:Spring中的Bean默认都是单例的。
- 模板方法模式:Spring中jdbcTemplate、hibernateTemplate等以Template结尾的对数据库操作的类,就是用到了模板模式。
- 包装器设计模式:我们的项目需要链接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库。
这种模式让我们可以根据客户需求都太切换不同的数据源。 - 观察者模式:Spring事件驱动模型就是观察者模式很经典的一个应用。
- 适配器模式:Spring AOP的增强或通知使用到了适配器模式。
七.Spring的事务有哪几种隔离级别
TransactionDefinition接口中定义了五个隔离级别的常量:
-
ISOLATION_DEFAULT:
使用后端数据库默认的隔离级别(一般用这个就好了),MySQL默认采用的是REPEATABLE_READ隔离级别,Oracle默认采用的是READ_COMMITTED隔离级别。 -
ISOLATION_READ_UNCOMMITTED:
最低的隔离级别,允许读取尚未提交的数据,可能导致脏读、幻读或不可重复读。 -
ISOLATION_READ_COMMITTED:
允许读取并发事务以及提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。 -
ISOLATION_REPEATABLE_READ:
对同一字段的多次读取结果都是一致的,除非数据是被事务自己修改的,可以阻止脏读和不可重复读,但幻读仍有可能发生。 -
ISOLATION_SERIALIZABLE:
最高的隔离级别,所有事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读和幻读。
但是这将严重影响程序性能,通常也不会用到。
八.Spring事务有哪几种事务传播行为
在TransactionDefinition中定义了7种事务传播行为:
-
PROPAGATION_REQUIRED:
如果当前存在事务,则加入该事务;
如果当前没有事务,则创建一个新的事务。 -
PROPAGATION_SUPPORTS:
如果当前存在事务,则加入该事务;
如果当前没有事务,则以非事务的方式继续运行。 -
PROPAGATION_MANDATORY:
如果当前存在事务,则加入该事务;
如果当前没有事务,则抛出异常(mandatory:强制) 不支持当前事务的情况 -
PROPAGATION_REQUIRES_NEW:
创建一个新的事务,如果当前存在事务,则把当前事务挂起。 -
PROPAGATION_NOT_SUPPORTED:
以非事务的方式运行,如果当前存在事务,则把当前事务挂起。 -
PROPAGATION_NEVER:
以非事务的方式运行,如果当前存在事务,则抛出异常。 -
PROPAGATION_NESTED:
如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;
如果当前没有事务,则该取值等价于PROPAGATION_REQUIRED。