Spring中的事务是怎么实现的?
- Spring事务底层是基于数据库事务和AOP机制的。
- 首先对于使用了@Transactional注解的Bean,Spring会创建一个代理对象作为Bean。
- 当调用了代理对象的方法时,会判断该方法是否增加了@Transactional注解。
- 如果加了,那么就利用事务管理器来创建一个数据库连接。
- 并且设置数据库连接的autoCommit为false,禁止此连接的自动提交,这是实现Spring事务非常重要的一步。
- 然后执行当前的方法,方法中会执行对应的sql。
- 执行完当前的方法后,没有异常就提交事务。
- 如果出现了异常,且异常需要进行数据库回滚操作那么就进行数据库回滚,否则仍然提交事务。
- Spring事务的隔离级别对应的是数据库的隔离级别。
- Spring事务的传播机制是Spring事务自己实现的。
- Spring事务的传播机制是基于数据库连接来做的,一个数据库连接一个事务,如果传播机制配置为需要新开一个事务,那么实际上就是先新建立一个数据库连接,在此数据库连接上执行sql。
Spring中什么时候@Transactional注解会失效?
因为Spring事务上基于代理实现的,所以加了@Transactional的方法只有被代理对象调用时,注解才会生效,否则就不会生效。
同时,如果某个方法是private修饰的,那么它的@Transactional也不会生效,因为底层cglib是基于父子类实现的,子类不能重载父类的private方法,所以无法很好的利用代理,也会导致@Transactional失效。
Spring容器启动流程是怎样的?
- 在创建Spring容器,也就是启动Spring容器时,首先会进行扫描,扫描所有的BeanDefition对象,并存在一个Map中。
- 然后筛选出非懒加载的BeanDefition进行创建Bean,对于多例Bean不需要启动过程中去创建,而在每次获取Bean时利用BeanDefition进行创建。
- 利用BeanDefition来创建Bean,这期间包括了合并BeanDefition、推断构造方法、实例化、属性填充、初始化前、初始化、初始化后等步骤,其中AOP就是发生在初始化后等操作。
- 单例Bean初始化完之后,Spring会发布一个容器启动事件。
- Spring启动结束。
- Spring启动过程中还会处理@import等注解。
Spring用到了哪些设计模式?
- 工厂模式(BeanFactory、FactoryBean、ProxyFactory)
- 原型模式(原型Bean、PrototypeTargetSource、PrototypeAspectInstanceFactory)
- 单例模式(单例Bean、SingletonTargetSource、DefaultBeanNameGenerator、SimpleAutowireCandidateResolver、AnnotationAwareOrderComparator)
- 构建器模式(BeanDefinitionBuilder——BeanDefinition构造器、BeanFactoryAspectAdvisorsBuilder——解析井构造@AspecU注解的Bean中所定义的Advisor、StringBuilder)
- 适配器模式(ApplicationListenerMethodAdapter——将@EventListener注解的方法适配成ApplicationListener、AdvisorAdapter——把Advisor适配成Methodinterceptor)
- 访问者模式(PropertyAccessor——属性访问器,用来访问和设置某个对象的某个属性、MessageSourceAccessor——国际化资源访问器)
- 装饰器模式(BeanWrapper——比单纯的Bean对象功能更加强大、HttpRequestWrapper)
- 代理模式(方式生成了代理对象的地方就用到了代理模式、AOP、@Configuration、@Lazy)
- 观察者模式(ApplicationListener——事件监听机制、AdvisedSupportListener——ProxyFactory可以提交此监听器,用来监听ProxyFactory创建代理对象完成事件、添加Advisor事件等)
- 策略模式(InstantiationStrategy——Spring需要根据BeanDefinition来实例化Bean,但是具体可以选择不同的策略来进行实例化、BeanNameGenerator——beanName生成器)
- 模板方法模式(AbstractApplicationContext——postProcessBeanFactory()、AbstractApplicationContext——onRefresh()——子类可以做一些额外的初始化)
- 责任链模式(DefaultAdvisorChainFactory——负责构造一条AdvisorChain,代理对象执行某个方法时会依次经过AdvisorChain中的每个Advisor、QualifierAnnotationAutowireCandidateResolver——判断某个Bean能不能用来进行依赖注入——勉强可以认为也是责任链)
Spring中常用注解以及底层实现
- @SpringBootApplication注解:这个注解标识了这是一个SpringBoot工程,其实它时由3个注解组成的。
a. @SpringBootConfiguartion:这个注解实际上就是一个@Configuartion,表示启动类也是配置类。
b. @EnableConfiguartion:向Spring容器中导入了一个Selector,用来加载
ClassPath下SpringFactories中所定义的自动配置类,将这些自动加载为配置Bean。
c. @ComponentScan:标识扫描路径,因为默认没有配置扫描路径,所以SpringBoot扫描路径是启动类所在的当前目录。 - @Bean注解:用来定义Bean,类似于XML文件中的标签,Spring启动前会对加了Bean注解的方法进行解析,将方法的名字作为beanName,并通过执行方法得到bean对象。
- @Controller、@Service、@ResponseBody、@Autowired
SpringBoot是如何启动Tomcat的?
- 首先,SpringBoot启动时会先创建一个Spring对象。
- 在创建Spring容器过程中,会利用@ConditionalOnClass技术来判断当前classpath中是否存在Tomcat依赖,如果存在则会生成一个启动Tomcat的
Bean。 - Spring容器创建完之后,就会获取启动Tomcat的Bean,并创建Tomcat对象,并绑定端口等,然后启动Tomcat。