Spring + SpringBoot史上最全的注解说明

Spring中的注解

Spring中的注解大概可以分为两大类:

  1. spring的bean容器相关的注解,或者说bean工厂相关的注解;
  2. springmvc相关的注解。

spring的bean容器相关的注解,先后有:@Required, @Autowired, @PostConstruct, @PreDestory,还有Spring3.0开始支持的JSR-330标准javax.inject.*中的注解(@Inject, @Named, @Qualifier, @Provider, @Scope, @Singleton).

springmvc相关的注解有:@Controller, @RequestMapping, @RequestParam, @ResponseBody等等。

要理解Spring中的注解,先要理解Java中的注解。

1. Java中的注解

Java中1.5中开始引入注解,我们最熟悉的应该是:@Override, 它的定义如下:

/*** Indicates that a method declaration is intended to override a* method declaration in a supertype. If a method is annotated with* this annotation type compilers are required to generate an error* message unless at least one of the following conditions hold:* The method does override or implement a method declared in a* supertype.* The method has a signature that is override-equivalent to that of* any public method declared in Object.** @author  Peter von der Ahé* @author  Joshua Bloch* @jls 9.6.1.4 @Override* @since 1.5*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

从注释,我们可以看出,@Override的作用是,提示编译器,使用了@Override注解的方法必须override父类或者java.lang.Object中的一个同名方法。我们看到@Override的定义中使用到了 @Target, @Retention,它们就是所谓的“元注解”——就是定义注解的注解,或者说注解注解的注解(晕了...)。我们看下@Retention

/*** Indicates how long annotations with the annotated type are to* be retained.  If no Retention annotation is present on* an annotation type declaration, the retention policy defaults to* RetentionPolicy.CLASS.*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {/*** Returns the retention policy.* @return the retention policy*/RetentionPolicy value();
}

@Retention用于提示注解被保留多长时间,有三种取值:

public enum RetentionPolicy {/*** Annotations are to be discarded by the compiler.*/SOURCE,/*** Annotations are to be recorded in the class file by the compiler* but need not be retained by the VM at run time.  This is the default* behavior.*/CLASS,/*** Annotations are to be recorded in the class file by the compiler and* retained by the VM at run time, so they may be read reflectively.** @see java.lang.reflect.AnnotatedElement*/RUNTIME
}

RetentionPolicy.SOURCE 保留在源码级别,被编译器抛弃(@Override就是此类);RetentionPolicy.CLASS被编译器保留在编译后的类文件级别,但是被虚拟机丢弃;

RetentionPolicy.RUNTIME保留至运行时,可以被反射读取。

再看 @Target:

package java.lang.annotation;/*** Indicates the contexts in which an annotation type is applicable. The* declaration contexts and type contexts in which an annotation type may be* applicable are specified in JLS 9.6.4.1, and denoted in source code by enum* constants of java.lang.annotation.ElementType* @since 1.5* @jls 9.6.4.1 @Target* @jls 9.7.4 Where Annotations May Appear*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {/*** Returns an array of the kinds of elements an annotation type* can be applied to.* @return an array of the kinds of elements an annotation type* can be applied to*/ElementType[] value();
}

@Target用于提示该注解使用的地方,取值有:

public enum ElementType {/** Class, interface (including annotation type), or enum declaration */TYPE,/** Field declaration (includes enum constants) */FIELD,/** Method declaration */METHOD,/** Formal parameter declaration */PARAMETER,/** Constructor declaration */CONSTRUCTOR,/** Local variable declaration */LOCAL_VARIABLE,/** Annotation type declaration */ANNOTATION_TYPE,/** Package declaration */PACKAGE,/*** Type parameter declaration* @since 1.8*/TYPE_PARAMETER,/*** Use of a type* @since 1.8*/TYPE_USE
}

分别表示该注解可以被使用的地方:

  1. 类,接口,注解,enum;
  2. 属性域;
  3. 方法;
  4. 参数;
  5. 构造函数;
  6. 局部变量;
  7. 注解类型;

