spring之基于注解管理Bean

学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。各位小伙伴,如果您:
想系统/深入学习某技术知识点…
一个人摸索学习很难坚持,想组团高效学习…
想写博客但无从下手,急需写作干货注入能量…
热爱写作,愿意让自己成为更好的人…

文章目录

  • 前言
  • 一、搭建子模块spring6-ioc-annotation
  • 二、开启组件扫描
  • 三、使用注解定义 Bean
  • 四、实验一:@Autowired注入
    • ①场景一:属性注入
    • ②场景二:set注入
    • ③场景三:构造方法注入
    • ④场景四:形参上注入
    • ⑤场景五:只有一个构造函数,无注解
    • ⑥场景六:@Autowired注解和@Qualifier注解联合
  • 五、实验二:@Resource注入
    • ①场景一:根据name注入
    • ②场景二:name未知注入
    • ③场景三 其他情况
  • 六、Spring全注解开发
  • 总结


前言

从 Java 5 开始,Java 增加了对注解(Annotation)的支持,它是代码中的一种特殊标记,可以在编译、类加载和运行时被读取,执行相应的处理。开发人员可以通过注解在不改变原有代码和逻辑的情况下,在源代码中嵌入补充信息。

Spring 从 2.5 版本开始提供了对注解技术的全面支持,我们可以使用注解来实现自动装配,简化 Spring 的 XML 配置。

Spring 通过注解实现自动装配的步骤如下:

  1. 引入依赖
  2. 开启组件扫描
  3. 使用注解定义 Bean
  4. 依赖注入

一、搭建子模块spring6-ioc-annotation

①搭建模块

搭建方式如:spring6-ioc-xml

②引入配置文件

引入spring-ioc-xml模块日志log4j2.xml

③添加依赖

<dependencies><!--spring context依赖--><!--当你引入Spring Context依赖之后,表示将Spring的基础依赖引入了--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>6.0.3</version></dependency><!--junit5测试--><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId><version>5.3.1</version></dependency><!--log4j2的依赖--><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.19.0</version></dependency><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-slf4j2-impl</artifactId><version>2.19.0</version></dependency>
</dependencies>

二、开启组件扫描

Spring 默认不使用注解装配 Bean,因此我们需要在 Spring 的 XML 配置中,通过 context:component-scan 元素开启 Spring Beans的自动扫描功能。开启此功能后,Spring 会自动从扫描指定的包(base-package 属性设置)及其子包下的所有类,如果类上使用了 @Component 注解,就将该类装配到容器中。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><!--开启组件扫描功能--><context:component-scan base-package="com.gedeshidai.spring6"></context:component-scan>
</beans>

注意:在使用 context:component-scan 元素开启自动扫描功能前,首先需要在 XML 配置的一级标签 中添加 context 相关的约束。

情况一:最基本的扫描方式

<context:component-scan base-package="com.gedeshidai.spring6">
</context:component-scan>

情况二:指定要排除的组件

<context:component-scan base-package="com.gedeshidai.spring6"><!-- context:exclude-filter标签:指定排除规则 --><!-- type:设置排除或包含的依据type="annotation",根据注解排除,expression中设置要排除的注解的全类名type="assignable",根据类型排除,expression中设置要排除的类型的全类名--><context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/><!--<context:exclude-filter type="assignable" expression="com.gedeshidai.spring6.controller.UserController"/>-->
</context:component-scan>

情况三:仅扫描指定组件

<context:component-scan base-package="com.gedeshidai" use-default-filters="false"><!-- context:include-filter标签:指定在原有扫描规则的基础上追加的规则 --><!-- use-default-filters属性:取值false表示关闭默认扫描规则 --><!-- 此时必须设置use-default-filters="false",因为默认规则即扫描指定包下所有类 --><!-- type:设置排除或包含的依据type="annotation",根据注解排除,expression中设置要排除的注解的全类名type="assignable",根据类型排除,expression中设置要排除的类型的全类名--><context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/><!--<context:include-filter type="assignable" expression="com.gedeshidai.spring6.controller.UserController"/>-->
</context:component-scan>

