本文对Spring相关知识点做了归纳整理,包括 Spring 优势、其框架结构、核心思想,并对IoC思想及AOP思想进行手动实现,增强对Spring 核心思想的理解。之后对Spring IoC、AOP 的实现方式和特性进行介绍,并对照源码理解其实现思路。

Spring 优势

  • 方便解耦,简化开发

    「[注:IoC(降低组件耦合性)、DI(降低业务对象替换的复杂性)]」

  • AOP编程的思想

    「[注:通用任务集中管理,使得代码可更好的复用]」

  • 声明式事务的支持

    「[注:@Transaction]」

  • 轻量级框架,代码侵入性低,可自由选择框架部分组件

  • 方便集成各种优秀框架

Spring 核心结构

img

  • Spring核心容器(Core Container):容器是Spring框架最核心的部分,管理Bean的创建(IoC)、配置(DI)和管理(Context),所有的Spring模块都构建于核心容器之上.

  • 面向切面编程(AOP):Spring应用系统中开发切面的基础,代码解耦,增强复用。

  • 数据访问与集成(Data Access):Spring的JDBC和DAO模块封装大量样板代码,使得数据库代码变得简洁,也可避免数据库资源释放失败引发的问题。由JDBC、Transactions(AOP模块支持)、ORM、OXM 和 JMS等模块组成。

  • Web:提供了SpringMVC框架给Web应⽤,还提供了多种构建和其它应⽤交互的远程调⽤⽅ 案。SpringMVC框架在Web层提升了应⽤的松耦合⽔平。

  • Test 为了使得开发者能够很⽅便的进⾏测试,Spring提供了测试模块以致⼒于Spring应⽤的测试。通过该模块,Spring为使⽤Servlet、JNDI等编写单元测试提供了⼀系列的mock对象实现。

核心思想

IoC(Inversion of Control)控制反转

IoC 是一个技术思想,而Spring对其进行了实现

控制反转:对象创建(实例化、管理)的权利交给外部环境(Spring框架、IoC容器)

解决问题:解决对象间的耦合问题

img

IoC 和 DI 的区别

DI(Dependancy Injection)依赖注⼊

IoC和DI描述的是同一件事情(对象实例化及依赖关系维护),只不过角度不一样罢了

IoC:站在对象的角度,对象实例化及其管理交给容器

DI:站在容器角度,容器会把对象依赖的其他对象注入

AOP(Aspect oriented Programming)面向切面编程

OOP与AOP

OOP是一种垂直继承体系(三大特征:封装、继承和多态)

「AOP为解决纵向重复问题,抽取横向逻辑代码,分离业务逻辑和横切逻辑,解耦合」

AOP解决问题

「解决纵向重复问题,抽取横向逻辑代码,分离业务逻辑和横切逻辑,解耦合」

IoC和AOP的手动实现

IoC与DI实现

  1. 定义beans.xml,其中定义:

    • 需要创建的对象的id和全限定类名 ⇒ 反射创建对象,id为标识

    • 属性名及依赖对象id ⇒ 通过对应类中的 Set方法 注入依赖属性

  2. 定义BeanFactory,读取解析xml,通过反射实例化对象,统一管理,并提供外部获取对象的接口方法

AOP 事务管理

  1. 将 Connection 与当前线程绑定,手动控制 JDBC 的 Connection 事务(关闭自动提交事务)

  2. 创建代理工厂类,对代理类进行事务增强

  3. 使用代理类对象替代对象进行方法的调用

Spring IoC 应用

IoC 实现方式及其对应启动方法

  1. 纯 xml 实现(bean 信息定义全部配置在 xml 中)

    // JavaSE 应用启动
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
    // 或者读取绝对路径下的配置文件(不推荐)
    ApplicationContext applicationContext = new FileSystemXmlApplicationContext("c:/beans.xml");// JavaWeb 应用
    /**配置 ContextLoaderListener 类(web.xml)监听器机制加载 xml
    */
    
    <!DOCTYPE web-app PUBLIC
    "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" >
    <web-app><display-name>Archetype Created Web Application</display-name><!--配置Spring ioc容器的配置⽂件--><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContext.xml</param-value></context-param><!--使⽤监听器启动Spring的IOC容器--><listener><listenerclass>org.springframework.web.context.ContextLoaderListener</listenerclass></listener>
    </web-app>
    
  2. xml + 注解(部分 bean 使用 xml 定义,部分 bean 使用注解定义)

    和纯 xml 实现一致

  3. 纯注解 (所有 bean 都是用注解来定义)

    // JavaSE 应用启动
    ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Spring.class);// JavaWeb 应用
    /**配置 ContextLoaderListener 类(web.xml)监听器机制加载 注解配置类
    */
    
    <!DOCTYPE web-app PUBLIC
    "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" >
    <web-app><display-name>Archetype Created Web Application</display-name><!--告诉ContextloaderListener知道我们使⽤注解的⽅式启动ioc容器--><context-param><param-name>contextClass</param-name><paramvalue>org.springframework.web.context.support.AnnotationConfigWebAppli cationContext</param-value></context-param><!--配置启动类的全限定类名--><context-param><param-name>contextConfigLocation</param-name><param-value>com.lagou.edu.SpringConfig</param-value></context-param><!--使⽤监听器启动Spring的IOC容器--><listener><listenerclass>org.springframework.web.context.ContextLoaderListener</listenerclass></listener>
    </web-app>
    

BeanFactory 与  ApplicationContext  区别