所以:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

表示 @Override 只能使用在方法上,保留在源码级别,被编译器处理,然后抛弃掉。

还有一个经常使用的元注解 @Documented :

/*** Indicates that annotations with a type are to be documented by javadoc* and similar tools by default.  This type should be used to annotate the* declarations of types whose annotations affect the use of annotated* elements by their clients.  If a type declaration is annotated with* Documented, its annotations become part of the public API* of the annotated elements.*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}

表示注解是否能被 javadoc 处理并保留在文档中。

2. 使用 元注解 来自定义注解 和 处理自定义注解

有了元注解,那么我就可以使用它来自定义我们需要的注解。结合自定义注解和AOP或者过滤器,是一种十分强大的武器。比如可以使用注解来实现权限的细粒度的控制——在类或者方法上使用权限注解,然后在AOP或者过滤器中进行拦截处理。下面是一个关于登录的权限的注解的实现:

/*** 不需要登录注解*/
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface NoLogin {
}

我们自定义了一个注解 @NoLogin, 可以被用于 方法 和 类 上,注解一直保留到运行期,可以被反射读取到。该注解的含义是:被 @NoLogin 注解的类或者方法,即使用户没有登录,也是可以访问的。下面就是对注解进行处理了:

/*** 检查登录拦截器* 如不需要检查登录可在方法或者controller上加上@NoLogin*/
public class CheckLoginInterceptor implements HandlerInterceptor {private static final Logger logger = Logger.getLogger(CheckLoginInterceptor.class);@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handler) throws Exception {if (!(handler instanceof HandlerMethod)) {logger.warn("当前操作handler不为HandlerMethod=" + handler.getClass().getName() + ",req="+ request.getQueryString());return true;}HandlerMethod handlerMethod = (HandlerMethod) handler;String methodName = handlerMethod.getMethod().getName();// 判断是否需要检查登录NoLogin noLogin = handlerMethod.getMethod().getAnnotation(NoLogin.class);if (null != noLogin) {if (logger.isDebugEnabled()) {logger.debug("当前操作methodName=" + methodName + "不需要检查登录情况");}return true;}noLogin = handlerMethod.getMethod().getDeclaringClass().getAnnotation(NoLogin.class);if (null != noLogin) {if (logger.isDebugEnabled()) {logger.debug("当前操作methodName=" + methodName + "不需要检查登录情况");}return true;}if (null == request.getSession().getAttribute(CommonConstants.SESSION_KEY_USER)) {logger.warn("当前操作" + methodName + "用户未登录,ip=" + request.getRemoteAddr());response.getWriter().write(JsonConvertor.convertFailResult(ErrorCodeEnum.NOT_LOGIN).toString()); // 返回错误信息return false;}return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response,Object handler, ModelAndView modelAndView) throws Exception {}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response,Object handler, Exception ex) throws Exception {}
}

上面我们定义了一个登录拦截器,首先使用反射来判断方法上是否被 @NoLogin 注解:

NoLoginnoLogin=handlerMethod.getMethod().getAnnotation(NoLogin.class);

然后判断类是否被 @NoLogin 注解:

noLogin=handlerMethod.getMethod().getDeclaringClass().getAnnotation(NoLogin.class);

如果被注解了,就返回 true,如果没有被注解,就判断是否已经登录,没有登录则返回错误信息给前台和false. 这是一个简单的使用 注解 和 过滤器 来进行权限处理的例子。扩展开来,那么我们就可以使用注解,来表示某方法或者类,只能被具有某种角色,或者具有某种权限的用户所访问,然后在过滤器中进行判断处理。

3. spring的bean容器相关的注解

1)@Autowired 是我们使用得最多的注解,其实就是 autowire=byType 就是根据类型的自动注入依赖(基于注解的依赖注入),可以被使用再属性域,方法,构造函数上。

