@ComponentScan注解原理

  • ComponentScan源码解析
    • 理解@Component
      • 1. 利用`@Repository`自定义一个注解
      • 2. 写一个测试类`NameRepository`,加上该注解
      • 3. 测试`NameRepository`类是否能被Spring容器加载
    • 探索源码
      • 1. 先看`@ComponentScan`源码

ComponentScan源码解析

下文源码分析版本Spring 5.2.5 release

理解@Component

@Component作为一种由Spring容器托管的通用组件,任何被@Component标注的组件均为组件扫描的对象。
类似的组件比如@Repository@Service或者使用@Component注解作为自定义注释。

//@see org.springframework.context.annotation.ClassPathBeanDefinitionScanner
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component {/*** The value may indicate a suggestion for a logical component name,* to be turned into a Spring bean in case of an autodetected component.* @return the suggested component name, if any (or empty String otherwise)*/String value() default "";}

1. 利用@Repository自定义一个注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
//@Component
@Repository
public @interface StringRepository {String value() default "";
}

2. 写一个测试类NameRepository,加上该注解

@StringRepository("chineseNameRepository")
public class NameRepository {public List<String> findAll() {return Arrays.asList("张三", "李四", "王二麻子");}
}

3. 测试NameRepository类是否能被Spring容器加载

创建一个测试类ComponentBootStrap,代码如下

@Configuration
@ComponentScan
public class ComponentBootStrap {public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ComponentBootStrap.class);
//        context.register(ComponentBootStrap.class);
//        context.refresh();NameRepository nameRepository = context.getBean(NameRepository.class);System.out.println("nameRepository.findAll() = " + nameRepository.findAll());}
}

小提示:类NameRepository与引导类ComponentBootStrap需放到一个包下,才能被@ComponentScan扫描加载。
输出结果为:nameRepository.findAll() = [张三, 李四, 王二麻子],这说明了自定义注解类@StringRepository也有类似于@Component的功能。
结论:只要你注解中包含了@Component,就能被Spring容器托管。因为@Component是元注解,也可以联合元注解去创造组合注解,比如@RestController就是由@Controller@ResponseBody组成的。
官网beans-meta-annotations

上面例子来源于小马哥的《Spring Boot编程思想》,NameRepository注解不是继承@ComponentScan,但是效果却是继承,借用小马哥对这种模式注解的定义为@ComponentScan的派生性。那下文就探索一下@ComponentScan派生性的原理。

探索源码

只要注解里面含有@Component,就会被Spring扫描,并注册。为什么会这么呢?是不是跟扫描方式有关系呢?
Spring扫描bean的方式有两种,一种是自定义标签<context:component-scan base-package=“com.xxx”/>这里base-package值填写NameRepository的包名,一种是注解@ComponentScan,如果不填写value值,就默认扫描注解类的包下所有类。

第一种自定义标签的方式这里暂时不讨论,以后会专门写一篇来解析。
我们这里重点讲解注解@ComponentScan方式。

1. 先看@ComponentScan源码

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {@AliasFor("basePackages")String[] value() default {};@AliasFor("value")String[] basePackages() default {};Class<?>[] basePackageClasses() default {};Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;String resourcePattern() default ClassPathScanningCandidateComponentProvider.DEFAULT_RESOURCE_PATTERN;// 这里默认为true,说明使用默认的过滤器,下文会详细说这里boolean useDefaultFilters() default true;Filter[] includeFilters() default {};Filter[] excludeFilters() default {};boolean lazyInit() default false;@Retention(RetentionPolicy.RUNTIME)@Target({})@interface Filter {FilterType type() default FilterType.ANNOTATION;@AliasFor("classes")Class<?>[] value() default {};@AliasFor("value")Class<?>[] classes() default {};String[] pattern() default {};}
}

该注解里面有很多属性,我这里就不介绍,有兴趣的自行查阅资料。里面有个注解@AliasFor("value")经常出现,要是有读者有兴趣,我下次就单独写篇文章来介绍这个。说偏题了,来继续探索,Spring是在哪里进行扫描的呢?看到这里很多人都会比较困惑,我的方法一般是先利用idea的find usages,快捷键也就是CTRL+G,来搜索那个地方调用了该注解,如下