BeanFactory是Spring框架中IoC容器的顶层接⼝,它只是⽤来定义⼀些基础功能,定义⼀些基础规范,⽽ApplicationContext是它的⼀个⼦接⼝,所以ApplicationContext是具备BeanFactory提供的全部功能的。

ApplicationContext是容器的⾼级接⼝,⽐ BeanFactory要拥有更多的功能,⽐如说国际化⽀持和资源访问(xml,java配置类)等等

实例化Bean的三种方式

  1. 使用无参构造器

    <!--配置service对象-->
    <bean id="userService" class="com.lagou.service.impl.TransferServiceImpl">
    </bean>
    
  2. 使用静态方法创建

    <!--使⽤静态⽅法创建对象的配置⽅式-->
    <bean id="userService" class="com.lagou.factory.BeanFactory" factory-method="getTransferService"></bean>
  3. 使用实例化方法创建

    <!--使⽤实例⽅法创建对象的配置⽅式-->
    <bean id="beanFactory" class="com.lagou.factory.instancemethod.BeanFactory"></bean>
    <bean id="transferService" factory-bean="beanFactory" factory-method="getTransferService"></bean>
    

Bean 的作用范围及生命周期

  • singleton(单例模式)

    单例模式的 bean 对象生命周期与容器相同

  • prototype(多例模式)

    多例模式的 bean 对象,Spring 框架只负责创建,不负责销毁

Xml 模式下 Bean 标签的属性

  • id:bean 的唯一标识

  • class:创建 Bean 对象的全限定类名

  • name:给 bean 提供一个或多个名称

  • factory-bean:指定创建当前 bean 对象的工厂bean 的唯一标识(当指定此属性,class 属性失效)

  • factory-method:指定创建当前对象的工厂方法

    • 「注:若配合 factory-bean 使用,class 属性失效,若配合 class 属性使用,方法必须是 static 修饰的」

  • scope:bean 作用域,默认 singleton

  • init-method:指定 bean 对象初始化方法,在 bean 装配后调用,必须是无参方法。

  • destory-method:指定 bean 对象销毁方法,在 bean 销毁前执行,只在 scope 为 singleton 时起作用(因为多例模式下Spring框架只负责创建)

DI 依赖注入的 xml 配置

  • 依赖注入分类

    • name:对应参数名

    • index:对应构造函数中指定索引

    • value:指定基本类型或 String 类型数据

    • ref:指定其他 Bean 类型的数据,值为 bean 的 id

    • 「注:当没有无参构造时,必须提供与构造参数个数及数据类型匹配的配置参数」

    • 使用标签 为构造函数赋值,其属性如下:

    • name:注入时调用的 set 方法名去掉 set 后的词缀

    • value:指定基本类型或 String 类型数据

    • ref:指定其他 Bean 类型的数据,值为 bean 的 id

    • 使用标签对应 set 方法,标签属性如下:

    • 按注入的方式分类

    • 按注入的数据类型分类

    1. 「基本类型、String」

    2. 「复杂类型 [Array,List,Set,Map,Properties]」

      示例( 以set方法注入为例,构造函数注入同样 ):

      <!-- Array -->
      <property name="myArray"><array><value>array1</value><value>array2</value></array>
      </property><!-- List -->
      <property name="myArray"><list><value>list1</value><value>list2</value></list>
      </property><!-- Set -->
      <property name="mySet"><set><value>set1</value><value>set2</value></set>
      </property><!-- Map -->
      <property name="myMap"><map><entry key="key1" value="value1"/><entry key="key2" value="value2"/></map>
      </property><!-- Properties -->
      <property name="myProperties"><map><prop key="key1" value="value1"/><prop key="key2" value="value2"/></map>
      </property>
      

      在List结构的集合数据注⼊时,array , list , set这三个标签通⽤,另外注值的value标签内部 可以直接写值,也可以使⽤bean标签配置⼀个对象,或者⽤ref标签引⽤⼀个已经配合的bean 的唯⼀标识。在Map结构的集合数据注⼊时,map标签使⽤entry⼦标签实现数据注⼊,entry标签可以使 ⽤key和value属性指定存⼊map中的数据。使⽤value-ref属性指定已经配置好的bean的引⽤。同时entry标签中也可以使⽤ref标签,但是不能使⽤bean标签。⽽property标签中不能使 ⽤ref或者bean标签引⽤对象

    3. 「其他 Bean 类型」

    1. 构造函数注入

    2. set 方法注入

注解与 xml 标签对应关系