2)@Qualifier 就是 autowire=byName, @Autowired注解判断多个bean类型相同时,就需要使用 @Qualifier("xxBean") 来指定依赖的bean的id:

@Controller
@RequestMapping("/user")
public class HelloController {@Autowired@Qualifier("userService")private UserService userService;

3)@Resource 属于JSR250标准,用于属性域额和方法上。也是 byName 类型的依赖注入。使用方式:@Resource(name="xxBean"). 不带参数的 @Resource 默认值类名首字母小写。

4)JSR-330标准javax.inject.*中的注解(@Inject, @Named, @Qualifier, @Provider, @Scope, @Singleton)。@Inject就相当于@Autowired, @Named 就相当于 @Qualifier, 另外 @Named 用在类上还有 @Component的功能。

5)@Component, @Controller, @Service, @Repository, 这几个注解不同于上面的注解,上面的注解都是将被依赖的bean注入进入,而这几个注解的作用都是生产bean, 这些注解都是注解在类上,将类注解成spring的bean工厂中一个一个的bean。@Controller, @Service, @Repository基本就是语义更加细化的@Component。

6)@PostConstruct 和 @PreDestroy 不是用于依赖注入,而是bean 的生命周期。类似于 init-method(InitializeingBean) destory-method(DisposableBean)

4. spring中注解的处理

spring中注解的处理基本都是通过实现接口 BeanPostProcessor 来进行的:

public interface BeanPostProcessor {Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}

相关的处理类有:AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor,PersistenceAnnotationBeanPostProcessor,RequiredAnnotationBeanPostProcessor

这些处理类,可以通过 context:annotation-config/ 配置隐式的配置进spring容器。这些都是依赖注入的处理,还有生产bean的注解(@Component, @Controller, @Service, @Repository)的处理:

<context:component-scan base-package="net.aazj.service,net.aazj.aop" />

这些都是通过指定扫描的基包路径来进行的,将他们扫描进spring的bean容器。注意context:component-scan也会默认将 AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor 配置进来。所以context:annotation-config/是可以省略的。另外context:component-scan也可以扫描@Aspect风格的AOP注解,但是需要在配置文件中加入 aop:aspectj-autoproxy/ 进行配合。

SpringBoot 注解

使用注解的优势:

  1. 采用纯java代码,不在需要配置繁杂的xml文件

  2. 在配置中也可享受面向对象带来的好处

  3. 类型安全对重构可以提供良好的支持

  4. 减少复杂配置文件的同时亦能享受到springIoC容器提供的功能

1、注解详解(配备了完善的释义)

可采用 ctrl+F 来进行搜索哦~~~~

@SpringBootApplication:申明让spring boot自动给程序进行必要的配置,这个配置等同于:@Configuration ,@EnableAutoConfiguration 和 @ComponentScan 三个配置。

@ResponseBody:表示该方法的返回结果直接写入HTTP response body中,一般在异步获取数据时使用,用于构建RESTful的api。在使用@RequestMapping后,返回值通常解析为跳转路径,加上@esponsebody后返回结果不会被解析为跳转路径,而是直接写入HTTP response body中。比如异步获取json数据,加上@Responsebody后,会直接返回json数据。该注解一般会配合@RequestMapping一起使用。

@Controller:用于定义控制器类,在spring项目中由控制器负责将用户发来的URL请求转发到对应的服务接口(service层),一般这个注解在类中,通常方法需要配合注解@RequestMapping。

@RestController:用于标注控制层组件(如struts中的action),@ResponseBody和@Controller的合集。

@RequestMapping:提供路由信息,负责URL到Controller中的具体函数的映射。

@EnableAutoConfiguration:SpringBoot自动配置(auto-configuration):尝试根据你添加的jar依赖自动配置你的Spring应用。例如,如果你的classpath下存在HSQLDB,并且你没有手动配置任何数据库连接beans,那么我们将自动配置一个内存型(in-memory)数据库”。你可以将@EnableAutoConfiguration或者@SpringBootApplication注解添加到一个@Configuration类上来选择自动配置。如果发现应用了你不想要的特定自动配置类,你可以使用@EnableAutoConfiguration注解的排除属性来禁用它们。

