Spring环境下AOP运行原理

​ 前面文章已经分析了SpringAop原生的运行原理,本节将分析使用频率最高场景: Spring环境下的AOP运行原理。本文会涉及到Spring启动期间注入Bean的流程,默认你已经非常熟悉了,本文不再详细赘述相关流程。

SpingBoot项目中使用AOP一般会做如下操作:

  • 主启动类上添加@EnableAspectJAutoProxy注解开启SpringAop功能
  • 自定义切面并注入到Spring中即可
@SpringBootApplication
@EnableAspectJAutoProxy
public class TestApplication {public static void main(String[] args) {SpringApplication.run(TestApplication.class, args);}
}@Aspect
@Component
public class TestAspect {@Pointcut(value = "execution(* com.ssm.test.aop.ATMService.withdrawMoney())")public void pointcut() {}@Before(value = "pointcut()")public void before() {System.out.println("TestAspect.before.....");}@After(value = "pointcut()")public void after() {System.out.println("TestAspect.after.....");}
}@Service
public class ATMService implements BankService {@Overridepublic void withdrawMoney() {System.out.println("ATMService : 取钱成功");}
}

如上代码所示是一个简单的AOP增强案例,本节就基于这个案例分析Spring环境下AOP的运行原理。

原理分析

@EnableAspectJAutoProxy

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {boolean proxyTargetClass() default false;boolean exposeProxy() default false;
}

首先分析下在主启动类上添加的的@EnableAspectJAutoProxy注解 , 该注解主要是用于配置proxyTargetClass、exposeProxy属性,这个两个属性在之前的文章也分析过了,此处不再赘述。如上图源码所示该注解还有有一个非常关键的作用 : @Import(AspectJAutoProxyRegistrar.class), 了解过Spring原理可以知道这边@Import注解是用来注入AspectJAutoProxyRegistrar这个Bean的.

AspectJAutoProxyRegistrar
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);AnnotationAttributes enableAspectJAutoProxy =AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);if (enableAspectJAutoProxy != null) {if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);}if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);}}}
}

如上图源码所示,AspectJAutoProxyRegistrarBeanDefinitionRegistry作为参数将主要逻辑都委托给了AopConfigUtils这个工具类。BeanDefinitionRegistry接口并不陌生,主要提供注册、删除、获取Bean的功能,所以可以大致判断出AopConfigUtils在这边主要是注入了某个Bean :

AopConfigUtils
public abstract class AopConfigUtils {//The bean name of the internally managed auto-proxy creator.public static final String AUTO_PROXY_CREATOR_BEAN_NAME ="org.springframework.aop.config.internalAutoProxyCreator";public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);}public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, @Nullable Object source) {return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);}private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {Assert.notNull(registry, "BeanDefinitionRegistry must not be null");if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);if (!cls.getName().equals(apcDefinition.getBeanClassName())) {int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());int requiredPriority = findPriorityForClass(cls);if (currentPriority < requiredPriority) {apcDefinition.setBeanClassName(cls.getName());}}return null;}RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);beanDefinition.setSource(source);//将当前要注入的Bean的优先级设置为最高beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);return beanDefinition;}public static void forceAutoProxyCreatorToUseClassProxying(BeanDefinitionRegistry registry) {if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);definition.getPropertyValues().add("proxyTargetClass", Boolean.TRUE);}}public static void forceAutoProxyCreatorToExposeProxy(BeanDefinitionRegistry registry) {if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);definition.getPropertyValues().add("exposeProxy", Boolean.TRUE);}}.....}

结合上图源码可知AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);这行代码实际上是手动向Spring注入了beanNameorg.springframework.aop.config.internalAutoProxyCreator, Bean类型为 : AnnotationAwareAspectJAutoProxyCreator.classBean. 有个细节需要注意:registerOrEscalateApcAsRequired()方法注入Bean时会为该Bean设置order属性,将Bean的优先级调整为最高级别,这样做的目的是可以优先注入该Bean, 但优先注入这个Bean具体有何意义此处先Mark一下。