然后在usage in .class里面去寻找有关系的,这里,我们在org.springframework.context.annotation.ConfigurationClassParser#doProcessConfigurationClass该方法里面找到了解析@ComponentScan的地方。但是猛的一看这个类,好家伙,里面不仅仅只解析我们谈论的@ComponentScan,还解析@Import,@Bean,@PropertySources,@ComponentScans,@ImportResource等,下次将一次性来讲解这个类。

来就重点来看核心代码ConfigurationClassParser#doProcessConfigurationClass

protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter){···// Process any @ComponentScan annotations// 获取ComponentScans,ComponentScan注解里面所有的属性Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);if (!componentScans.isEmpty() &&!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {for (AnnotationAttributes componentScan : componentScans) {// The config class is annotated with @ComponentScan -> perform the scan immediately// 核心代码parse:下面重点解析Set<BeanDefinitionHolder> scannedBeanDefinitions =this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());// Check the set of scanned definitions for any further config classes and parse recursively if neededfor (BeanDefinitionHolder holder : scannedBeanDefinitions) {BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();if (bdCand == null) {bdCand = holder.getBeanDefinition();}if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {parse(bdCand.getBeanClassName(), holder.getBeanName());}}}}···

ComponentScanAnnotationParser#parse(AnnotationAttributes,String)

	public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {// 这里new一个scanner对象,因为@ComponentScan注解里面的useDefaultFilters默认为true,所以这里传入的值为true// 也就是在构造器中使用了默认的过滤器,下文会介绍ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :BeanUtils.instantiateClass(generatorClass));ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy");if (scopedProxyMode != ScopedProxyMode.DEFAULT) {scanner.setScopedProxyMode(scopedProxyMode);}else {Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver");scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));}scanner.setResourcePattern(componentScan.getString("resourcePattern"));for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) {for (TypeFilter typeFilter : typeFiltersFor(filter)) {scanner.addIncludeFilter(typeFilter);}}for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) {for (TypeFilter typeFilter : typeFiltersFor(filter)) {scanner.addExcludeFilter(typeFilter);}}boolean lazyInit = componentScan.getBoolean("lazyInit");if (lazyInit) {scanner.getBeanDefinitionDefaults().setLazyInit(true);}Set<String> basePackages = new LinkedHashSet<>();String[] basePackagesArray = componentScan.getStringArray("basePackages");for (String pkg : basePackagesArray) {String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg),ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);Collections.addAll(basePackages, tokenized);}for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) {basePackages.add(ClassUtils.getPackageName(clazz));}if (basePackages.isEmpty()) {basePackages.add(ClassUtils.getPackageName(declaringClass));}scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {@Overrideprotected boolean matchClassName(String className) {return declaringClass.equals(className);}});// 上面都是将注解里面的属性赋值给scanner,然后解析方法委托给ClassPathBeanDefinitionScanner#doScanreturn scanner.doScan(StringUtils.toStringArray(basePackages));}

org.springframework.context.annotation.ClassPathBeanDefinitionScanner#doScan

protected Set<BeanDefinitionHolder> doScan(String... basePackages) {Assert.notEmpty(basePackages, "At least one base package must be specified");Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();// 这里的basePackages就是之前的@ScanComponent所在的包名for (String basePackage : basePackages) {// 找到候选组件Set<BeanDefinition> candidates = findCandidateComponents(basePackage);for (BeanDefinition candidate : candidates) {ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);candidate.setScope(scopeMetadata.getScopeName());String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);if (candidate instanceof AbstractBeanDefinition) {postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);}if (candidate instanceof AnnotatedBeanDefinition) {AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);}if (checkCandidate(beanName, candidate)) {BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);definitionHolder =AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);beanDefinitions.add(definitionHolder);// 将候选组件注册为BeanDefinitionregisterBeanDefinition(definitionHolder, this.registry);}}}return beanDefinitions;
}

扫描候选组件的类路径
ClassPathScanningCandidateComponentProvider#findCandidateComponents(String)

public Set<BeanDefinition> findCandidateComponents(String basePackage) {if (this.componentsIndex != null && indexSupportsIncludeFilters()) {return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);}else {return scanCandidateComponents(basePackage);}
}private Set<BeanDefinition> scanCandidateComponents(String basePackage) {Set<BeanDefinition> candidates = new LinkedHashSet<>();try {// String CLASSPATH_ALL_URL_PREFIX = "classpath*:";// 假如这里的basePackage是com.example.learnspring,resolveBasePackage(basePackage)就把包名变成com/example/learnspring// resolveBasePackage(basePackage)的目的是将包名里面的"."换成"/",String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +resolveBasePackage(basePackage) + '/' + "**/*.class";// 根据传入的路径解析成ResourceResource[] resources = getResourcePatternResolver().getResources(packageSearchPath);···省去日志if (resource.isReadable()) {try {// 产生一个访问元数据的门面类MetadataReaderMetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);// 判断是否为候选组件if (isCandidateComponent(metadataReader)) {ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);sbd.setResource(resource);sbd.setSource(resource);if (isCandidateComponent(sbd)) {candidates.add(sbd);}else {if (debugEnabled) {logger.debug("Ignored because not a concrete top-level class: " + resource);}}}}}catch (Throwable ex) {···}return candidates;
}

这里先介绍一下MetadataReader,这是一个通过ASM访问类元数据的门面类,在这里的实现类是SimpleMetadataReader,元数据就是SimpleAnnotationMetadataReadingVisitor通过ASM产生的。

final class SimpleMetadataReader implements MetadataReader {private static final int PARSING_OPTIONS = ClassReader.SKIP_DEBUG| ClassReader.SKIP_CODE | ClassReader.SKIP_FRAMES;private final Resource resource;// 数据元信息,包括className,superClassName等等,// 如果还是不清楚,看下面类StringRepository数据元信息图private final AnnotationMetadata annotationMetadata;SimpleMetadataReader(Resource resource, @Nullable ClassLoader classLoader) throws IOException {// 通过SimpleAnnotationMetadataReadingVisitor来创建AnnotationMetadata,原理是ASM,对这里有兴趣的同学可以在这里打个断点,尽情调试SimpleAnnotationMetadataReadingVisitor visitor = new SimpleAnnotationMetadataReadingVisitor(classLoader);getClassReader(resource).accept(visitor, PARSING_OPTIONS);this.resource = resource;this.annotationMetadata = visitor.getMetadata();}

数据元信息
再来判断是否是候选组件

protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {for (TypeFilter tf : this.excludeFilters) {if (tf.match(metadataReader, getMetadataReaderFactory())) {return false;}}for (TypeFilter tf : this.includeFilters) {if (tf.match(metadataReader, getMetadataReaderFactory())) {return isConditionMatch(metadataReader);}}return false;
}

我们的类StringRepository之前已经成功被Spring加载了,所有在这里肯定是返回true的,因此在这里打个断点进行调试。
excludeFilters: 排除含有注解的元信息
includeFilters:匹配含有注解的元信息
这里发现includeFilters里面包含了两个AnnotationTypeFilter,分别包含ComponentManagedBean,这是因为在registerDefaultFilters方法里面注册了默认的过滤器。

protected void registerDefaultFilters() {this.includeFilters.add(new AnnotationTypeFilter(Component.class));ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();try {this.includeFilters.add(new AnnotationTypeFilter(((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");}catch (ClassNotFoundException ex) {// JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.}try {this.includeFilters.add(new AnnotationTypeFilter(((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");}catch (ClassNotFoundException ex) {// JSR-330 API not available - simply skip.}
}

搜索一下哪里调用了registerDefaultFilters,发现ClassPathBeanDefinitionScanner#ClassPathBeanDefinitionScanner()

	public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,Environment environment, @Nullable ResourceLoader resourceLoader) {Assert.notNull(registry, "BeanDefinitionRegistry must not be null");this.registry = registry;if (useDefaultFilters) {// 设置默认的过滤器registerDefaultFilters();}setEnvironment(environment);setResourceLoader(resourceLoader);}

最后发现在ClassPathBeanDefinitionScanner构造器中设置了默认的过滤器,也就是在ComponentScanAnnotationParser#parse方法的第一行,创建ClassPathBeanDefinitionScanner对象,与上文形成呼应。

public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);

绕来绕去,你可能有些晕了,让我们在整理一下,刚才介绍到判断是候选组件,也就是下面的match()方法返回true。从方法名猜测只要类中包含注解@Component或者@ManageBean就会匹配成功。下面继续深入源码分析。

	protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {for (TypeFilter tf : this.excludeFilters) {if (tf.match(metadataReader, getMetadataReaderFactory())) {return false;}}for (TypeFilter tf : this.includeFilters) {// 核心判断逻辑if (tf.match(metadataReader, getMetadataReaderFactory())) {// 判断元信息是否包含@Conditional,跟条件相关的,这里省略return isConditionMatch(metadataReader);}}return false;}

AbstractTypeHierarchyTraversingFilter#match(MetadataReader,MetadataReaderFactory)

	public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)throws IOException {// 主要讲解这个方法,下面的逻辑有兴趣的同学可以自己研究if (matchSelf(metadataReader)) {return true;}······return false;}protected boolean matchSelf(MetadataReader metadataReader) {// 获取元信息,这里是自定义注解@StringRepository信息AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();// 下面的this.annotationType.getName()是传入的org.springframework.stereotype.Componentreturn metadata.hasAnnotation(this.annotationType.getName()) ||(this.considerMetaAnnotations && metadata.hasMetaAnnotation(this.annotationType.getName()));}

AnnotationMetadata#hasMetaAnnotation

// 判断底层注解是否包含metaAnnotationName
default boolean hasMetaAnnotation(String metaAnnotationName) {return getAnnotations().get(metaAnnotationName,MergedAnnotation::isMetaPresent).isPresent();
}

到了这里, 就已经很清晰了,只有两个方法,一个是metadata.hasAnnotation(this.annotationType.getName()),这是判断类上是否含有给定的注解,
还有个方法就是 metadata.hasMetaAnnotation(this.annotationType.getName()),这是判断底层class是否含有给定的注解,而@StringRepository的底层确实包含了@Component,所以这里方法返回true。

如果有地方有疑惑或者写的有不好,可以评论或者通过邮箱联系我creazycoder@sina.com

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

相关文章

  1. AlibabaProtect无法删除?无法禁用?

    转载自:https://blog.csdn.net/becooner/article/details/99833665 AlibabaProtect,与优酷捆绑并强行安装的软件(或许阿里系软件都有) 但是却无法直接结束该进程,c盘下的\Program Files (x86)中的AlibabaProtect文件夹也无法直接删除。 ** 下面介绍如何快速删除该进程服务 …...

    2024/4/20 13:36:17
  2. 模型保存和加载

    保存模型 三种方法:save/load weights save/load entire model saved_model最常用的方式 save/load weights 此方式多用在当自己自定义模型时。 具体用法为:保存模型的参数(可以随意指定保存的路径)model.sava_weights(".\chekpoints\my_checkpoint")加载模型的参…...

    2024/4/16 10:33:32
  3. 小白学cloud之创建父工程

    1、新建Project, 选择java8 ,选择maven架构2、maven 最好选择自己安装的3.5以上的3、进来以后开启自动导入功能4、字符编码 setting ->File Encodings 选UTF-85、注解生效激活6、java编译版本选择87、父工程pom文件 (删除src文件夹)dependecyManegement 管理依赖版本号…...

    2024/4/16 10:35:37
  4. 折半查找法的递归与非递归写法——C++

    介绍: 折半查找(BinarySearch)也称二分查找,它是一种效率较高的查找方法。但是,折半查找要求线性表必须采用顺序存储结构, 而且表中元素按关键字有序排列。 查找过程: 从表的中间记录开始,如果给定值和中间记录的关键字相等, 则查找成功;如果给定值大于或者小千中间记录…...

    2024/4/16 10:36:19
  5. Redis(开发与运维):49---集群之(集群伸缩:伸缩原理、集群扩容、集群收缩)

    一、伸缩原理Redis集群提供了灵活的节点扩容和收缩方案。在不影响集群对外服务的情况下,可以为集群添加节点进行扩容也可以下线部分节点进行缩容,如下图所示:从上图看出,Redis集群可以实现对节点的灵活上下线控制。其中原理可抽象为槽和对应数据在不同节点之间灵活移动。首…...

    2024/4/24 9:35:20
  6. 九大排序之快速排序(C语言实现)(数据结构)

    快速排序(Quicksort)是对冒泡排序的一种改进。 快速排序由C. A. R. Hoare在1960年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程…...

    2024/4/24 9:35:19
  7. jQuery实现无动画轮播图(含完整源码)

    本博文源于jquery基础,旨在探讨如何实现无动画轮播图。 测试效果自己会动,点击黄色按钮或者点击右下方按钮也可以自动跳转。 之前用原生态实现动画轮播图,也可以去看一下: JavaScript|3步搞定轮播图(含测试源码) 因为之前比较简单,只是考虑左右按钮点点动动,所以大家看完…...

    2024/4/24 9:35:18
  8. 图片实现染色效果(基于滤镜和混合模式)

    法一:基于滤镜 sepia(),它会给图片增加一种降饱和度的橙黄色染色效果。 如果我们想好的主色调的饱和度比这高,可用saturate()滤镜来给每个像素提升饱和度。 若不希望把图片调为橙黄色调,而是稍深的亮粉色,还需再添加一个hue-rotate()滤镜,把每个像素的色相以指定的度数进…...

    2024/4/24 9:35:14
  9. JS怎么获取当前时间戳

    JS获取当前时间戳,可以通过Date.now()方法来实现,返回自1970年1月1日00:00:00 UTC以来经过的毫秒数也就是当前时间戳。下面我们就结合具体的代码示例,给大家介绍JS怎么获取当前时间戳。代码示例如下:打造全网web前端全栈资料库(总目录)看完学的更快,掌握的更加牢固,你值…...

    2024/4/24 9:35:13
  10. PySeison-教程4:TideGauge类

    PySeison-教程4:TideGauge类%pylab inline从numpy和matplotlib填充交互式名称空间1. PySeidon-TideGauge对象初始化与“ ADCP类”和“ Drifter类”相似,“ TideGauge类”是基于测量的对象。1.1。包装进口与Python中的任何其他库一样,必须先导入PySeidon才能使用。在这里,我…...

    2024/4/24 9:35:13
  11. Linux笔记

    Linux与UNIX发展史 关系:UNIX-Linux(父-子)Linux系统简介 开源软件 商业软件:收费 开源软件:不等同于免费软件Linux应用领域 查询后台服务器网站:www.netcraft.com 1、企业服务器 2、嵌入式 3、电影娱乐业 Linux系统安装VMware 简介 VMware是一个虚拟PC软件,可以在现有的…...

    2024/4/24 9:35:11
  12. Ubuntu图形化界面崩溃修复办法

    Ubuntu图形化界面的修复 问题复现:界面出现“The system is running in low-graphics mode”错误 解决方法: 1.Ctrl+ALT+F1 进入控制台【笔记本:Ctrl+Fn+ALT+F1】 2.输入用户名(root)和密码进入系统 3.输入以下命令:cd /etc/X11 sudo cp xorg.conf.failsafe xorg.conf sud…...

    2024/4/27 4:53:10
  13. idea相关快捷键

    Ctrl相关快捷键 介绍Ctrl + B 进入光标所在的方法/变量的接口或是定义处,等效于Ctrl + 左键单击Ctrl + D 复制光标所在行或复制选择内容,并把复制内容插入光标位置下面Ctrl + F 在当前文件进行文本查找Ctrl + H 查看类的继承结构Ctrl + N 通过类名定位文件Ctrl + O 快速重写父…...

    2024/4/24 9:35:09
  14. 辉涩笔记004—20200531

    如何让自己在黑月中也可以发光 目标,30500 1.规划好自己的职业路线 2.规划好自己的时间,每天要做什么?每天都有产出。 3.让别人感觉到自己的进步。 4.多看书。写读后感。 拼尽所有,拼上生命,往前跑,只为在漫漫旅途中给你照亮前方。...

    2024/4/24 9:35:16
  15. 原生js实现Ajax原理

    相信很多小伙伴在面试的时候,大部分都逃不了被问原生js的问题吧,尤其是高频的高频,** 说一下实现原生Ajax的原理** 原生???哦买噶的!在回答这个问题前,我们需要了解一下什么是ajax,通俗易懂的来说就是在不刷新页面的情况下,能获取到新的数据 ajax的工作原理是什么?废…...

    2024/4/24 9:35:10
  16. 词根vol/volve/vor/vid/vis/等衍生出单词

    本博文源于刘洪波老师的《英文字根词源精讲》,包含vid/vis/vig/viv/voc/vol/volve/vor/等词根衍生的单词,也包含ab/ad/ambi/an/anti/auto/bene/bi/cata/circum/com/contra/de等英文前根 vid/vis = to see 看见 来源于拉丁文videre,“to see”. visa n.签证 visage n.容貌 vi…...

    2024/4/16 10:35:12
  17. 2020.5.31 python学习

    与类相关的魔术属性 class Man():passclass Woman():passclass Children(Man,Woman):""" 成员属性: eye 成员方法: skylight moonread __makebaby 完成的功能: 描述小孩天生神力. """eye = "血轮眼"def skylight(self):print("一…...

    2024/4/16 10:36:14
  18. Python常用内建模块

    文章目录datetime获取当前日期和时间获取指定日期和时间datetime转化为timestamptimestamp转化为datetimestr转化为datetimedatetime转化为strdatetime加减collectionsnamedtupledequedefaultdictChainMapCounterbase64hashlib摘要算法简介MD5摘要算法使用摘要算法的应用hmacit…...

    2024/4/18 23:26:26
  19. 设置Android Studio开发无线调试

    设置Android Studio开发无线调试1、从插件市场安装插件WIFI ADB ULTIMATE并重启Android Studio生效。这是右边框会增加一个选项,就是刚才安装的插件:2、保证手机/pad设备和电脑连接同一wifi,否则无法进行无线调试,切记。3、通过数据线连接设备,打开设备的5555端口,每次设…...

    2024/4/16 10:36:04
  20. 计算机网络安全教程(第三版)第十章简答题答案

    第 10 章 防火墙与入侵检测什么是防火墙?古时候的防火墙和目前通常说的防火墙有什么联系和区别? 答: 防火墙的本义原指古代人们的房屋之间修建的墙,这道墙可以防止火灾发生时蔓延到别的房屋。现今防火墙不是指为了防火而造的墙,而是指隔离在本地网络与外界网络之间的一道防…...

    2024/4/16 10:36:29

最新文章

  1. JS三级联动

    三级联动是指页面上有三个下拉框&#xff0c;第一个下拉框选定某个选项后&#xff0c;第二个下拉框会根据第一个下拉框的选项进行筛选&#xff0c;第三个下拉框会根据第二个下拉框的选项进行筛选。这种交互方式可以帮助用户快速定位到需要的选项。 下面是一个简单的三级联动的…...

    2024/4/27 13:35:33
  2. 梯度消失和梯度爆炸的一些处理方法

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

    2024/3/20 10:50:27
  3. 【THM】Protocols and Servers(协议和服务器)-初级渗透测试

    介绍 这个房间向用户介绍了一些常用的协议,例如: HTTP协议文件传输协议POP3邮件传输协议IMAP每个协议的每个任务都旨在帮助我们了解底层发生的情况,并且通常被优雅的GUI(图形用户界面)隐藏。我们将使用简单的 Telnet 客户端来使用上述协议进行“对话”,以充分了解GUI客户…...

    2024/4/26 8:55:10
  4. Kafka架构概述

    Kafka的体系结构 Kafka是由Apache软件基金会管理的一个开源的分布式数据流处理平台。Kafka具有支持消息的发布/订阅模式、高吞吐量与低延迟、持久化、支持水平扩展、高可用性等特点。可以将Kafka应用于大数据实时处理、高性能数据管道、流分析、数据集成和关键任务应用等场景。…...

    2024/4/24 15:38:05
  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/25 18:39:22
  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