@ComponentScan:表示将该类自动发现扫描组件。个人理解相当于,如果扫描到有@Component、@Controller、@Service等这些注解的类,并注册为Bean,可以自动收集所有的Spring组件,包括@Configuration类。我们经常使用@ComponentScan注解搜索beans,并结合@Autowired注解导入。可以自动收集所有的Spring组件,包括@Configuration类。我们经常使用@ComponentScan注解搜索beans,并结合@Autowired注解导入。如果没有配置的话,Spring Boot会扫描启动类所在包下以及子包下的使用了@Service,@Repository等注解的类。

@Configuration:相当于传统的xml配置文件,如果有些第三方库需要用到xml文件,建议仍然通过@Configuration类作为项目的配置主类——可以使用@ImportResource注解加载xml配置文件。

@Import:用来导入其他配置类。

@ImportResource:用来加载xml配置文件。

@Autowired:自动导入依赖的bean

@Service:一般用于修饰service层的组件

@Repository:使用@Repository注解可以确保DAO或者repositories提供异常转译,这个注解修饰的DAO或者repositories类会被ComponetScan发现并配置,同时也不需要为它们提供XML配置项。

@Bean:用@Bean标注方法等价于XML中配置的bean。

@Value:注入Spring boot application.properties配置的属性的值。示例代码:

@Inject:等价于默认的@Autowired,只是没有required属性;

@Component:泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。

@Bean:相当于XML中的,放在方法的上面,而不是类,意思是产生一个bean,并交给spring管理。

@AutoWired:自动导入依赖的bean。byType方式。把配置好的Bean拿来用,完成属性、方法的组装,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。当加上(required=false)时,就算找不到bean也不报错。

@Qualifier:当有多个同一类型的Bean时,可以用@Qualifier(“name”)来指定。与@Autowired配合使用。@Qualifier限定描述符除了能根据名字进行注入,但能进行更细粒度的控制如何选择候选者,具体使用方式如下:

@Resource(name=”name”,type=”type”):没有括号内内容的话,默认byName。与@Autowired干类似的事。

2、注解列表如下

@SpringBootApplication:包含了@ComponentScan、@Configuration和@EnableAutoConfiguration注解。其中

@ComponentScan:让spring Boot扫描到Configuration类并把它加入到程序上下文。

@Configuration :等同于spring的XML配置文件;使用Java代码可以检查类型安全。

@EnableAutoConfiguration :自动配置。

@ComponentScan :组件扫描,可自动发现和装配一些Bean。

@Component可配合CommandLineRunner使用,在程序启动后执行一些基础任务。

@RestController:注解是@Controller和@ResponseBody的合集,表示这是个控制器bean,并且是将函数的返回值直 接填入HTTP响应体中,是REST风格的控制器。

@Autowired:自动导入。

@PathVariable:获取参数。

@JsonBackReference:解决嵌套外链问题。

@RepositoryRestResourcepublic:配合spring-boot-starter-data-rest使用。

3、JPA注解

@Entity:@Table(name=”“):表明这是一个实体类。一般用于jpa这两个注解一般一块使用,但是如果表名和实体类名相同的话,@Table可以省略

@MappedSuperClass:用在确定是父类的entity上。父类的属性子类可以继承。

@NoRepositoryBean:一般用作父类的repository,有这个注解,spring不会去实例化该repository。

@Column:如果字段名与列名相同,则可以省略。

@Id:表示该属性为主键。

@GeneratedValue(strategy = GenerationType.SEQUENCE,generator = “repair_seq”):表示主键生成策略是sequence(可以为Auto、IDENTITY、native等,Auto表示可在多个数据库间切换),指定sequence的名字是repair_seq。