forceAutoProxyCreatorToUseClassProxying()、forceAutoProxyCreatorToExposeProxy()两个方法实际上是为上面注入的AnnotationAwareAspectJAutoProxyCreator这个Bean设置proxyTargetClass、exposeProxy属性值。虽然@EnableAspectJAutoProxy注解中这两个属性值默认值为false, 但是底层源码却直接将属性值置为了true, 从而可以知道SpringBoot中使用SpringAop默认会使用强制使用CGLIB代理,并且会将当前的代理对象暴露在当前线程中,可以直接使用AopContext获取到当前代理对象。

综上所述可以总结出: 主启动类上添加@EnableAspectJAutoProxy这个注解可以向Spring中注入AnnotationAwareAspectJAutoProxyCreator这个Bean, 具体它是用来干嘛的此处先不表,下面会详细分析它。

AnnotationAwareAspectJAutoProxyCreator

如上图所示是AnnotationAwareAspectJAutoProxyCreatorUML图,由于涉及的比较多所以分析时只会贴出关键代码。上图可以很清楚的看出AnnotationAwareAspectJAutoProxyCreator实现了BeanPostProcessor、InstantiationAwareBeanPostProcessor接口,所以本质上是一个BeanPostProcessor. 对Spring了解的同学应该都知道Spring在启动期间注入Bean时,会使用IOC中的BeanPostProcessor类型的Bean对当前Bean的注入做增强处理(相当于是一个埋点处理), 我们简单贴个代码回顾一下 :

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactoryimplements AutowireCapableBeanFactory {......protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {try {//Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.Object bean = resolveBeforeInstantiation(beanName, mbdToUse);if (bean != null) {return bean;}}catch (Throwable ex) {throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,"BeanPostProcessor before instantiation of bean failed", ex);}try {Object beanInstance = doCreateBean(beanName, mbdToUse, args);if (logger.isTraceEnabled()) {logger.trace("Finished creating instance of bean '" + beanName + "'");}return beanInstance;}catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {throw ex;}catch (Throwable ex) {throw new BeanCreationException("", ex);}}protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {......Object wrappedBean = bean;if (mbd == null || !mbd.isSynthetic()) {//调用BeanPostProcessor接口中的postProcessBeforeInitialization方法wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}try {invokeInitMethods(beanName, wrappedBean, mbd);}catch (Throwable ex) {throw new BeanCreationException("Invocation of init method failed", ex);}if (mbd == null || !mbd.isSynthetic()) {//调用BeanPostProcessor接口中的postProcessAfterInitialization方法wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}return wrappedBean;}protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {Object bean = null;if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {Class<?> targetType = determineTargetType(beanName, mbd);if (targetType != null) {//调用BeanPostProcessor接口InstantiationAwareBeanPostProcessor接口中的postProcessBeforeInstantiation方法bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);if (bean != null) {//调用BeanPostProcessor接口中的postProcessAfterInitialization方法bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);}}}mbd.beforeInstantiationResolved = (bean != null);}return bean;}......
}

如上图所示是Spring遍历注入一个Bean时会调用到AbstractAutowireCapableBeanFactory#createBean()方法,在这个方法中有这样一行代码 : Object bean = resolveBeforeInstantiation(beanName, mbdToUse); 这行代码上有一行非常重要的注释 : 给BeanPostProcessor一个机会返回代理实例而不是目标实例。 仔细观察resolveBeforeInstantiation()方法逻辑可以看到它主要是遍历调用IOC中所有的BeanPostProcessorpostProcessBeforeInstantiation方法(该方法属于InstantiationAwareBeanPostProcessor)和postProcessAfterInitialization方法(该方法属于BeanPostProcessor).

createBean还会委托到AbstractAutowireCapableBeanFactory#initializeBean()方法 :

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {......Object wrappedBean = bean;if (mbd == null || !mbd.isSynthetic()) {wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}try {invokeInitMethods(beanName, wrappedBean, mbd);}catch (Throwable ex) {throw new BeanCreationException((mbd != null ? mbd.getResourceDescription() : null),beanName, "Invocation of init method failed", ex);}if (mbd == null || !mbd.isSynthetic()) {wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}return wrappedBean;}

这个方法会在执行Spring初始化方法afterPropertiesSet前后分别遍历调用IOC中所有BeanPostProcessorpostProcessBeforeInitializationpostProcessAfterInitialization方法。

根据上面AnnotationAwareAspectJAutoProxyCreator UML图可知它实现了BeanPostProccesor和InstantiationAwareBeanPostProcessor接口,所以我们重点关注一下它和BeanPostProcessor有关的接口实现 ,这些逻辑在AnnotationAwareAspectJAutoProxyCreator的父类AbstractAutoProxyCreator中 :

AbstractAutoProxyCreator
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupportimplements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {//保存那些有指定TargetSource的Bean的名称private final Set<String> targetSourcedBeans = Collections.newSetFromMap(new ConcurrentHashMap<>(16));//保存需要被AOP拦截的Bean的名称与它的代理对象Class类型的映射关系private final Map<Object, Class<?>> proxyTypes = new ConcurrentHashMap<>(16);//保存Bean是否需要被AOP拦截,如果需要拦截value为true,否则为falseprivate final Map<Object, Boolean> advisedBeans = new ConcurrentHashMap<>(256);//该方法是InstantiationAwareBeanPostProcessor接口中的//根据上面的分析可知该方法会在Spring注入每个Bean的时候都执行@Overridepublic Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {Object cacheKey = getCacheKey(beanClass, beanName);if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) { //这个if用于判断是否已经处理过当前Beanif (this.advisedBeans.containsKey(cacheKey)) {return null;}//到这个if说明当前的Bean还没被处理过//isInfrastructureClass方法首先会判断当前Bean是否是一个切面//重点是shouldSkip方法,该方法第一次调用是会找到当前IOC中所有的切面,然后遍历切面判断当前的Bean是否可以被切点拦截//以本案例中注入ATMService为例,它不是切面但是需要被AOP拦截,所以这个if为falseif (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {this.advisedBeans.put(cacheKey, Boolean.FALSE);return null;}}//获取当前Bean对应的TargetSource实例,由于案例中没有提供ATMService的TargetSource//所以会这个方法会返回null结束TargetSource targetSource = getCustomTargetSource(beanClass, beanName);//如果有指定TargetSource则会调用createProxy方法,该方法会使用之前分析过的ProxyFacoty生成代理对象并返回if (targetSource != null) {if (StringUtils.hasLength(beanName)) {this.targetSourcedBeans.add(beanName);}Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);this.proxyTypes.put(cacheKey, proxy.getClass());return proxy;}return null;}@Overridepublic boolean postProcessAfterInstantiation(Object bean, String beanName) {return true;}@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) {return bean;}//该方法是实现的`BeanPostProcessor`接口中的//该方法会在Spring注入Bean期间执行afterPropertiesSet方法后执行//这个方法将逻辑委托给了wrapIfNecessary方法@Overridepublic Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {if (bean != null) {Object cacheKey = getCacheKey(bean.getClass(), beanName);if (this.earlyProxyReferences.remove(cacheKey) != bean) {return wrapIfNecessary(bean, beanName, cacheKey);}}return bean;}protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {//如果targetSourcedBeans包含当前的beanName,说明上面的postProcessBeforeInstantiation方法已经处理过这个Bean了,此处就不需要再处理if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {return bean;}//如果当前Bean属于Advisor类型则也不需要处理if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {return bean;}//如果当前Bean是切面或者不需要生成代理对象则直接返回if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {this.advisedBeans.put(cacheKey, Boolean.FALSE);return bean;}//到这一步就说明当前Bean有被切面拦截到所以需要生成当前Bean的代理对象以便实现AOP增强Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);if (specificInterceptors != DO_NOT_PROXY) {this.advisedBeans.put(cacheKey, Boolean.TRUE);Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));this.proxyTypes.put(cacheKey, proxy.getClass());return proxy;}this.advisedBeans.put(cacheKey, Boolean.FALSE);return bean;}//生成当前Bean的代理对象//使用的是之前分析过的ProxyFactory方式生成了代理对象protected Object createProxy(Class<?> beanClass, @Nullable String beanName,@Nullable Object[] specificInterceptors, TargetSource targetSource) {if (this.beanFactory instanceof ConfigurableListableBeanFactory) {AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);}ProxyFactory proxyFactory = new ProxyFactory();proxyFactory.copyFrom(this);if (!proxyFactory.isProxyTargetClass()) {if (shouldProxyTargetClass(beanClass, beanName)) {proxyFactory.setProxyTargetClass(true);}else {evaluateProxyInterfaces(beanClass, proxyFactory);}}Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);proxyFactory.addAdvisors(advisors);proxyFactory.setTargetSource(targetSource);customizeProxyFactory(proxyFactory);proxyFactory.setFrozen(this.freezeProxy);if (advisorsPreFiltered()) {proxyFactory.setPreFiltered(true);}return proxyFactory.getProxy(getProxyClassLoader());}......}

流程总结

SpringBoot集成SpringAop后会注入AnnotationAwareAspectJAutoProxyCreator这个Bean, 它是一个BeanPostProcessor类型. Spring在启动期间遍历注入Bean时会遍历调用IOC中所有BeanPostProcessor类型的postProcessBeforeInitialization、postProcessAfterInitialization方法。 AnnotationAwareAspectJAutoProxyCreator也属于BeanPostProcessor,所以Spring注入每个Bean时也会调用到它的这个两个方法,方法是在它的父类AbstractAutoProxyCreator中实现的。 AbstractAutoProxyCreator中的这两个方法会判断当前Spring正在注入的这个Bean是否需要被IOC中的切面拦截,如果不需要则直接返回不做任何处理,否则会调用它的createProxy方法使用之前文章分析过的ProxyFactory方式生成当前Bean的代理对象并返回,之后的逻辑就和之前文章分析过的代理过程一样了。

查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. centOS 系统目录结构

    目录名称功能与作用描述/bin二进制应用程序目录&#xff0c;其中包含二进制文件 CentOS 系统所有用户使用的命令都在这个目录下。/boot开机启动引导目录&#xff0c;启动 (boot) 配置文件&#xff0c;其中包括了 Linux 内核文件与开机所需要的文件。/dev设备目录&#xff0c;设…...

    2024/4/26 14:29:02
  2. win访问mac下虚拟机中宝塔后台

    mac下安装了CentOS7作为开发测试环境&#xff0c;CentOS里面安装了宝塔&#xff0c; 虚拟机没有使用和mac同网段的ip&#xff0c;虚拟机的网络适配器使用的是与mac共享模式 win系统ip是192.168.1.2 mac系统ip是192.168.1.3 CentOS系统ip是172.16.155.2 mac能访问宝塔后台&…...

    2024/4/19 22:59:08
  3. 质量基础设施一站式服务平台,NQI云服务平台搭建

    质量基础设施一站式服务平台&#xff0c;NQI云服务平台搭建 质量基础设施“一站式”服务是通过有机融合计量、标准、认证认可、检验检测、质量管理等要素资源&#xff0c;面向企业、产业、区域特别是中小企业提供的全链条、全方位、全过程质量基础设施综合服务。是提高供给体系…...

    2024/4/27 14:50:03
  4. UG NX 12 对象的隐丽与顺复显示

    选择【编辑】-【显示和隐藏】菜单命令后&#xff0c;可以从其子菜单中选择不同的选项进行对象的隐藏与显示。 1&#xff0c;根据类型显示和隐藏对象 根据类型显示和隐藏指定的一个或多个对象&#xff0c;用户进行下述操作即可激活该功能。 &#xff08;1&#xff09;工具条…...

    2024/4/27 15:37:01
  5. Pig调优参数详解

    1. pig.maxCombinedSplitSize 和 pig.splitCombination用途:当处理处理大批量的小文件时,默认设置情况下可能会遇到“命名空间超过配额限制”的错误。Pig脚本运行结果可能会产生数量巨大的输出文件(通常在没有reduce时),比如几万甚至几十万个文件输出。Pig提供了能够合并多…...

    2024/4/27 3:23:11
  6. Odoo 字段设置唯一不重复

    一、字段增加唯一约束 前台违反约束效果&#xff1a; 后台模型中定义代码&#xff1a; 括号中三个参数依次是约束定义名、约束定义内容、弹出提醒内容。 在_sql_constraints定义中可以填写多个字段的约束定义&#xff0c;每个用()包裹&#xff0c;之间用逗号分隔开即可。 …...

    2024/4/15 4:03:04
  7. Centos7.4上部署PostgreSQL12和PostGIS3.0及创建geom表验证

    安装PostgreSQL 1.安装rpm a sudo yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm 2.安装PostgreSQL yum list | grep postgresql #查看可安装的列表 sudo yum install -y postgresql12 postgresql1…...

    2024/4/26 13:33:10
  8. 牛奶神马搜索权重批量查询软件【SEO必备工具】

    ...

    2024/4/27 15:59:26
  9. 【Screw】数据库表结构文档工具操作

    【Screw】数据库表结构文档工具操作需求介绍使用方式1. 代码方式1.1 创建spring工程&#xff0c;并且选择SQL依赖的JDBC API1.2 配置application.properties配置1.3 添加依赖1.4 编写测试代码1.5 执行后即可在resource路径下生成相应的HTML2. Maven 插件方式2.1 引入插件2.2 mv…...

    2024/4/26 1:17:46
  10. opencv-滤波

    线性滤波与卷积的基本概念 线性滤波可以说是图像处理最基本的方法&#xff0c;它可以允许我们对图像进行处理&#xff0c;产生很多不同的效果。做法很简单。首先&#xff0c;我们有一个二维的滤波器矩阵&#xff08;有个高大上的名字叫卷积核&#xff09;和一个要处理的二维图…...

    2024/4/20 13:38:02
  11. SpringBoot整合Elasticsearch详细步骤以及代码示例(附源码)

    准备工作 环境准备 JAVA版本 Copy java version "1.8.0_121" Java(TM) SE Runtime Environment (build 1.8.0_121-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode) ES版本 Copy {"name": "pYaFJhZ","cluster_…...

    2024/4/17 18:24:45
  12. 抖智传媒:主播加入公会有什么好处?

    相信很多新手主播都听说过公会&#xff0c;但是很多人可能并不清楚公会到底能为主播做些什么。工会是锚与平台之间的桥梁。平台不可能直接管理如此大量的主播资源。但是&#xff0c;每个主播都有自己的一系列问题&#xff0c;如设备故障、心理问题、规则理解等&#xff0c;无法…...

    2024/4/26 14:32:03
  13. 手把手教你搭建 ELK 实时日志分析平台

    本篇文章主要是手把手教你搭建 ELK 实时日志分析平台&#xff0c;那么&#xff0c;ELK 到底是什么呢&#xff1f; ELK 是三个开源项目的首字母缩写&#xff0c;这三个项目分别是&#xff1a;Elasticsearch、Logstash 和 Kibana。 Elasticsearch 是一个搜索和分析引擎。Logsta…...

    2024/4/27 16:08:44
  14. 国外社媒营销之KOL经验分享(外贸篇)

    1.在平台twitter、facebook、reddit和discord上注册产品推广。通过整合横幅和简短段落&#xff0c;确保通过平台将任何相关新闻和事件发布并传达给我们的目标受众。例如说我们公司是做B2B中国贸易线上展会的&#xff0c;我们公司有自己的搜索引擎网站matchup expo,那么我们就会…...

    2024/4/26 18:46:11
  15. 智慧屏有什么用

    对于电视机来讲&#xff0c;智慧屏的作用就是一对N结构&#xff0c;也就是说电视并不单纯的是电视&#xff0c;可以智能覆盖家庭、办公、运动以及出行等生活场景&#xff0c;进而打通物理世界与数字世界的边界&#xff0c;带来真正的无缝体验。 电视使用技巧&#xff1a;在日常…...

    2024/4/15 4:03:30
  16. 高压扭转(HPT)

    大塑性变形(Severe plastic deformation&#xff0c;SPD)因其强大的晶粒细化能力&#xff0c;可使多晶体材料的内部组织细化至亚微米级甚至纳米级的超细晶材料&#xff0c;表现出优异的力学性能和使用性能&#xff0c;因而引起研究者的广范兴趣。 SPD 指的是一种加工金属材料的…...

    2024/4/15 22:53:57
  17. 导轨式串口服务器将ModbusTCP网口设备连接云端

    1.概述 我司在ModbusRTU转JSON的应用上满足了很多客户串口设备上云的需求&#xff0c;但是Modbus协议并不是只存在于串口设备&#xff0c;很多ModbusTCP网口只是走TCP/IP传输&#xff0c;也就是ModbusTCP协议。而大多数ModbusTCP网口设备是不给第三方云后台提供接口的&#xff…...

    2024/4/20 18:29:01
  18. 五分钟看一次股票被老板叼,连夜写个Python股票价格CLI。

    前言 今天兴高采烈的去上班&#xff0c;因为我买的股票大赚&#xff0c;所以美滋滋&#xff01;当天上班就肯定没啥状态嘛&#xff0c;心思都在股票上&#xff01;随便涨几个点就是一个月的工资&#xff0c;那肯定还是香一些的&#xff0c;所以今天格外关注股票价格信息&#x…...

    2024/4/25 20:45:13
  19. JVM配置参数续

    目录 1、jps&#xff1a;显示所有java进程pid 2、jinfo&#xff1a;实时查看和调整虚拟机参数 3、jstat:监控虚拟机各种运行状态信息 4、option: 5、jmap:生成堆转储快照 6、jhat&#xff1a;Java堆分析工具 7、jstack:堆栈跟踪工具 8、线程状态 9、JDK可视化工具 jc…...

    2024/4/24 5:35:57
  20. Quartz简单应用(Springboot环境)

    需求&#xff1a; 在项目中免不了会使用定时任务来执行一些自动化的操作。简单的定时任务可以在方法上加上Schedule的注解来执行定时任务。但是如果有多个同级的模块在不同的时间点执行同一个方法&#xff0c;就没办法仅仅使用Schedule来执行了。 侃场景&#xff1a; 现在某一个…...

    2024/4/25 8:35:29

最新文章

  1. Blender点操作

    顶点操作即一般的“布线”操作 1.顶点移动 -先切到顶点模式 -移动&#xff0c;G 或 G X/Y/Z -旋转&#xff0c;R 同上 -缩放&#xff0c;S 同上 2.顶点滑移&#xff0c;用于微调顶点的位置 快捷键&#xff1a;Shift V&#xff0c;G G 3.顶点删除 -选中一个顶点 -按…...

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

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

    2024/3/20 10:50:27
  3. 如何转行成为产品经理?

    转行NPDP也是很合适的一条发展路径&#xff0c;之后从事新产品开发相关工作~ 一、什么是NPDP&#xff1f; NPDP 是产品经理国际资格认证&#xff0c;美国产品开发与管理协会&#xff08;PDMA&#xff09;发起的&#xff0c;是目前国际公认的唯一的新产品开发专业认证&#xff…...

    2024/4/22 16:14:13
  4. 深入浅出 -- 系统架构之微服务中Nacos的部署

    前面我们提到过&#xff0c;在微服务架构中&#xff0c;Nacos注册中心属于核心组件&#xff0c;通常我们会采用高性能独立服务器进行部署&#xff0c;下面我们一起来看看Nacos部署过程&#xff1a; 1、环境准备 因为Nacos是支持windows和Linux系统的&#xff0c;且服务器操作…...

    2024/4/23 6:26:15
  5. 【外汇早评】美通胀数据走低,美元调整

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

    2024/4/26 18:09:39
  6. 【原油贵金属周评】原油多头拥挤,价格调整

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

    2024/4/26 20:12:18
  7. 【外汇周评】靓丽非农不及疲软通胀影响

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

    2024/4/26 23:05:52
  8. 【原油贵金属早评】库存继续增加,油价收跌

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

    2024/4/27 4:00:35
  9. 【外汇早评】日本央行会议纪要不改日元强势

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

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

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

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

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

    2024/4/26 21:56:58
  12. 【原油贵金属早评】波动率飙升,市场情绪动荡

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

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

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

    2024/4/26 16:00:35
  14. 【原油贵金属早评】市场情绪继续恶化,黄金上破

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

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

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

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

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

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

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

    2024/4/26 22:01:59
  18. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

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

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

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

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

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

    2024/4/25 2:10:52
  21. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

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

    2024/4/25 18:39:00
  22. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

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

    2024/4/26 19:46:12
  23. 广州械字号面膜生产厂家OEM/ODM4项须知!

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

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

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

    2024/4/27 8:32:30
  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