三、使用注解定义 Bean

Spring 提供了以下多个注解,这些注解可以直接标注在 Java 类上,将它们定义成 Spring Bean。

注解说明
@Component该注解用于描述 Spring 中的 Bean,它是一个泛化的概念,仅仅表示容器中的一个组件(Bean),并且可以作用在应用的任何层次,例如 Service 层、Dao 层等。 使用时只需将该注解标注在相应类上即可。
@Repository该注解用于将数据访问层(Dao 层)的类标识为 Spring 中的 Bean,其功能与 @Component 相同。
@Service该注解通常作用在业务层(Service 层),用于将业务层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。
@Controller该注解通常作用在控制层(如SpringMVC 的 Controller),用于将控制层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。

四、实验一:@Autowired注入

单独使用@Autowired注解,默认根据类型装配。【默认是byType】

查看源码:

package org.springframework.beans.factory.annotation;import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {boolean required() default true;
}

源码中有两处需要注意:

  • 第一处:该注解可以标注在哪里?

    • 构造方法上
    • 方法上
    • 形参上
    • 属性上
    • 注解上
  • 第二处:该注解有一个required属性,默认值是true,表示在注入的时候要求被注入的Bean必须是存在的,如果不存在则报错。如果required属性设置为false,表示注入的Bean存在或者不存在都没关系,存在的话就注入,不存在的话,也不报错。

①场景一:属性注入

创建UserDao接口

package com.gedeshidai.spring6.dao;public interface UserDao {public void print();
}

创建UserDaoImpl实现

package com.gedeshidai.spring6.dao.impl;import com.gedeshidai.spring6.dao.UserDao;
import org.springframework.stereotype.Repository;@Repository
public class UserDaoImpl implements UserDao {@Overridepublic void print() {System.out.println("Dao层执行结束");}
}

创建UserService接口

package com.gedeshidai.spring6.service;public interface UserService {public void out();
}

创建UserServiceImpl实现类

package com.gedeshidai.spring6.service.impl;import com.gedeshidai.spring6.dao.UserDao;
import com.gedeshidai.spring6.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class UserServiceImpl implements UserService {@Autowiredprivate UserDao userDao;@Overridepublic void out() {userDao.print();System.out.println("Service层执行结束");}
}

创建UserController类

package com.gedeshidai.spring6.controller;import com.gedeshidai.spring6.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;@Controller
public class UserController {@Autowiredprivate UserService userService;public void out() {userService.out();System.out.println("Controller层执行结束。");}}

测试一