@SequenceGeneretor(name = “repair_seq”, sequenceName = “seq_repair”, allocationSize = 1):name为sequence的名称,以便使用,sequenceName为数据库的sequence名称,两个名称可以一致。

@Transient:表示该属性并非一个到数据库表的字段的映射,ORM框架将忽略该属性。如果一个属性并非数据库表的字段映射,就务必将其标示为@Transient,否则,ORM框架默认其注解为@Basic。@Basic(fetch=FetchType.LAZY):标记可以指定实体属性的加载方式

@JsonIgnore:作用是json序列化时将Java bean中的一些属性忽略掉,序列化和反序列化都受影响。

@JoinColumn(name=”loginId”):一对一本表中指向另一个表的外键。一对多:另一个表指向本表的外键。

@OneToOne、@OneToMany、@ManyToOne:对应hibernate配置文件中的一对一,一对多,多对一。

4、springMVC相关注解

@RequestMapping:@RequestMapping(“/path”)表示该控制器处理所有“/path”的UR L请求。RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。

用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。该注解有六个属性:

  • params:指定request中必须包含某些参数值是,才让该方法处理。

  • headers:指定request中必须包含某些指定的header值,才能让该方法处理请求。

  • value:指定请求的实际地址,指定的地址可以是URI Template 模式

  • method:指定请求的method类型, GET、POST、PUT、DELETE等

  • consumes:指定处理请求的提交内容类型(Content-Type),如application/json,text/html;

  • produces:指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回

@RequestParam:用在方法的参数前面。

@RequestParam

String a =request.getParameter(“a”)。

@PathVariable:路径变量。

参数与大括号里的名字一样要相同。

5、全局异常处理

@ControllerAdvice:包含@Component。可以被扫描到。统一处理异常。

@ExceptionHandler(Exception.class):用在方法上面表示遇到这个异常就执行以下方法。

6、项目中具体配置解析和使用环境

@MappedSuperclass

  1. @MappedSuperclass 注解使用在父类上面,是用来标识父类的

  2. @MappedSuperclass 标识的类表示其不能映射到数据库表,因为其不是一个完整的实体类,但是它所拥有的属性能够映射在其子类对用的数据库表中

  3. @MappedSuperclass 标识的类不能再有@Entity或@Table注解

@Column

1.当实体的属性与其映射的数据库表的列不同名时需要使用@Column标注说明,该属性通常置于实体的属性声明语句之前,还可与 @Id 标注一起使用。

2.@Column 标注的常用属性是name,用于设置映射数据库表的列名。此外,该标注还包含其它多个属性,如:unique、nullable、length、precision等。具体如下:

  • name属性:name属性定义了被标注字段在数据库表中所对应字段的名称

  • unique属性:unique属性表示该字段是否为唯一标识,默认为false,如果表中有一个字段需要唯一标识,则既可以使用该标记,也可以使用@Table注解中的@UniqueConstraint

  • nullable属性:nullable属性表示该字段是否可以为null值,默认为true

  • insertable属性:insertable属性表示在使用”INSERT”语句插入数据时,是否需要插入该字段的值

  • updateable属性:updateable属性表示在使用”UPDATE”语句插入数据时,是否需要更新该字段的值

  • insertable和updateable属性:一般多用于只读的属性,例如主键和外键等,这些字段通常是自动生成的

  • columnDefinition属性:columnDefinition属性表示创建表时,该字段创建的SQL语句,一般用于通过Entity生成表定义时使用,如果数据库中表已经建好,该属性没有必要使用

  • table属性:table属性定义了包含当前字段的表名

  • length属性:length属性表示字段的长度,当字段的类型为varchar时,该属性才有效,默认为255个字符

  • precision属性和scale属性:precision属性和scale属性一起表示精度,当字段类型为double时,precision表示数值的总长度,scale表示小数点所占的位数

具体如下:

  • double类型将在数据库中映射为double类型,precision和scale属性无效

  • double类型若在columnDefinition属性中指定数字类型为decimal并指定精度,则最终以columnDefinition为准

  • BigDecimal类型在数据库中映射为decimal类型,precision和scale属性有效

  • precision和scale属性只在BigDecimal类型中有效

