ps做电商网站流程,有没有免费做物流推荐的网站,哈尔滨网站公司哪家好,传扬互动网站建设公司文章目录 1.spring事务传播机制2.spring事务失效原因3.Bean的生命周期4.Bean作用域5.依赖注入三种方式#xff08;Ioc的三种实现方式#xff09;6.实例化bean的三种方式7.IOC容器初始化加载Bean流程 1.spring事务传播机制
声明式事务虽然优于编程式事务#xff0c;但也有不… 文章目录 1.spring事务传播机制2.spring事务失效原因3.Bean的生命周期4.Bean作用域5.依赖注入三种方式Ioc的三种实现方式6.实例化bean的三种方式7.IOC容器初始化加载Bean流程 1.spring事务传播机制
声明式事务虽然优于编程式事务但也有不足声明式事务管理的粒度是方法级别而编程式事务是可以精确到代码块级别的。
要想实现事务管理和业务代码的抽离就必须得用到 Spring 当中的AOP其本质是对方法前后进行拦截然后在目标方法开始之前创建或者加入一个事务执行完目标方法之后根据执行的情况提交或者回滚。
①.声明式 在配置文件中设置以下6项
(1) required 如果客户端没有事务 在bean中新起一个事务 如果客户端有事务bean 中就加进去
子事务主事务结果异常正常并try-catch异常均回滚正常异常均回滚正常异常并try-catch异常不回滚
(2)requiresNew 不管客户端有没有事务服务器段都新起一个事务 如果客户端有事务就将事务挂起
子事务主事务结果异常正常并try-catch异常子回滚主不回滚正常异常子不回滚主回滚异常正常均回滚
(3)supports 如果客户端没有事务服务端也没有事务 如果客户端有事务服务端就加一个事务
(4)mandatcry 如果客户端没有事务服务端就会报错 如果客户端有事务服务端就加事务
(5)notSupported 不管客户端有没有事务服务端都没有事务 如果客户端有事务服务端就挂起
(6)never 不管客户端有没有事务服务端都没有事务 如果客户端有事务就报错
(7)NESTED 如果当前存在事务则在嵌套事务内执行。 如果当前没有事务则进行与REQUIRED类似的操作
子事务主事务结果异常正常并try-catch异常子回滚主不回滚正常异常均回滚异常正常均回滚
②.编程式事务 Javax.transaction.UserTranscation JTA 事务可以精确到事务的开始和结束
2.spring事务失效原因
①.service没有托管给spring 失效原因 spring事务生效的前提是service必须是一个bean对象 解决方案 将service注入spring
②抛出受检异常 失效原因 spring默认只会回滚非检查异常和error异常 解决方案 配置rollbackFor
③业务自己捕获了异常try-catch 失效原因 spring事务只有捕捉到了业务抛出去的异常才能进行后续的处理如果业务自己捕获了异常则事务无法感知。 解决方案 (1)将异常原样抛出 (2)设置TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
④切面顺序导致 失效原因 spring事务切面的优先级顺序最低但如果自定义的切面优先级和他一样且自定义的切面没有正确处理异常则会同业务自己捕获异常的那种场景一样 解决方案 (1)在切面中将异常原样抛出 (2)在切面中设置TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
⑤非Public方法 失效原因 spring事务默认生效的方法权限都必须为public 解决方案 (1)将方法改为public (2)修改TansactionAttributeSource,将publicMethodsOnly改为false
⑥父子容器 失效原因 子容器扫描范围过大将未加事务配置的serivce扫描进来 解决方案 (1)父子容器个扫个的范围 (2)不用父子容器所有bean都交给同一容器管理
⑦方法用final/static修饰 失效原因 因为spring事务是用动态代理实现因此如果方法使用了final修饰则代理类无法对目标方法进行重写植入事务功能 解决方案 方法不要用final修饰
⑧调用本类方法 失效原因 本类方法不经过代理无法进行增强 解决方案 (1)注入自己来调用 (2)使用EnableAspectJAutoProxy(exposeProxy true) AopContext.currentProxy()
⑨多线程调用 失效原因 因为spring的事务是通过数据库连接来实现而数据库连接spring是放在threadLocal里面。同一个事务只能用同一个数据库连接。而多线程场景下拿到的数据库连接是不一样的即是属于不同事务
⑩错误的传播行为 失效原因 使用的传播特性不支持事务
⑪使用了不支持事务的存储引擎 失效原因 使用了不支持事务的存储引擎。比如mysql中的MyISAM
⑫数据源没有配置事务管理器 注 因为springboot他默认已经开启事务管理器。
⑬被代理的类过早实例化 失效原因 当代理类的实例化早于AbstractAutoProxyCreator后置处理器就无法被AbstractAutoProxyCreator后置处理器增强
3.Bean的生命周期
①默认情况下IOC容器中bean的生命周期分为五个阶段: (1)调用构造器 或者是通过工厂的方式创建Bean对象 (2)给bean对象的属性注入值 (3)调用初始化方法进行初始化 初始化方法是通过init-method来指定的 (4)使用 (5)IOC容器关闭时 销毁Bean对象
②当加入了Bean的后置处理器后IOC容器中bean的生命周期分为七个阶段: 调用构造器 或者是通过工厂的方式创建Bean对象 (1)给bean对象的属性注入值 (2)执行Bean后置处理器中的 postProcessBeforeInitialization (3)调用初始化方法进行初始化 初始化方法是通过init-method来指定的 (4)执行Bean的后置处理器中 postProcessAfterInitialization (5)使用 (6)IOC容器关闭时 销毁Bean对象
4.Bean作用域
名称作用域singleton单例对象默认值的作用域prototype每次获取都会创建⼀个新的 bean 实例request每⼀次HTTP请求都会产⽣⼀个新的bean该bean仅在当前HTTP request内有效。session在一次 HTTP session 中容器将返回同一个实例global-session将对象存入到web项目集群的session域中,若不存在集群,则global session相当于session
默认作用域是singleton多个线程访问同一个bean时会存在线程不安全问题
5.依赖注入三种方式Ioc的三种实现方式
①构造方法注入 ②setter注入 ③基于注解的注入
6.实例化bean的三种方式
①无参构造方法实例化Spring默认常用需要bean类中存在无参构造方法 ②静态工厂实例化 ③实例化工厂实例化
7.IOC容器初始化加载Bean流程
Override
public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) {// 第一步:刷新前的预处理 prepareRefresh();//第二步: 获取BeanFactory并注册到 BeanDefitionRegistryConfigurableListableBeanFactory beanFactory obtainFreshBeanFactory();// 第三步:加载BeanFactory的预准备工作(BeanFactory进行一些设置比如context的类加载器等)prepareBeanFactory(beanFactory);try {// 第四步:完成BeanFactory准备工作后的前置处理工作 postProcessBeanFactory(beanFactory);// 第五步:实例化BeanFactoryPostProcessor接口的Bean invokeBeanFactoryPostProcessors(beanFactory);// 第六步:注册BeanPostProcessor后置处理器在创建bean的后执行 registerBeanPostProcessors(beanFactory);// 第七步:初始化MessageSource组件(做国际化功能;消息绑定消息解析); initMessageSource();// 第八步:注册初始化事件派发器 initApplicationEventMulticaster();// 第九步:子类重写这个方法在容器刷新的时候可以自定义逻辑 onRefresh();// 第十步:注册应用的监听器。就是注册实现了ApplicationListener接口的监听器registerListeners();//第十一步:初始化所有剩下的非懒加载的单例bean 初始化创建非懒加载方式的单例Bean实例(未设置属性)finishBeanFactoryInitialization(beanFactory);//第十二步: 完成context的刷新。主要是调用LifecycleProcessor的onRefresh()方法完成创建finishRefresh();}……
} 四个阶段 ①实例化 Instantiation ②属性赋值 Populate ③初始化 Initialization ④销毁 Destruction
多个扩展点 ①影响多个Bean BeanPostProcessor InstantiationAwareBeanPostProcessor ②影响单个Bean Aware
完整流程
①实例化一个Bean也就是我们常说的new ②按照Spring上下文对实例化的Bean进行配置也就是IOC注入 ③如果这个Bean已经实现了BeanNameAware接口会调用它实现的setBeanName(String)方法也就是根据就是Spring配置文件中Bean的id和name进行传递 ④如果这个Bean已经实现了BeanFactoryAware接口会调用它实现setBeanFactory(BeanFactory)也就是Spring配置文件配置的Spring工厂自身进行传递 ⑤如果这个Bean已经实现了ApplicationContextAware接口会调用setApplicationContext(ApplicationContext)方法和4传递的信息一样但是因为ApplicationContext是BeanFactory的子接口所以更加灵活 ⑥如果这个Bean关联了BeanPostProcessor接口将会调用postProcessBeforeInitialization()方法BeanPostProcessor经常被用作是Bean内容的更改由于这个是在Bean初始化结束时调用那个的方法也可以被应用于内存或缓存技术 ⑦如果Bean在Spring配置文件中配置了init-method属性会自动调用其配置的初始化方法。 ⑧如果这个Bean关联了BeanPostProcessor接口将会调用postProcessAfterInitialization()打印日志或者三级缓存技术里面的bean升级 ⑨以上工作完成以后就可以应用这个Bean了那这个Bean是一个Singleton的所以一般情况下我们调用同一个id的Bean会是在内容地址相同的实例当然在Spring配置文件中也可以配置非Singleton这里我们不做赘述。 ⑩当Bean不再需要时会经过清理阶段如果Bean实现了DisposableBean这个接口或者根据spring配置的destroy-method属性调用实现的destroy()方法