package com.gedeshidai.spring6.bean;import com.gedeshidai.spring6.controller.UserController;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class UserTest {private Logger logger = LoggerFactory.getLogger(UserTest.class);@Testpublic void testAnnotation(){ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");UserController userController = context.getBean("userController", UserController.class);userController.out();logger.info("执行成功");}}

②场景二:set注入

修改UserServiceImpl类

package com.gedeshidai.spring6.service.impl;import com.gedeshidai.spring6.dao.UserDao;
import com.gedeshidai.spring6.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class UserServiceImpl implements UserService {private UserDao userDao;@Autowiredpublic void setUserDao(UserDao userDao) {this.userDao = userDao;}@Overridepublic void out() {userDao.print();System.out.println("Service层执行结束");}
}

修改UserController类

package com.gedeshidai.spring6.controller;import com.gedeshidai.spring6.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;@Controller
public class UserController {private UserService userService;@Autowiredpublic void setUserService(UserService userService) {this.userService = userService;}public void out() {userService.out();System.out.println("Controller层执行结束。");}}

测试:成功调用

③场景三:构造方法注入

修改UserServiceImpl类

package com.gedeshidai.spring6.service.impl;import com.gedeshidai.spring6.dao.UserDao;
import com.gedeshidai.spring6.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class UserServiceImpl implements UserService {private UserDao userDao;@Autowiredpublic UserServiceImpl(UserDao userDao) {this.userDao = userDao;}@Overridepublic void out() {userDao.print();System.out.println("Service层执行结束");}
}

修改UserController类

package com.gedeshidai.spring6.controller;import com.gedeshidai.spring6.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;@Controller
public class UserController {private UserService userService;@Autowiredpublic UserController(UserService userService) {this.userService = userService;}public void out() {userService.out();System.out.println("Controller层执行结束。");}}

测试:成功调用

④场景四:形参上注入

修改UserServiceImpl类

package com.gedeshidai.spring6.service.impl;import com.gedeshidai.spring6.dao.UserDao;
import com.gedeshidai.spring6.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class UserServiceImpl implements UserService {private UserDao userDao;public UserServiceImpl(@Autowired UserDao userDao) {this.userDao = userDao;}@Overridepublic void out() {userDao.print();System.out.println("Service层执行结束");}
}

修改UserController类

package com.gedeshidai.spring6.controller;import com.gedeshidai.spring6.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;@Controller
public class UserController {private UserService userService;public UserController(@Autowired UserService userService) {this.userService = userService;}public void out() {userService.out();System.out.println("Controller层执行结束。");}}

测试:成功调用

⑤场景五:只有一个构造函数,无注解

修改UserServiceImpl类

package com.gedeshidai.spring6.service.impl;import com.gedeshidai.spring6.dao.UserDao;
import com.gedeshidai.spring6.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;@Service
public class UserServiceImpl implements UserService {@Autowiredprivate UserDao userDao;public UserServiceImpl(UserDao userDao) {this.userDao = userDao;}@Overridepublic void out() {userDao.print();System.out.println("Service层执行结束");}
}

测试通过

当有参数的构造方法只有一个时,@Autowired注解可以省略。

说明:有多个构造方法时呢?大家可以测试(再添加一个无参构造函数),测试报错

⑥场景六:@Autowired注解和@Qualifier注解联合

添加dao层实现

package com.gedeshidai.spring6.dao.impl;import com.gedeshidai.spring6.dao.UserDao;
import org.springframework.stereotype.Repository;@Repository
public class UserDaoRedisImpl implements UserDao {@Overridepublic void print() {System.out.println("Redis Dao层执行结束");}
}

测试:测试异常

错误信息中说:不能装配,UserDao这个Bean的数量等于2

怎么解决这个问题呢?当然要byName,根据名称进行装配了。

修改UserServiceImpl类

package com.gedeshidai.spring6.service.impl;import com.gedeshidai.spring6.dao.UserDao;
import com.gedeshidai.spring6.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class UserServiceImpl implements UserService {@Autowired@Qualifier("userDaoImpl") // 指定bean的名字private UserDao userDao;@Overridepublic void out() {userDao.print();System.out.println("Service层执行结束");}
}

总结

  • @Autowired注解可以出现在:属性上、构造方法上、构造方法的参数上、setter方法上。
  • 当带参数的构造方法只有一个,@Autowired注解可以省略。()
  • @Autowired注解默认根据类型注入。如果要根据名称注入的话,需要配合@Qualifier注解一起使用。

五、实验二:@Resource注入

@Resource注解也可以完成属性注入。那它和@Autowired注解有什么区别?

  • @Resource注解是JDK扩展包中的,也就是说属于JDK的一部分。所以该注解是标准注解,更加具有通用性。(JSR-250标准中制定的注解类型。JSR是Java规范提案。)
  • @Autowired注解是Spring框架自己的。
  • @Resource注解默认根据名称装配byName,未指定name时,使用属性名作为name。通过name找不到的话会自动启动通过类型byType装配。
  • @Autowired注解默认根据类型装配byType,如果想根据名称装配,需要配合@Qualifier注解一起用。
  • @Resource注解用在属性上、setter方法上。
  • @Autowired注解用在属性上、setter方法上、构造方法上、构造方法参数上。

@Resource注解属于JDK扩展包,所以不在JDK当中,需要额外引入以下依赖:【如果是JDK8的话不需要额外引入依赖。高于JDK11或低于JDK8需要引入以下依赖。

<dependency><groupId>jakarta.annotation</groupId><artifactId>jakarta.annotation-api</artifactId><version>2.1.1</version>
</dependency>

源码:

package jakarta.annotation;import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(Resources.class)
public @interface Resource {String name() default "";String lookup() default "";Class<?> type() default Object.class;Resource.AuthenticationType authenticationType() default Resource.AuthenticationType.CONTAINER;boolean shareable() default true;String mappedName() default "";String description() default "";public static enum AuthenticationType {CONTAINER,APPLICATION;private AuthenticationType() {}}
}

①场景一:根据name注入

修改UserDaoImpl类

package com.gedeshidai.spring6.dao.impl;import com.gedeshidai.spring6.dao.UserDao;
import org.springframework.stereotype.Repository;@Repository("myUserDao")
public class UserDaoImpl implements UserDao {@Overridepublic void print() {System.out.println("Dao层执行结束");}
}

修改UserServiceImpl类

package com.gedeshidai.spring6.service.impl;import com.gedeshidai.spring6.dao.UserDao;
import com.gedeshidai.spring6.service.UserService;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;@Service
public class UserServiceImpl implements UserService {@Resource(name = "myUserDao")private UserDao myUserDao;@Overridepublic void out() {myUserDao.print();System.out.println("Service层执行结束");}
}

测试通过

②场景二:name未知注入

修改UserDaoImpl类

package com.gedeshidai.spring6.dao.impl;import com.gedeshidai.spring6.dao.UserDao;
import org.springframework.stereotype.Repository;@Repository("myUserDao")
public class UserDaoImpl implements UserDao {@Overridepublic void print() {System.out.println("Dao层执行结束");}
}

修改UserServiceImpl类

package com.gedeshidai.spring6.service.impl;import com.gedeshidai.spring6.dao.UserDao;
import com.gedeshidai.spring6.service.UserService;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;@Service
public class UserServiceImpl implements UserService {@Resourceprivate UserDao myUserDao;@Overridepublic void out() {myUserDao.print();System.out.println("Service层执行结束");}
}

测试通过

当@Resource注解使用时没有指定name的时候,还是根据name进行查找,这个name是属性名。

③场景三 其他情况

修改UserServiceImpl类,userDao1属性名不存在

package com.gedeshidai.spring6.service.impl;import com.gedeshidai.spring6.dao.UserDao;
import com.gedeshidai.spring6.service.UserService;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;@Service
public class UserServiceImpl implements UserService {@Resourceprivate UserDao userDao1;@Overridepublic void out() {userDao1.print();System.out.println("Service层执行结束");}
}

测试异常

根据异常信息得知:显然当通过name找不到的时候,自然会启动byType进行注入,以上的错误是因为UserDao接口下有两个实现类导致的。所以根据类型注入就会报错。

@Resource的set注入可以自行测试

总结:

@Resource注解:默认byName注入,没有指定name时把属性名当做name,根据name找不到时,才会byType注入。byType注入时,某种类型的Bean只能有一个

六、Spring全注解开发

全注解开发就是不再使用spring配置文件了,写一个配置类来代替配置文件。

package com.gedeshidai.spring6.config;import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;@Configuration
//@ComponentScan({"com.gedeshidai.spring6.controller", "com.gedeshidai.spring6.service","com.gedeshidai.spring6.dao"})
@ComponentScan("com.gedeshidai.spring6")
public class Spring6Config {
}

测试类

@Test
public void testAllAnnotation(){ApplicationContext context = new AnnotationConfigApplicationContext(Spring6Config.class);UserController userController = context.getBean("userController", UserController.class);userController.out();logger.info("执行成功");
}

总结

以上就是spring之基于注解管理Bean的相关知识点,希望对你有所帮助。
积跬步以至千里,积怠惰以至深渊。时代在这跟着你一起努力哦!

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

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

相关文章

[每周一更]-(第28期):Windows服务自启动设置

需求&#xff1a;有时候有些软件&#xff0c;想在开机后自启动&#xff0c;但是由于屏幕需要录入密码&#xff0c;但是普通开机启动的应用&#xff0c;需要在录入密码进去Windows界面才能启动&#xff0c;但是 不用解锁屏幕但需要运行的应用还是有的&#xff0c;比如一些软件远…

《每天一分钟学习C语言·二》

1、当使用const关键字变量就无法修改可当常量来用。常量指针不能通过指针来改变变量的值&#xff0c;但可以通过其他引用来改变变量的值常量指针也可以指向其他变量地址&#xff0c;如 int a5,b6; const int *pt &a; *pt6; //错误 a6; //正确 pt&b; //正确指针常量指…

互式流程图|BPMN JointJS+ JavaScript 3.7.3 Crack

JointJS 是 JavaScript 图表库为卓越的 UI 提供支持 使用经过验证的库快速、自信地构建高级视觉和无代码/低代码应用程序。 赋能全球行业领导者 使用 JointJS 构建的图表 一个库&#xff0c;‍无限 UI 选项 直接在您的应用程序中享受交互式流程图、BPMN 和其他图表工作室。利用…

7000字详解ERP管理系统!

在当今竞争激烈的商业世界中&#xff0c;中小企业不仅需要保持灵活性&#xff0c;更需要高效管理企业资源。 你可能听说过ERP系统&#xff0c;但它究竟是什么&#xff1f;它为何成为中小企业管理的不二选择&#xff1f;又是如何助力中小企业整合资源、提升效率&#xff0c;并在…

C 库函数 - asctime()

描述 C 库函数 char *asctime(const struct tm *timeptr) 返回一个指向字符串的指针&#xff0c;它代表了结构 struct timeptr 的日期和时间。 声明 下面是 asctime() 函数的声明。 char *asctime(const struct tm *timeptr)参数 timeptr 是指向 tm 结构的指针&#xff0c…

使用极狐gitlab初始化导入本地项目

本地有项目的情况需要同步到极狐gitlab上 第一步&#xff1a; 在gitlab上新创建一个空项目 ⚠️⚠️⚠️这里需要注意红色圈住的地方一定不要选择&#xff0c;因为选择了这个后续会有不必要的麻烦 第二步 在本地项目中删除原来的.git文件(这一步如果是新项目可以忽略&#…

VMware网络设置+Linux网卡设置+主机与虚拟机相互Ping通

目录 1. Linux网卡设置 1.1 ifcfg-ens33 1.2 修改配置信息 1.3 添加IP信息 1.4 重启网卡、关闭防火墙 2. VMware网络设置 3. 设置主机网络 4. 测试主机与虚拟机网络是否连通 4.1 主机ping虚拟机的Linux 4.2 虚拟机Linux来ping主机 1. Linux网卡设置 刚开始安装的Lin…

〖Python网络爬虫实战㊸〗- 极验滑块介绍(五)

订阅&#xff1a;新手可以订阅我的其他专栏。免费阶段订阅量1000 python项目实战 Python编程基础教程系列&#xff08;零基础小白搬砖逆袭) 说明&#xff1a;本专栏持续更新中&#xff0c;订阅本专栏前必读关于专栏〖Python网络爬虫实战〗转为付费专栏的订阅说明作者&#xff1…

ubuntu x86环境创建armv8 ubuntu2004 64位docker服务器

在arm编译速度慢&#xff0c;运行vscode远程耗费资源&#xff0c;因此尝试在ubuntu服务器上搭建armv8 64位编译环境&#xff0c;过程很简单&#xff0c;记录如下 一、安装qemu解释器 # 宿主机安装解释器和时区设置 sudo apt install -y qemu-user-static tzdata # 重启docker…

Java对接腾讯多人音视频房间回调接口示例

在前面我们已经对接好了腾讯多人音视频房间相关内容&#xff1a;Java对接腾讯多人音视频房间示例 为了完善业务逻辑&#xff0c;我们还需要对接它的一些回调接口 官方文档地址 主要就下面这些 这里因为比较简单直接上代码 里面有些工具类和上一章一样这里就没贴&#xff0c;需要…

React面试题:React.Component和React.PureComponent的区别?

回答思路&#xff1a;什么是PureComponent-->Component更新过程-->PureComponent更新过程-->PureComponent的优点 什么是PureComponent&#xff1a;pure&#xff1a;纯净的&#xff0c;即为纯组件&#xff0c;可以用来优化React程序&#xff0c;减少render函数执行的…

想要将numpyarray转换成Image出错,ValueError: Could not save to PNG for display

问题再现 cams_H 是一个形状为torch.size([1, 7, 7, 3])的tensor&#xff0c; 它经历了以下语句&#xff1a; cams_H_np cams_H.numpy() cams_H_img Image.fromarray(cams_H_np[0, :, :, 0]) cams_H_img报错了&#xff1a; ---------------------------------------------…

如何安装运行Wagtail并结合cpolar内网穿透实现公网访问网站界面

文章目录 前言1. 安装并运行Wagtail1.1 创建并激活虚拟环境 2. 安装cpolar内网穿透工具3. 实现Wagtail公网访问4. 固定的Wagtail公网地址 前言 Wagtail是一个用Python编写的开源CMS&#xff0c;建立在Django Web框架上。Wagtail 是一个基于 Django 的开源内容管理系统&#xf…

pycharm或anaconda安装第三方库的办法

https://pypi.tuna.tsinghua.edu.cn/simple/ ctrlF 查找seaborn 我是直接去镜像网站或官方网站找要下载安装的包&#xff0c;手动下载下来&#xff0c;再手动安装会比较快。 输入 pip install D:\Downloads\seaborn-0.9.0-py3-none-any.whl 回车&#xff0c;就很酸爽&#xff…

2024年软考报名条件有哪些?有学历限制吗?

不少考生开始准备报名2024年软件水平考试&#xff0c;那么报名软考有没有学历、专业以及工作经验等方面的限制呢?今天小编就给大家详细来介绍一下。 软考报名条件如下&#xff1a; 1、凡遵守中华人民共和国宪法和各项法律&#xff0c;恪守职业道德&#xff0c;具有一定计算机…

vscode设置保存时代码格式自动对齐

1.点击左下角扩展图标→点击“设置” 2.工作区→文本编辑器→格式化→format on save 打钩 3.看看效果&#xff1a; 加一个数据gender&#xff0c;跟前面的msg、age不对齐 CtrlS保存后&#xff0c;自动对齐了

Linux服务器已有硬盘扩容

1、进入服务器使用命令“lsblk”&#xff0c;可以看到vda2实际上是有1.2T空间的&#xff0c;但只使用了400G空间。 lsblk 2、 查看并新建磁盘分区 fdisk /dev/vda 输入“n”新建一个分区&#xff0c; “Select”输入“p”表示新建一个主分区&#xff0c; “Partition number”…

openwrt docker nginx 站点搭建

应为家里一直是 openwrt 软路由&#xff0c;这样以来也不用 重新买服务器了&#xff0c;就直接在 openwrt 上面跑个 nginx就行了。把自己的一些东西就可以放上面了。资源再利用哈哈&#xff1b; 先 ssh 连接上 openwrt &#xff1a;我这里的 openwrt 最近刚更新的固件&#xff…

HNU-数据库系统-实验1-数据定义/数据操纵

数据库系统 课程实验1数据定义/数据操纵 计科210X 甘晴void 202108010XXX 目录 文章目录 数据库系统 课程实验1<br>数据定义/数据操纵实验目的实验样例实验环境实验内容1.1 数据库定义1&#xff09;实验内容与要求2&#xff09;实验重难点3&#xff09;实验基础知识①模…

fastjson1.2.24 反序列化漏洞(CVE-2017-18349)分析

FastJson在< 1.2.24 版本中存在反序列化漏洞&#xff0c;主要原因FastJson支持的两个特性&#xff1a; fastjson反序列化时&#xff0c;JSON字符串中的type字段&#xff0c;用来表明指定反序列化的目标恶意对象类。fastjson反序列化时&#xff0c;字符串时会自动调用恶意对…