3.@Column 标注的columnDefinition属性: 表示该字段在数据库中的实际类型.通常 ORM 框架可以根据属性类型自动判断数据库中字段的类型,但是对于Date类型仍无法确定数据库中字段类型究竟是DATE,TIME还是TIMESTAMP.此外,String的默认映射类型为VARCHAR,如果要将 String 类型映射到特定数据库的 BLOB 或TEXT字段类型.

4.@Column标注也可置于属性的getter方法之前

@Getter和@Setter(Lombok)

@Setter:注解在属性上;为属性提供 setting 方法 @Getter:注解在属性上;为属性提供 getting 方法

  • @Data:注解在类上;提供类所有属性的 getting 和 setting 方法,此外还提供了equals、canEqual、hashCode、toString 方法

  • @Setter:注解在属性上;为属性提供 setting 方法

  • @Getter:注解在属性上;为属性提供 getting 方法

  • @Log4j2 :注解在类上;为类提供一个 属性名为log 的 log4j 日志对象,和@Log4j注解类似

  • @NoArgsConstructor:注解在类上;为类提供一个无参的构造方法

  • @AllArgsConstructor:注解在类上;为类提供一个全参的构造方法

  • @EqualsAndHashCode:默认情况下,会使用所有非瞬态(non-transient)和非静态(non-static)字段来生成equals和hascode方法,也可以指定具体使用哪些属性。

  • @toString:生成toString方法,默认情况下,会输出类名、所有属性,属性会按照顺序输出,以逗号分割。

  • @NoArgsConstructor, @RequiredArgsConstructor and @AllArgsConstructor无参构造器、部分参数构造器、全参构造器,当我们需要重载多个构造器的时候,只能自己手写了

  • @NonNull:注解在属性上,如果注解了,就必须不能为Null

  • @val:注解在属性上,如果注解了,就是设置为final类型,可查看源码的注释知道

当你在执行各种持久化方法的时候,实体的状态会随之改变,状态的改变会引发不同的生命周期事件。这些事件可以使用不同的注释符来指示发生时的回调函数。

@javax.persistence.PostLoad:加载后。

@javax.persistence.PrePersist:持久化前。

@javax.persistence.PostPersist:持久化后。

@javax.persistence.PreUpdate:更新前。

@javax.persistence.PostUpdate:更新后。

@javax.persistence.PreRemove:删除前。

@javax.persistence.PostRemove:删除后。

1)数据库查询

@PostLoad事件在下列情况下触发:

执行EntityManager.find()或getreference()方法载入一个实体后。

执行JPQL查询后。

EntityManager.refresh()方法被调用后。

2)数据库插入

@PrePersist和@PostPersist事件在实体对象插入到数据库的过程中发生:

@PrePersist事件在调用persist()方法后立刻发生,此时的数据还没有真正插入进数据库。

@PostPersist事件在数据已经插入进数据库后发生。

3)数据库更新

@PreUpdate和@PostUpdate事件的触发由更新实体引起:

@PreUpdate事件在实体的状态同步到数据库之前触发,此时的数据还没有真正更新到数据库。

@PostUpdate事件在实体的状态同步到数据库之后触发,同步在事务提交时发生。

4)数据库删除

@PreRemove和@PostRemove事件的触发由删除实体引起:

@PreRemove事件在实体从数据库删除之前触发,即在调用remove()方法删除时发生,此时的数据还没有真正从数据库中删除。

@PostRemove事件在实体从数据库中删除后触发。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/238084.shtml

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

相关文章

国产低成本Wi-Fi SoC解决方案芯片ESP8266与ESP8285对比差异