xml 与注解相结合模式下,通常第三方jar 中的bean 定义在 xml 中,自己开发的 bean 定义使用注解

  1. 配置方面

    • @Configuration 注解,对应 beans.xml 文件

    • @ComponentScan 注解,替代 context:component-scan

    • @PropertySource,引⼊外部属性配置⽂件

    • @Import 引⼊其他配置类

    • @Value 对变量赋值,可以直接赋值,也可以使⽤ ${} 读取资源配置⽂件中的信息

    • @Bean 将⽅法返回对象加⼊ SpringIoC 容器

  2. IoC

    xml形式对应的注解形式
    标签@Component("accountDao"),注解加在类上 bean的id属性内容直接配置在注解后⾯如果不配置,默认定义个这个bean的id为类 的类名⾸字⺟⼩写;另外,针对分层代码开发提供了@Componenet的三种别名@Controller、 @Service、@Repository分别⽤于控制层类、服务层类、dao层类的bean定义,这 四个注解的⽤法完全⼀样,只是为了更清晰的区分⽽已
    scope属性@Scope("prototype"),默认单例,注解加在类上
    标签的 init-method 属性@PostConstruct,注解加在⽅法上,该⽅法就是初始化后调⽤的⽅法
    destory-method 属性@PreDestory,注解加在⽅法上,该⽅法就是销毁前调⽤的⽅法
  3. DI

    • J2EE 提供,@Resource 在 Jdk 11中已经移除,使用需导入包 javax.annotation.Resource

    • 注入规则:

    • 如果同时指定了 name 和 type,则从Spring上下⽂中找到唯⼀匹配的bean进⾏装配,找不到则抛出异常。

    • 如果指定了 name,则从上下⽂中查找名称(id)匹配的bean进⾏装配,找不到则抛出异常。

    • 如果指定了 type,则从上下⽂中找到类似匹配的唯⼀bean进⾏装配,找不到或是找到多个, 都会抛出异常。

    • 如果既没有指定name,⼜没有指定type,则⾃动按照byName⽅式进⾏装配;

    • 「按类型注入,如果有多个 bean 值,需配合 @Qualifier(name="") 使用」

    • @Autowired

    • @Resource

Spring IoC 常用特性

lazy-Init 延迟加载

  • 关闭延迟加载(默认状态) :ApplicationContext 容器的默认⾏为是在启动服务器时将所有 singleton bean 提前进⾏实例化

  • 开启延迟加载:bean 将不会在 ApplicationContext 启动时提前被实例化,⽽是第⼀次向容器通过 getBean 索取 bean 时实例化的。

    1. 在设置 lazy-init="true",控制单个 bean

    2. 在设置 default-lazy-init="true" ,控制该容器下所有 bean

作用:

  1. 开启延迟加载⼀定程度提⾼容器启动和运转性能

  2. 对于不常使⽤的 Bean 设置延迟加载,这样偶尔使⽤的时候再加载,不必要从⼀开始该 Bean 就占⽤资源

FactoryBean 和 BeanFactory

  • BeanFactory接口:容器顶级接口,定义容器的一些基础行为

  • FactoryBean接口:借助他自定义Bean,作用类似于 Bean 创建方式的静态方法和实例化方法

    「使用方法」

    1. 创建 Bean 对应的 Factory 类,实现 FactoryBean 接口,重写 getObject() 、getObjectType() 和 isSingleton()

    2. 在 xml 中配置该 Factory 类

    3. 容器初始化过程中 会自动实例化 Factory 对象并调用其 getObject() 并管理

      「注:如果需要 Factory 对象,可获取容器中的 &${id} 对象」

      <bean id="testBean" class="com.test.TestBeanFactory"></bean><!--getBean("testBean") 获取的是 TestBean 对象getBean("&testBean") 获取的是 TestBeanFactory 对象
      -->
      

后置处理器

Spring 提供两种后置处理 bean 的扩展接口

  • 「BeanPostProcessor:Bean 对象实例化且装配后调用」

    该接口提供两个方法:

    1. postProcessBeforeInitialization:Bean 初始化方法前

    2. postProcessAfterInitialization:Bean 初始化方法后

  • 「BeanFactoryPostProcessor:BeanFactory 初始化后(bean 还未实例化,此时 bean 刚被解析成 BeanDefinition对象)调用」

    此接口提供了⼀个⽅法,⽅法参数为ConfigurableListableBeanFactory,该参数类型定义了⼀些⽅法其中有个⽅法名为getBeanDefinition的⽅法,我们可以根据此⽅法,找到我们定义bean 的 BeanDefinition对象。然后我们可以对定义的属性进⾏修改。

    **BeanDefinition对象:**我们在 XML 中定义的 bean标签,Spring 解析 bean 标签成为⼀个 JavaBean, 这个JavaBean 就是 BeanDefinition

Spring IoC 源码剖析

Spring IoC 容器继承体系

![](img/Spring IoC容器继承体系.jpg)

Bean 生命周期关键时机点

「Bean对象创建的⼏个关键时机点代码层级的调⽤都在 AbstractApplicationContext 类 的 refresh ⽅法中」

关键点触发代码
构造器refresh#finishBeanFactoryInitialization(beanFactory)(beanFactory)
BeanFactoryPostProcessor 初始化refresh#invokeBeanFactoryPostProcessors(beanFactory)
BeanFactoryPostProcessor ⽅法调⽤refresh#invokeBeanFactoryPostProcessors(beanFactory)
BeanPostProcessor 初始化registerBeanPostProcessors(beanFactory)
BeanPostProcessor ⽅法调⽤refresh#finishBeanFactoryInitialization(beanFactory)

源码如下:

public void refresh() throws BeansException, IllegalStateException {// 对象锁加锁synchronized (this.startupShutdownMonitor) {/*Prepare this context for refreshing.刷新前的预处理表示在真正做refresh操作之前需要准备做的事情:设置Spring容器的启动时间,开启活跃状态,撤销关闭状态验证环境信息里一些必须存在的属性等*/prepareRefresh();/*Tell the subclass to refresh the internal bean factory.获取BeanFactory;默认实现是DefaultListableBeanFactory加载BeanDefition 并注册到 BeanDefitionRegistry*/ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();/*Prepare the bean factory for use in this context.BeanFactory的预准备工作(BeanFactory进行一些设置,比如context的类加载器等)*/prepareBeanFactory(beanFactory);try {/*Allows post-processing of the bean factory in context subclasses.BeanFactory准备工作完成后进行的后置处理工作*/postProcessBeanFactory(beanFactory);/*Invoke factory processors registered as beans in the context.实例化实现了BeanFactoryPostProcessor接口的Bean,并调用接口方法*/invokeBeanFactoryPostProcessors(beanFactory);/*Register bean processors that intercept bean creation.注册BeanPostProcessor(Bean的后置处理器),在创建bean的前后等执行*/registerBeanPostProcessors(beanFactory);/*Initialize message source for this context.初始化MessageSource组件(做国际化功能;消息绑定,消息解析);*/initMessageSource();/*Initialize event multicaster for this context.初始化事件派发器*/initApplicationEventMulticaster();/*Initialize other special beans in specific context subclasses.子类重写这个方法,在容器刷新的时候可以自定义逻辑;如创建Tomcat,Jetty等WEB服务器*/onRefresh();/*Check for listener beans and register them.注册应用的监听器。就是注册实现了ApplicationListener接口的监听器bean*/registerListeners();/*Instantiate all remaining (non-lazy-init) singletons.初始化所有剩下的非懒加载的单例bean初始化创建非懒加载方式的单例Bean实例(未设置属性)填充属性初始化方法调用(比如调用afterPropertiesSet方法、init-method方法)调用BeanPostProcessor(后置处理器)对实例bean进行后置处理*/finishBeanFactoryInitialization(beanFactory);/*Last step: publish corresponding event.完成context的刷新。主要是调用LifecycleProcessor的onRefresh()方法,并且发布事件(ContextRefreshedEvent)*/finishRefresh();}catch (BeansException ex) {if (logger.isWarnEnabled()) {logger.warn("Exception encountered during context initialization - " +"cancelling refresh attempt: " + ex);}// Destroy already created singletons to avoid dangling resources.destroyBeans();// Reset 'active' flag.cancelRefresh(ex);// Propagate exception to caller.throw ex;}finally {// Reset common introspection caches in Spring's core, since we// might not ever need metadata for singleton beans anymore...resetCommonCaches();}}

BeanFactory 创建流程

获取 BeanFactory 子流程

img

BeanDefinition加载解析及注册⼦流程

  1. Resource 定位:把 XML 文件封装成 Resource 对象的过程

  2. BeanDefinition 载入:把⽤户定义好的Javabean表示为IoC容器内部的数据结构,这个容器内部的数 据结构就是BeanDefinition。

  3. 注册BeanDefinition到 IoC 容器

img

Bean 创建流程

「注:参考IoC 循环依赖时序图」

lazy-inti 延迟加载机制原理

public void preInstantiateSingletons() throws BeansException {if (logger.isTraceEnabled()) {logger.trace("Pre-instantiating singletons in " + this);}// Iterate over a copy to allow for init methods which in turn register new bean definitions.// While this may not be part of the regular factory bootstrap, it does otherwise work fine.// 所有bean的名字List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);// Trigger initialization of all non-lazy singleton beans...// 触发所有非延迟加载单例bean的初始化,主要步骤为getBeanfor (String beanName : beanNames) {// 合并父BeanDefinition对象// map.get(beanName)RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {if (isFactoryBean(beanName)) {Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);// 如果是FactoryBean则加&if (bean instanceof FactoryBean) {final FactoryBean<?> factory = (FactoryBean<?>) bean;boolean isEagerInit;if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)((SmartFactoryBean<?>) factory)::isEagerInit, getAccessControlContext());}else {isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factory).isEagerInit());}if (isEagerInit) {getBean(beanName);}}}else {// 实例化当前beangetBean(beanName);}}}// Trigger post-initialization callback for all applicable beans...for (String beanName : beanNames) {Object singletonInstance = getSingleton(beanName);if (singletonInstance instanceof SmartInitializingSingleton) {final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;if (System.getSecurityManager() != null) {AccessController.doPrivileged((PrivilegedAction<Object>) () -> {smartSingleton.afterSingletonsInstantiated();return null;}, getAccessControlContext());}else {smartSingleton.afterSingletonsInstantiated();}}}
}

如源码:

  • 对于被修饰为lazy-init的bean Spring 容器初始化阶段不会进⾏ init 并且依赖注⼊,当第⼀次 进⾏getBean时候才进⾏初始化并依赖注⼊

  • 对于⾮懒加载的bean,getBean的时候会从缓存⾥头获取,因为容器初始化阶段 Bean 已经 初始化完成并缓存了起来

Spring IoC 循环依赖问题

  • 单例 bean 构造器参数循环依赖(⽆法解决)

  • prototype 原型 bean循环依赖(⽆法解决)

    对于原型bean的初始化过程中不论是通过构造器参数循环依赖还是通过setXxx⽅法产⽣循环依 赖,Spring都 会直接报错处理。

  • 单例bean通过setXxx或者@Autowired进⾏循环依赖

    「Spring 的循环依赖的理论依据基于 Java 的引⽤传递,当获得对象的引⽤时,对象的属性是可以延后设置的,但是构造器必须是在获取引⽤之前」

img

Spring AOP 应用

相关概念

  • joinPoint(连接点):方法开始时、结束时、正常运行完毕时、方法异常时等这些特殊的时机点,连接点时一种候选点

  • pointCut(切入点):指定 AOP 影响的具体方法,描述感兴趣的方法

  • Advice(通知/增强):切⾯类中⽤于提供增强功能的⽅法,也表示通知的类型,其分类有:

    前置通知、后置通知、异常通知、最终通知、环绕通知

    • 横切逻辑

    • 方位点

  • Target(⽬标对象):被代理对象

  • Proxy(代理):代理对象

  • Weaving(织⼊):把增强应⽤到⽬标对象来创建新的代理对象的过程。spring采⽤动态代 理织⼊,⽽AspectJ采⽤编译期织⼊和类装载期织⼊。

  • Aspect(切⾯):增强的代码所关注的方面。[例如:TransactionManage类]

    • Aspect切⾯:切⾯概念是对上述概念的⼀个综合

    • Aspect切⾯= 切⼊点+增强 = 切⼊点(锁定⽅法) + ⽅位点(锁定⽅法中的特殊时机)+ 横切逻辑

Spring中 AOP 的代理选择

  • Spring 实现AOP 思想使用的是动态代理技术

  • 默认情况下

    如果 被代理类 「实现接口」 ⇒ 选择 JDK 动态代理

    否则 ⇒ 选择 CGLIB 动态代理

  • 可通过配置方式设置强制使用 CGLIB 动态代理

Spring AOP 实现

1. XML 模式

  1. 引入依赖

  2. 把 Bean 交给 Spring 管理

  3. 配置 aop:config

    • 配置切面 aop:aspect

    • 在切面中 配置 通知增强,一是方位,二是切点

「需要注意的点:」

  1. 切入点表达式

    指的是遵循特定语法结构的字符串,其 作⽤是⽤于对符合语法格式的连接点进⾏增强。

// 示例
// 全限定⽅法名 访问修饰符 返回值 包名.包名.包名.类名.⽅法名(参数列表)
// 全匹配⽅式:
public void com.lagou.service.impl.TransferServiceImpl.updateAccountByCardNo(com.lagou.pojo.Account) // 访问修饰符可以省略
void com.lagou.service.impl.TransferServiceImpl.updateAccountByCardNo(com.lagou.pojo.Account) 
// 返回值可以使⽤*,表示任意返回值
* com.lagou.service.impl.TransferServiceImpl.updateAccountByCardNo(com.lagou.pojo.Account)
// 包名可以使⽤.表示任意包,但是有⼏级包,必须写⼏个
* ....TransferServiceImpl.updateAccountByCardNo(com.lagou.pojo.Account)
// 包名可以使⽤..表示当前包及其⼦包
* ..TransferServiceImpl.updateAccountByCardNo(com.lagou.pojo.Account)
// 类名和⽅法名,都可以使⽤.表示任意类,任意⽅法
* ...(com.lagou.pojo.Account)
// 参数列表,可以使⽤具体类型 基本类型直接写类型名称 :int
// 引⽤类型必须写全限定类名:java.lang.String
// 参数列表可以使⽤*,表示任意参数类型,但是必须有参数
* *..*.*(*)
// 参数列表可以使⽤..,表示有⽆参数均可。有参数可以是任意类型
* *..*.*(..)
// 全通配⽅式:
* *..*.*(..)
  1. 改变代理方式的配置

    • 使用aop:config 标签配置

      <aop:config proxy-target-class="true">
      
    • 使⽤aop:aspectj-autoproxy标签配置

      <!--此标签是基于XML和注解组合配置AOP时的必备标签,表示Spring开启注解配置AOP 的⽀持-->
      <aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectjautoproxy>
      
  2. 五种通知类型

    1. 前置通知:切入点方法执行前执行

      aop:before

    2. 后置通知:切入点方法正常执行后执行

      aop:after-returning

    3. 异常通知:切⼊点⽅法执⾏产⽣异常之后执⾏

      aop:after-throwing

    4. 最终通知:切⼊点⽅法执⾏完成之后,切⼊点⽅法返回之前执⾏(无论是否异常都会执行,finally)

      aop:after

    5. 环绕通知:较特殊,借助的ProceedingJoinPoint接⼝及其实现类, 实现⼿动触发切⼊点⽅法的调⽤

2. XML + 注解模式

  1. XML 中开启 Spring 对注解 AOP 的⽀持

    <!--开启spring对注解aop的⽀持-->
    <aop:aspectj-autoproxy/>
    
  2. 示例

    /**
    * 模拟记录⽇志
    */
    @Component
    @Aspect
    public class LogUtil {/*** 我们在xml中已经使⽤了通⽤切⼊点表达式,供多个切⾯使⽤,那么在注解中如何使⽤呢?* 第⼀步:编写⼀个⽅法* 第⼆步:在⽅法使⽤@Pointcut注解* 第三步:给注解的value属性提供切⼊点表达式* 细节:* 1.在引⽤切⼊点表达式时,必须是⽅法名+(),例如"pointcut()"。* 2.在当前切⾯中使⽤,可以直接写⽅法名。在其他切⾯中使⽤必须是全限定⽅法名。*/@Pointcut("execution(* com.lagou.service.impl.*.*(..))")public void pointcut(){}@Before("pointcut()")public void beforePrintLog(JoinPoint jp){Object[] args = jp.getArgs();System.out.println("前置通知:beforePrintLog,参数是:"+Arrays.toString(args));}@AfterReturning(value = "pointcut()",returning = "rtValue")public void afterReturningPrintLog(Object rtValue){System.out.println("后置通知:afterReturningPrintLog,返回值是:"+rtValue);}@AfterThrowing(value = "pointcut()",throwing = "e")public void afterThrowingPrintLog(Throwable e){System.out.println("异常通知:afterThrowingPrintLog,异常是:"+e);}@After("pointcut()")public void afterPrintLog(){System.out.println("最终通知:afterPrintLog");}/*** 环绕通知* @param pjp* @return*/@Around("pointcut()")public Object aroundPrintLog(ProceedingJoinPoint pjp){//定义返回值Object rtValue = null;try{//前置通知System.out.println("前置通知");//1.获取参数Object[] args = pjp.getArgs();//2.执⾏切⼊点⽅法rtValue = pjp.proceed(args);//后置通知System.out.println("后置通知");}catch (Throwable t){//异常通知System.out.println("异常通知");t.printStackTrace();}finally {//最终通知System.out.println("最终通知");}return rtValue;}
    }
    

3. 注解模式

  1. 在配置类上加 @EnableAspectJAutoProxy 开启spring对注解AOP的⽀持

Spring 声明式事务的⽀持

**编程式事务:**在业务代码中添加事务控制代码,这样的事务控制机制就叫做编程式事务

**声明式事务:**通过xml或者注解配置的⽅式达到事务控制的⽬的,叫做声明式事务

事务四大特性

  1. **原⼦性(Atomicity):**原⼦性是指事务是⼀个不可分割的⼯作单位,事务中的操作要么都发⽣,要么都不发⽣。

    是从「操作」的角度描述的

  2. 「⼀致性(Consistency):」 事务必须使数据库从⼀个⼀致性状态变换到另外⼀个⼀致性状态。

    「数据」的角度描述

  3. **隔离性(Isolation):**事务的隔离性是多个⽤户并发访问数据库时,数据库为每⼀个⽤户开启的事务, 每个事务不能被其他事务的操作数据所⼲扰,多个并发事务之间要相互隔离。

  4. **持久性(Durability):**持久性是指⼀个事务⼀旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发⽣故障 也不应该对其有任何影响。

事务隔离级别

问题:

  • 脏读:⼀个线程中的事务读到了另外⼀个线程中「未提交」的数据。

  • 不可重复读:⼀个线程中的事务读到了另外⼀个线程中「已经提交」「update」的数据(前后内容不⼀样)

  • 虚读(幻读):⼀个线程中的事务读到了另外⼀个线程中「已经提交」的insert或者delete的数据(前后条数不⼀样)

数据库四种隔离级别:

  • Serializable(串⾏化):可避免脏读、不可重复读、虚读情况的发⽣。(串⾏化) 最⾼

  • Repeatable read(可重复读):可避免脏读、不可重复读情况的发⽣。(幻读有可能发⽣) 第⼆

    该机制下会对要update的⾏进⾏加锁

  • Read committed(读已提交):可避免脏读情况发⽣。不可重复读和幻读⼀定会发⽣。第三

  • Read uncommitted(读未提交):最低级别,以上情况均⽆法保证。(读未提交) 最低

「注意:级别依次升⾼,效率依次降低」

MySQL的默认隔离级别是:REPEATABLE READ

事务传播行为

常用前两条(加粗)

PROPAGATION_REQUIRED如果当前没有事务,就新建⼀个事务,如果已经存在⼀个事务中, 加⼊到这个事务中。这是最常⻅的选择。
「PROPAGATION_SUPPORTS」「⽀持当前事务,如果当前没有事务,就以⾮事务⽅式执⾏。」
PROPAGATION_MANDATORY使⽤当前的事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED以⾮事务⽅式执⾏操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER以⾮事务⽅式执⾏,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED如果当前存在事务,则在嵌套事务内执⾏。如果当前没有事务,则 执⾏与PROPAGATION_REQUIRED类似的操作。

Spring 声明式事务配置

注:与AOP配置类似,配置tx:advice

开启spring对注解事务的⽀持

`或 `@EnableTransactionManagement

Spring AOP 源码剖析

AOP源码分析类⽅法调⽤关系

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean
调⽤
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
调⽤
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization(后置处理器AbstractAutoProxyCreator完成bean代理对象创建)
调⽤
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary
调⽤
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy(在这⼀步把委托对象的aop增强和通⽤拦截进⾏合并,最终给代理对象)
调⽤
org.springframework.aop.framework.DefaultAopProxyFactory#createAopProxy
调⽤
org.springframework.aop.framework.CglibAopProxy#getProxy(java.lang.ClassLoader )

Spring声明式事务控制

@EnableTransactionManagement 注解
1)通过@import引⼊了TransactionManagementConfigurationSelector类它的selectImports⽅法导⼊了另外两个类:AutoProxyRegistrar和ProxyTransactionManagementConfiguration
2)AutoProxyRegistrar类分析⽅法registerBeanDefinitions中,引⼊了其他类,通过AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry)引⼊
InfrastructureAdvisorAutoProxyCreator,它继承了AbstractAutoProxyCreator,是⼀个后置处理器类
3)ProxyTransactionManagementConfiguration 是⼀个添加了@Configuration注解的配置类 (注册bean)注册事务增强器(注⼊属性解析器、事务拦截器)属性解析器:AnnotationTransactionAttributeSource,内部持有了⼀个解析器集合Set<TransactionAnnotationParser> annotationParsers;具体使⽤的是SpringTransactionAnnotationParser解析器,⽤来解析@Transactional的事务属性事务拦截器:TransactionInterceptor实现了MethodInterceptor接⼝,该通⽤拦截会在产⽣代理对象之前和aop增强合并,最终⼀起影响到代理对象TransactionInterceptor的invoke⽅法中invokeWithinTransaction会触发原有业
务逻辑调⽤(增强事务)
查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. 波士顿动力机器狗首次开箱:53万,我买到了啥?

    波士顿动力机器狗首次开箱:53万,我买到了啥?波士顿动力首款零售的机器人 Spot,今年 6 月 16 日起正式向美国企业用户发售了。作为机器人里的明星,发货时间超过六周显然不会浇灭人们的热情。最近,这款售价 7.5 万美元(折合人民币 53 万元)起的 Spot「机器狗」已经有了买…...

    2024/4/16 0:28:07
  2. HEVC学习笔记 第1章 编码结构

    第1章 编码结构 1.1 视频编码标准简介 视频编码标准只是规定了编码码流的语法语义和解码器,只要求视频编码后的码流符合标准的语法结构,解码器就可以根据码流的语法语义进行正常解码。因此,符合某个视频编码标准的编码器是有很大自由度的,只要编码后的码流符合标准的规定即…...

    2024/4/1 3:44:00
  3. [转]6个开源数据科学项目

    作者|PRANAV DAR编译|VK来源|Analytics Vidhya概述利用这段时间,用这些顶级的开源项目来制作你的数据科学简历从Facebook AI的计算机视觉框架到OpenAI的GPT-3模型,我们涵盖了广泛的开源数据科学项目介绍“到目前为止,你完成了多少数据科学项目?”这是面试者在数据科学面试中…...

    2024/4/22 10:46:16
  4. C语言-不同数据类型长度获取问题

    我们能常在用到 sizeof 和 strlen 的时候,通常是计算字符串数组的长度, C语言中有一个可以获取字符串长度的函数strlen并且与sizeof做对比: extern unsigned int strlen(char s); 其中形参只能为字符指针类型,其从给定变量的第一个位置开始扫描,直到遇到‘\0’,计数结束,…...

    2024/4/16 0:28:43
  5. libuv如何实现多线程io模型的服务端程序

    libuv如何实现多线程io模型的服务端程序...

    2024/4/18 14:27:01
  6. Golang 项目配置文件读取之 viper 实践

    Golang 项目配置文件读取之 viper 实践 在我们做一个工程化项目的时候,经常涉及到配置文件的读取,viper 包很好地满足这一需求,而且在 Golang 生态中是流行度最高的。导入方式: import "github.com/spf13/viper"这里分享下我对 viper 包的使用关键实践: 首先,在…...

    2024/4/16 0:28:33
  7. cap定理

    下面的总结参考自阮一峰的bloghttp://www.ruanyifeng.com/blog/2018/07/cap.html1,什么是CAP,Consistency 一致性Availability 可用性Partition tolerance 分区容错 CAP定理:分布式系统不能同时保证,一致性,可用性,分区容错分区容错:大多数分布式系统都分布在多个子网络…...

    2024/4/16 0:28:02
  8. 全新适配UI,专业第四方支付源码,全功能,无限制,可兼容对接任何API接口

    更新时间:20200501 版本号:7.0更新订单回调验证机制 增加订单、金额、商户、回调IP等关键数据核验增加回调参数写入数据库以备查阅废除EditMoney参数更新订单 使用支付模型更新 彻底杜绝非法回调更新时间:20200323 版本号:7.0紧急:修复一处漏洞,可通过订单补发机制非法…...

    2024/4/16 0:29:03
  9. leetcode1524:二维数组的查找,辣鸡大王算法,竟然效果不错

    题目不贴了,leetcode上有 class Solution { public:bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {if(matrix.empty()|| matrix[0].empty())//这句话是抄的,为了针对某种算例{return false;}for(int i=0;i<matrix.size();i++){if(…...

    2024/4/16 0:28:53
  10. 【SpringCloudAlibaba】怎样用Nacos来实现服务注册中心呢

    之前我们是用Eureka来实现服务注册中心的(关于Eureka实现注册中心的博客链接:一步一步进行搭建Eureka,实践中理解Eureka),那么Nacos该怎么实现服务注册中心呢 关于Nacos实现服务注册中心,我们不在需要单独建一个eureka的项目的,只有生产者和消费者一些服务项目就可以了 …...

    2024/4/17 7:44:16
  11. MATLAB 离散傅里叶变换(DFS)、逆离散傅里叶变换(IDFS)、快速傅里叶变换(FFT)的实现

    离散傅里叶变换(DFS)、逆离散傅里叶变换(IDFS)的实现代码如下,其中xn为时序序列clc;clear; xn=[7,6,5,4,3,2]; Xk=dfs(xn,6); x=idfs(Xk,6);subplot(2,2,1);stem(0:5,abs(Xk),filled); axis([0,5,0,1.1*max(abs(Xk))]); title(x[n]经DFT后的幅度);xlabel(频率w);ylabel(幅…...

    2024/4/25 10:20:43
  12. Nginx学习 (二) : Nginx的启动与停止

    目录启动停止重新加载配置文件安装完了Nginx就是启动, 修改配置, 再启动, 再修改配置, 再启动...循环所以启动与停止很重要. 所以就要跟着Begin Guide学习Nginx的启动与停止启动nginx在Begin Guide上, 启动就一句话带过了, 导致我第一次看的时候, 都没有特别注意, 因为我只看那…...

    2024/4/16 0:29:29
  13. LeetCode】63. 不同路径 II(有障碍物时)(动态规划)

    相似题目: 【LeetCode】62. 不同路径(动态规划) 一、题目描述 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。 现在考虑网格中有障碍物。那么…...

    2024/4/22 19:54:58
  14. Leetcode:NO.315 计算右侧小于当前元素的个数 归并排序+树状数组

    题目 给定一个整数数组 nums,按要求返回一个新数组 counts。数组 counts 有该性质: counts[i] 的值是 nums[i] 右侧小于 nums[i] 的元素的数量。 示例:输入: [5,2,6,1] 输出: [2,1,1,0] 解释: 5 的右侧有 2 个更小的元素 (2 和 1). 2 的右侧仅有 1 个更小的元素 (1). 6 的右…...

    2024/4/16 20:32:34
  15. VSCode环境使用的一些问题

    VSCode由于插件众多,支持的语言也非常多,是越来越好用,越来越火。有一款插件叫Code Runner支持VSCode下一键运行各种语言,非常好用,但笔者在使用过程中遇到一些问题,需要修改配置才能正常使用,这里作一个记录: 一、Go语言 Go语言的包管理是以目录界限的,一个目录中只允…...

    2024/4/22 19:43:59
  16. SpringBoot后台CRM项目

    ├─视频 │ Springboot后台项目-01前言概述.rmvb │ SpringBoot后台项目-02技术选型.rmvb │ SpringBoot后台项目-03使用Initializr创建SpringBoot项目.rmvb │ SpringBoot后台项目-04添加数据库连接信息和MyBatis依赖.rmvb │ SpringBoot后台项目-0…...

    2024/4/16 0:28:48
  17. layui的laydate控件的常用属性

    目前使用的layui版,没有单独使用laydate。 官网上的例子是每个属性单独设置的,我稍微整合了一下常用属性。引入了css和js以后//初始化时间 layui.use(laydate, function() {//初始化layuivar laydate = layui.laydate;//执行一个laydate实例laydate.render({elem: .date //指…...

    2024/4/1 3:43:49
  18. 动态规划-----算法考试

    动态规划斐波那契求解整数拆分问题求解 0/1 背包问题最长公共子序列 斐波那契 #include <iostream> #define Max_N 100 /***动态规划* *fibonacci 数列 **/ int memo[Max_N]; //存放斐波那契数 using namespace std; int fib(int n) {//终结条件 n<=2时返回1 if(…...

    2024/4/19 22:10:38
  19. LeNet-5网络训练集采用minst数据集

    LeNet-5网络如下:#导入需要的包 import tensorflow as tf from tensorflow import keras #定义网络模型 batch=32 model=tf.keras.Sequential([keras.layers.Conv2D(6,3),keras.layers.MaxPooling2D(pool_size=2,strides=2),keras.layers.ReLU(),keras.layers.Conv2D(16,3),ke…...

    2024/4/16 0:29:34
  20. Kafka 3:多线程下的生产者

    KafkaProducer 的实现是线程安全的,所以我们可以在多线程的环境下,安全的使用 KafkaProducer 的实例。 1.创建主题concurrent-test ./kafka-topics.sh --zookeeper localhost:2181 --create --topic concurrent-test --replication-factor 1 --partitions 82.添加常量package…...

    2024/4/28 7:08:21

最新文章

  1. 13.异常、IO流、序列化和反序列化

    异常 概念 程序在编译或运行的过程中&#xff0c;可能会发生的问题&#xff0c;称为异常。 作为程序员应该要提前预料这个异常的发生情况&#xff0c;尽早把异常情况排除、捕获。 java中的异常体系 Throwable 是异常体系的最顶层的结构&#xff0c;所有异常子类或错误类都是…...

    2024/4/30 16:46:48
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/3/20 10:50:27
  3. 微信小程序的页面交互2

    一、自定义属性 &#xff08;1&#xff09;定义&#xff1a; 微信小程序中的自定义属性实际上是由data-前缀加上一个自定义属性名组成。 &#xff08;2&#xff09;如何获取自定义属性的值&#xff1f; 用到target或currentTarget对象的dataset属性可以获取数据 &#xff…...

    2024/4/30 7:10:53
  4. 比nestjs更优雅的ts控制反转策略-依赖查找

    一、Cabloy5.0内测预告 Cabloy5.0采用TS对整个全栈框架进行了脱胎换骨般的大重构&#xff0c;并且提供了更加优雅的ts控制反转策略&#xff0c;让我们的业务开发更加快捷顺畅 1. 新旧技术栈对比&#xff1a; 后端前端旧版js、egg2.0、mysqljs、vue2、framework7新版ts、egg3…...

    2024/4/30 3:30:06
  5. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/4/29 23:16:47
  6. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/4/29 6:03:24
  7. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/4/29 2:29:43
  8. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/4/29 14:21:50
  9. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/4/27 17:58:04
  10. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/4/27 14:22:49
  11. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/4/28 1:28:33
  12. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/4/30 9:43:09
  13. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/4/27 17:59:30
  14. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/4/25 18:39:16
  15. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/4/28 1:34:08
  16. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/4/26 19:03:37
  17. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/4/29 20:46:55
  18. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/4/25 18:39:14
  19. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/4/26 23:04:58
  20. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/4/27 23:24:42
  21. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/4/28 5:48:52
  22. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/4/30 9:42:22
  23. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/4/30 9:43:22
  24. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

    2024/4/30 9:42:49
  25. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  26. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  27. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  28. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  29. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  30. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  31. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  32. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  33. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  34. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  35. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  36. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  37. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  38. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  39. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  40. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  41. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  42. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  43. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  44. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57