目录 ESP8266与ESP8285对比差异微信号&#xff1a;dnsj5343ESP8285简介ESP8285 主要特性Wi-Fi特性射频模块CPU特性硬件软件 ES8285 8266通用开发板 ESP8266与ESP8285对比差异 ESP8285相当于在ESP8266基础上多加了1/2MB Flash&#xff0c; ESP8285与ESP8266同用一套SDK&#xf…

落叶归根:递归思想在二叉树叶子节点类问题中的妙用

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《linux深造日志》 《高效算法》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 一、递归的介绍二、递归算法的妙用2.1 二叉树结点个数2.2 二叉树叶子结点个数2.3 二叉树第k层结点个数2.4 二叉树…

一些CSS的笔记

1.margin margin:0 auto 是指上下的值为0&#xff0c;左右的值为auto&#xff1b; margin:auto是指上右下左的值全都auto&#xff0c;即都是自适应的&#xff1b; margin:0; 这个是上右下左的值都为0&#xff1b; 2.vertical-align vertical-align 属性设置元素的垂直对齐方式。…

基于比较的排序算法总结(java实现版)

目录 什么是基于比较的排序算法 什么是排序算法的稳定性 基础排序算法的稳定性 插入排序法 希尔排序法 冒泡排序法 总结 高级算法的稳定性 快速排序法 堆排序法 归并排序法 总结 注意 什么是基于比较的排序算法 基于比较的排序算法定义&#xff1a;之所以能给元素…

安装gnvm,nodejs,npm使用方法

安装gnvm,nodejs,npm使用方法 一、安装gnvm gnvm.exe下载地址&#xff1a; https://download.csdn.net/download/hsg77/88651752 http://ksria.com/gnvm/#download 二、配置gnvm环境变量 新建目录&#xff0c;如&#xff1a;d:/nodejs 并把gnvm.exe存储到此目录 并把d:/node…

【MATLAB第85期】基于MATLAB的2023年智能进化算法/元启发式算法合集(持续更新)

【MATLAB第85期】基于MATLAB的2023年智能进化算法/元启发式算法合集&#xff08;持续更新&#xff09; 1.海象进化算法&#xff08;Walrus Optimization Algorithm&#xff09; 作者&#xff1a;Pavel Trojovsk and Mohammad Dehghani 2.暴龙优化算法&#xff08;Tyrannosa…

安卓13上手势导航失效、手机卡死问题

问题描述&#xff1a;打开我们开发的app后&#xff0c;手势导航无法退回、无法回到桌面、无法切换应用。 使用设备&#xff1a;小米手机、MI14,、安卓13 未适配安卓13安卓x的情况下&#xff0c;检查自己的 AndroidManifest 文件&#xff0c;过滤器是否设置了 <category a…

apache poi_5.2.5 实现表格内某一段单元格的复制

apache poi_5.2.5 实现表格内&#xff0c;某一段单元格的复制。 实现思路 1.定位开始位置 2.从开始位置之后&#xff0c;在行索引集合中添加行索引下标 3.截至到结束位置。 4.对行索引集合去重&#xff0c;并循环行索引集合 5.利用XWPFTableRow对像的getCtRow().copy()方法&a…

什么是伦敦金的假突破?假突破为何有效?

部分投资者做伦敦金交易的时候喜欢追逐那些强势的行情&#xff0c;也就是我们所说的突破行情。但是突破行情会带来两种结果&#xff0c;一种是突破成功&#xff0c;而另一种是出现假突破。什么是伦敦金中的假突破呢&#xff1f;为什么假突破会有效呢&#xff1f;下面我们就来讨…

Python自动化测试(超详细总结)

Python自动化测试常用于Web应用、移动应用、桌面应用等的测试 Python自动化实现思路通常分为以下几步&#xff1a; 1. 确定自动化测试的范围和目标&#xff1a; 首先需要明确需要进行自动化测试的范围和目标&#xff0c;包括测试场景、测试用例、测试数据等。 2. 选择自动化…

考研数学二内容总结

目录 高等数学 一、函数、极限、连续 考试内容 &#x1f3c1;总结&#xff1a; 考试要求 &#x1f3c1;1&#xff0e;理解函数的概念&#xff0c;掌握函数的表示法&#xff0c;会建立应用问题的函数关系&#xff0e; 2&#xff0e;了解函数的有界性、单调性、周期性和奇…

el-tree lazy懒加载(进阶版)

2023.12.22今天我学习了el-tree如何实现懒加载&#xff0c;效果如&#xff1a; 代码如下&#xff1a; 懒加载的使用不需要用:data <template><div><el-tree:props"props":load"loadNode"lazynode-key"id"show-checkbox/><…

寒冬送温暖||关爱山东省济宁市泗水县残疾人孤寡老人暖冬行

倡导扶残助弱的社会风尚&#xff0c;共建和谐美好的社会&#xff0c;保障山区残疾人、孤寡老人特殊群体度过一个安全、温暖的寒冬。12月19日&#xff0c;潍坊市金阳公益服务中心 、济宁市泗水县残疾人联合会、山东金琉通国际文化交流有限公司志愿站 在潍坊市社会组织培育中心举…

uniapp 添加分包页面,配置分包预下载

为什么要分包 ? 分包即将小程序代码分成多个部分打包&#xff0c;可以减少小程序的加载时间&#xff0c;提升用户体验 添加分包页面 比较便捷的方法是使用vscode插件 uni-create-view 新建分包文件夹 以在我的页面&#xff0c;添加分包的设置页面为例&#xff0c;新建文件夹 s…

python:删除空白

删除字符串末尾的空白 例如&#xff0c;下面的代码&#xff0c;变量hobby指向的字符串在末尾有一个空格&#xff1a; 可以使用函数rstrip()删除字符串末尾的空格&#xff0c;如下&#xff1a; 因为删除字符串末尾的空格并没有赋值给原变量hobby&#xff0c;所以此时查看hobb…

PDF文件如何设置限制打印?

想要限制PDF文件的打印功能&#xff0c;想要限制PDF文件打印清晰度&#xff0c;都可以通过设置限制编辑来达到目的。 打开PDF编辑器&#xff0c;找到设置限制编辑的界面&#xff0c;切换到加密状态&#xff0c;然后我们就看到 有印刷许可。勾选【权限密码】输入一个PDF密码&am…

lua中的循环 while、for、repeat until三种循环方式、pairs和ipairs区别

lua中的循环 while、for、repeat until三种循环方式、pairs和ipairs区别 介绍for循环参数ipairs和pairs whilerepeat until总结 介绍 这里我用while、for、repeat until分别输出1-20之间的奇数 &#xff0c;具体的语法可以看下面的代码 for循环 参数 定义一个初始值为start…

网络基础篇【网线的制作,OSI七层模型,集线器和交换机的介绍,路由器的介绍与设置】

目录 一、网线制作 1.1 工具介绍 1.1.1网线 1.1.2 网线钳 1.1.3 水晶头 1.1.4 网线测试仪 二、OSI七层模型 2.1 简介 2.2 OSI模型层次介绍 2.2.1 结构图 2.2.2 数据传输过程 2.3 相关网站 二、集线器 2.1 介绍 2.2 适用场景 三、交换机 3.1 介绍 3.2 适用场景…

Torch 加速

loss.item() 1. 费时 loss.backward() loss_item loss.item() # todo loss.item() 这个比较费时间 0.2743 秒 2. 省时 loss_item loss.item() #todo 把它 移到 loss.backward() 前面&#xff0c;这个操作只需要 0.00027 秒 loss.backward() Index d_inv[torch.isin…

重学设计模式-Iterator(迭代器模式)

Iterator迭代器模式 介绍&#xff1a; 迭代器模式是一种行为型设计模式&#xff0c;它允许你在不暴露集合底层表示&#xff08;并不知道集合底层使用何种方式对数据尽心存储&#xff09;的情况下遍历集合中的元素。 这种模式提供了一种方法&#xff0c;可以顺序访问一个聚合…