[Spring] Spring5——IOC 简介(二)

目录

六、工厂 Bean(Factory)

1、普通 bean

2、工厂 bean

3、示例

七、Bean 的作用域

1、单例和多例

2、如何设置为单实例或多实例

八、Bean 的生命周期

1、生命周期

2、生命周期示例

3、Bean 的后置处理器

4、后置处理器示例

九、XML 的自动装配

1、什么是自动装配

2、byName 示例

3、byType 示例

十、外部属性文件

1、直接配置数据库信息

2、引入外部属性文件配置

十一、基于注解方式的创建对象

1、什么是注解

2、为创建对象提供的注解;

3、基于注解方式实现对象创建

 4、组件扫描的配置

十二、基于注解方式的属性注入

1、@Autowired(针对 Object 类型)

2、@Qualifier(针对 Object 类型)

3、@Resource(针对 Object 类型)

4、@Value(针对普通类型)

十三、完全注解开发


六、工厂 Bean(Factory)

Spring 有两种类型 bean,一种普通 bean,另外一种工厂 bean(FactoryBean)。

1、普通 bean

普通 bean:在配置文件中的 id 定位 bean实例,定义的 class 类型就是返回类型。

2、工厂 bean

工厂 bean:在配置文件定义 bean 类型可以和返回类型不一样

通过两个步骤即可实现工厂 bean:

  • 第一步:创建类,让这个类作为工厂 bean,实现接口 FactoryBean<T>
  • 第二步:实现接口里面的方法,在实现的方法中定义返回的 bean 类型

3、示例

建立一个 Factory 类,获取 Course 实例对象。在 xml 中 bean 类型写的是 Factory 类,但是可以返回 Course(通过继承接口 FactoryBean<T>)

(1)代码

(1-1)Factory 类:

package com.demo.factory;import com.demo.pojo.Course;
import org.springframework.beans.factory.FactoryBean;public class Factory implements FactoryBean<Course> {@Overridepublic Course getObject() throws Exception {Course course = new Course();course.setName("course01");return course;}@Overridepublic Class<?> getObjectType() {return null;}@Overridepublic boolean isSingleton() {return FactoryBean.super.isSingleton();}
}

(1-2)Course 类:

package com.demo.pojo;public class Course {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "Course{" +"name='" + name + '\'' +'}';}
}

(1-3)FactoryBean.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="CourseFactory" class="com.demo.factory.Factory"></bean></beans>

(1-4)测试代码

import com.demo.pojo.Course;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class FactoryTest {@Testpublic void test() {ApplicationContext context = new ClassPathXmlApplicationContext("FactoryBean.xml");Course course = context.getBean("CourseFactory", Course.class);System.out.println(course);}
}

(2)输出结果

七、Bean 的作用域

bean 的作用域,可以设置我们创建的 bean 实例,是单实例还是多实例。默认情况下,Spring 会将 bean 设置为单实例对象。

1、单例和多例

  • 单例就是所有的请求都用一个对象来处理,比如我们常用的service和dao层的对象通常都是单例的;
  • 多例则指每个请求用一个新的对象来处理,比如action; 

单例其实就在内存中该对象只有一个内存对应地址。无论你多少个线程访问那个对象,都是同一个地址。这样节省内存。

(1)单实例的输出结果

可以看到,两个实例的地址是一样的。说明该 bean 对象是一个单实例对象

2、如何设置为单实例或多实例

在 spring 配置文件中的 bean 标签里面有属性(scope)用于设置单实例还是多实例。

(1)scope 的属性值

  • scope = "singleton",表示单实例对象(默认值);
  • scope = "prototype",表示多实例对象;

(2)修改 scope = "prototype" 后

(3)singleton 和 prototype 区别

  • singleton 单实例,prototype 多实例;
  • scope = singleton 时,加载 spring 配置文件时候就会创建单实例对象;
  • scope = prototype 时,不是在加载 spring 配置文件时候创建对象,而是在调用 getBean() 方法时才创建多实例对象;

(4)属性值为 request 和 session

  • scope = "request" 时,创建的对象会放到 request 域中;
  • scope = "session" 时,创建的对象会放到 session 域中;

八、Bean 的生命周期

1、生命周期

Bean 对象从创建到销毁的过程。有如下 5 个步骤:

  • 通过无参构造函数创建 bean 实例;
  • 为 bean 实例的属性设置值或对其他 bean 的引用(如:外部 bean、内部 bean);(调用 set 方法)
  • 调用 bean 的初始化的方法(需要手动写出初始化的方法);
  • bean 可以使用了(对象获取到了);
  • 当容器关闭时候,调用 bean 的销毁的方法(需要手动写出销毁的方法)

2、生命周期示例

(1)代码

(1-1)Course 类

package com.demo.pojo;public class Course {private String name;public Course() {System.out.println("1.无参构造 bean 实例");}// 创建执行的初始化方法public void initFunc() {System.out.println("3.执行初始化方法");}// 创建销毁的方法public void destroyFunc() {System.out.println("5.执行销毁方法");}public String getName() {return name;}public void setName(String name) {System.out.println("2.调用 set 方法");this.name = name;}@Overridepublic String toString() {return "Course{" +"name='" + name + '\'' +'}';}
}

(1-2)LifeBean.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="course" class="com.demo.pojo.Course" init-method="initFunc" destroy-method="destroyFunc"><property name="name" value="C++从入门到入土"></property></bean></beans>

(1-3)测试代码

import com.demo.pojo.Course;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class LifeBeanTest {@Testpublic void test() {ApplicationContext context = new ClassPathXmlApplicationContext("LifeBean.xml");Course course = context.getBean("course", Course.class);System.out.println("4.getBean 对象:" + course);// 最后要手动销毁 bean 实例,Application 的子类才有 close 方法((ClassPathXmlApplicationContext)context).close();}
}

(2)输出结果

3、Bean 的后置处理器

Bean 的生命周期除了前面的 5 个步骤外,还有两个步骤,分别位于初始化方法前和初始化方法后

  • 通过无参构造函数创建 bean 实例;
  • 为 bean 实例的属性设置值或对其他 bean 的引用(如:外部 bean、内部 bean);(调用 set 方法)
  • 把 bean 实例传递给 bean 的后置处理器的方法 postProcessBeforeInitialization
  • 调用 bean 的初始化的方法(需要手动写出初始化的方法);
  • 把 bean 实例传递给 bean 的后置处理器的方法 postProcessAfterInitialization
  • bean 可以使用了(对象获取到了);
  • 当容器关闭时候,调用 bean 的销毁的方法(需要手动写出销毁的方法)

4、后置处理器示例

(1)创建类,实现接口 BeanPostProcessor

package com.demo.impl;import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;public class PostProcess implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println("初始化之前执行 postProcessBeforeInitialization");return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {System.out.println("初始化之后执行 postProcessAfterInitialization");return bean;}
}

(2)xml 配置文件,配置后置处理器

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="course" class="com.demo.pojo.Course" init-method="initFunc" destroy-method="destroyFunc"><property name="name" value="C++从入门到入土"></property></bean><!-- 配置后置处理器 --><bean id="postProcess" class="com.demo.impl.PostProcess"></bean>
</beans>

(3)输出结果

九、XML 的自动装配

1、什么是自动装配

  • 手动装配:通过 <property name="" value="">、外部/内部 Bean、等等,来给属性值赋值,就是手动装配。
  • 自动装配:根据指定的装配规则(属性名称或者属性类型),Spring 自动将匹配的属性值进行注入。

(1)bean 标签属性 autowire,配置自动装配

  • autowire = "byName",表示根据属性名称注入,要求 bean 的 id 值目标属性的属性名一致;
  • autowire = "byType",表示根据属性类型注入,也因此在 xml 中同一类型只能配置 1 个 bean; 

(2)易错点

注意目标类路径所指向的类是否与配置的类一致,比如有很多 Util 类,不论在 java 文件中导入错误的类路径,还是在 xml 中写错了类路径,都无法匹配 set() 方法。

2、byName 示例

(1)代码

(1-1)Employee 类

package com.demo.autowire;import com.demo.autowire.Department;public class Employee {private Department department;@Overridepublic String toString() {return "Employee{" +"department=" + department +'}';}public Department getDepartment() {return department;}public void setDepartment(Department department) {this.department = department;}
}

(1-2)Department 类

package com.demo.autowire;public class Department {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}}

(1-3)AutoWireBean.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="employee" class="com.demo.autowire.Employee" autowire="byName"></bean><bean id="department" class="com.demo.autowire.Department"><property name="name" value="技术部门"></property></bean></beans>

(1-4)测试代码

import com.demo.autowire.Employee;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class AutoWireBeanTest {@Testpublic void test() {ApplicationContext context = new ClassPathXmlApplicationContext("AutoWireBean.xml");Employee employee = context.getBean("employee", Employee.class);System.out.println(employee);System.out.println(employee.getDepartment().getName());}
}

(2)输出结果

3、byType 示例

将 autowire = "byName" 改成 byType 即可。但是如果使用 byType,同一个类型就只能有 1 个 bean。

在实际开发中,更多情况下使用的是注解的方法来做到自动注入。

十、外部属性文件

当一个类中的属性非常的多的时候,使用 <property> 的方式进行注入,既麻烦又不好维护。对于一些固定的属性值,我们可以统一放到某个配置文件中,再用 xml 配置文件去读取相关信息。(比如数据库连接池使用的就是 properties 文件)

下面以数据库的直接配置和引用外部文件作比较为例。

1、直接配置数据库信息

下面用一个自定义的 Druid 类,包含一个数据库连接池属性,然后通过写死配置信息的方式注入 Druid 的数据库连接池。

需要用到 druid 和 jdbc,jdbc 根据自己使用的数据库引入依赖,导 jar 包或者 maven 都可以。

(1)配置 druid 连接池

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="druid" class="com.demo.pojo.Druid"><property name="dataSource" ref="dataSource"></property></bean><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="org.postgresql.Driver"></property><property name="url" value="jdbc:postgresql://localhost:5432/MyDatabase"></property><property name="username" value="postgres"></property><property name="password" value="123456"></property></bean></beans>

(2)Druid 类(包含 DruidDataSource 属性)

package com.demo.pojo;import com.alibaba.druid.pool.DruidDataSource;public class Druid {private DruidDataSource dataSource;public void setDataSource(DruidDataSource dataSource) {this.dataSource = dataSource;}public DruidDataSource getDataSource() {return dataSource;}}

(3)测试代码

import com.alibaba.druid.pool.DruidDataSource;
import com.demo.pojo.Druid;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class DruidTest {@Testpublic void test1() {ApplicationContext context = new ClassPathXmlApplicationContext("Druid.xml");Druid druid = context.getBean("druid", Druid.class);try {DruidDataSource druidDataSource = druid.getDataSource();System.out.println(druidDataSource.getConnection());} catch (Exception e) {e.printStackTrace();}}
}

(4)输出结果

2、引入外部属性文件配置

引入外部配置文件,只需要在上面的基础上修改 xml 配置文件即可:

  • xml 文件要添加两个命名空间:util 和 context;
  • property 的 value 属性值改用 EL 表达式的形式;

(1)修改 xml 文件

<?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:util="http://www.springframework.org/schema/util"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><context:property-placeholder location="druid.properties"/><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${prop.driverClassName}"></property><property name="url" value="${prop.url}"></property><property name="username" value="${prop.username}"></property><property name="password" value="${prop.password}"></property></bean><bean id="druid" class="com.demo.pojo.Druid"><property name="dataSource" ref="dataSource"></property></bean></beans>

(2)duird.properties

prop.url = jdbc:postgresql://localhost:5432/bookmarket
prop.username = postgres
prop.password = 123456
prop.driverClassName = org.postgresql.Driver

十一、基于注解方式的创建对象

1、什么是注解

注解是代码特殊标记,格式:@注解名称(属性名称=属性值, 属性名称=属性值..)

  • 注解可以作用在类上面,方法上面,属性上面
  • 使用注解目的:简化 xml 配置,减少 xml 代码的书写

2、为创建对象提供的注解;

  • @Component
  • @Service,一般用于 Service 层
  • @Controller,一般用于 Web 层
  • @Repository,一般用于 Dao 层(持久层)

上面四个注解功能是一样的,都可以用来创建 bean 实例,只是为了区分不同的层次而用不同的名称

3、基于注解方式实现对象创建

(1)引入依赖 spring-aop-5.2.6.RELEASE

需要注意的是,此时 JDK 版本如果不兼容,就会报错:

  • 17-21,建议使用 6.0 以上的版本;
  • 8-16,建议使用 5.3 的版本,其中 16 最特殊,只能用 5.3 的版本;

(2)开启组件扫描,使得 spring 可以找到我们写的类

在 xml 配置文件中,添加 context 命名空间,然后写上:

(3)创建类,在类上面添加创建对象注解

@Component,包括另外几个注解,其中的 value 属性值,代表了 <bean> 中的 id 属性值。而如果没有显式地写出 value,那么默认值就是类名且首字母小写。

package com.demo.service.impl;import com.demo.dao.UserDao;
import com.demo.service.UserService;
import org.springframework.stereotype.Component;@Component(value = "userService")
public class UserServiceImpl implements UserService {private UserDao userDao;public UserDao getUserDao() {return userDao;}public void setUserDao(UserDao userDao) {this.userDao = userDao;}@Overridepublic void func() {System.out.println("调用 UserService 的 func");userDao.func();}
}

(4)测试代码

import com.demo.service.UserService;
import com.demo.service.impl.UserServiceImpl;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class AopBeanTest {@Testpublic void test() {ApplicationContext context = new ClassPathXmlApplicationContext("AopBean.xml");UserService userService = context.getBean("userService", UserServiceImpl.class);userService.func();}}

 4、组件扫描的配置

前面我们知道,对于一个 base-package,Spring 会扫描这个目录下的所有 class。而通过添加其他配置,可以规定哪些需要扫描、哪些不需要扫描。

(1)use-default-filters

当它的值为 false 时,表示不使用默认的 filter,而使用自己配置的 filter。

(2)如何自己配置 filter

(2-1)设置需要扫描哪些内容

  • 在组件扫描中,设置 use-default-filters="false",然后嵌套 context:include-filter。

(2-2)设置不需要扫描哪些内容,而是扫描其他的所有内容

  • 在组件扫描中,不需要设置 use-default-filters="false",直接嵌套 context:exclude-filter。
  • (因为还要扫描其他所有内容,所以不用设置 use-default-filters="false")

(3)内容如何规定

在 context:include-filter 和 context:exclude-filter 中,有两个属性配合使用:

<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>

表示目标内容就是带有注解 @Controller 的类

十二、基于注解方式的属性注入

1、@Autowired(针对 Object 类型)

@Autowired:根据属性类型进行自动装配。

其缺点在于,如果一个接口有多个实现类(比如有 DaoImpl1、DaoImpl2),那么就无法得知在 UserServiceImpl 中的属性 UserDao,具体应该被注入哪一个实现类,因此 @Autowired 只适合仅有一种实现类的情况。

(1)创建 service 和 dao 对象,在 service 和 dao 的 Impl 类中添加创建对象注解

Service 添加 @Service,Dao添加 @Repository。

(2)在 service 类添加 dao 类型属性,在属性上面使用注解

注意:不需要添加 set 方法,Spring 已经封装好 set 方法。

(3)代码

(3-1)UserDaoImpl 类

package com.demo.dao.impl;import com.demo.dao.UserDao;
import org.springframework.stereotype.Repository;@Repository
public class UserDaoImpl implements UserDao {@Overridepublic void func() {System.out.println("调用 UserDao 的 func");}
}

(3-2)UserServiceImpl 类

package com.demo.service.impl;import com.demo.dao.UserDao;
import com.demo.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 func() {System.out.println("调用 UserService 的 func");userDao.func();}
}

(3-3)AnnotationBean.xml

<?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/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><context:component-scan base-package="com.demo" use-default-filters="false"><context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/><context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/></context:component-scan></beans>

(3-4)测试代码

import com.demo.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class AnnotationBeanTest {@Testpublic void test() {ApplicationContext context = new ClassPathXmlApplicationContext("AnnotationBean.xml");UserService userService = context.getBean("userServiceImpl", UserService.class);userService.func();}}

(4)输出结果

2、@Qualifier(针对 Object 类型)

@Qualifier:根据属性名称进行自动装配,并且需要跟 @Autowired 一起使用

当有多个实现类,比如:Impl1、Impl2,这时候 @Autowired 配合上 @Qualifier(value = "Impl1"),就可以明确注入 Impl1 这个实现类。

简单来说,就是 @Autowired 确定了接口,Qualifier 确定了具体的实现类。

(1)在 AnnotationBean.xml 和 测试代码 不变的情况下,修改以下内容

(1-1)UserDaoImpl1 类

package com.demo.dao.impl;import com.demo.dao.UserDao;
import org.springframework.stereotype.Repository;@Repository(value = "userDaoImpl1")
public class UserDaoImpl1 implements UserDao {@Overridepublic void func() {System.out.println("调用 UserDaoImpl1 的 func");}
}

(1-2)UserDaoImpl2 类

package com.demo.dao.impl;import com.demo.dao.UserDao;
import org.springframework.stereotype.Repository;@Repository(value = "userDaoImpl2")
public class UserDaoImpl2 implements UserDao {@Overridepublic void func() {System.out.println("调用 UserDaoImpl2 的 func");}
}

(1-3)UserServiceImpl 类

package com.demo.service.impl;import com.demo.dao.UserDao;
import com.demo.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 {@Autowired@Qualifier(value = "userDaoImpl2")private UserDao userDao;@Overridepublic void func() {System.out.println("调用 UserService 的 func");userDao.func();}
}

(2)输出结果

3、@Resource(针对 Object 类型)

@Resource:可以根据类型注入,也可以根据名称注入。

  • @Resource:根据类型注入;
  • @Resource(name = "userDaoImpl1"):根据名称注入

需要注意的是,@Resource 是 javax 提供的注解,不是 Spring 官方提供的,因此建议还是使用 @Autowired 和 @Qualifier。

(1)修改 UserServiceImpl 类

package com.demo.service.impl;import com.demo.dao.UserDao;
import com.demo.service.UserService;
import org.springframework.stereotype.Service;import javax.annotation.Resource;@Service
public class UserServiceImpl implements UserService {@Resource(name = "userDaoImpl2")private UserDao userDao;@Overridepublic void func() {System.out.println("调用 UserService 的 func");userDao.func();}
}

(2)输出结果

4、@Value(针对普通类型)

@Value:注入普通类型属性。

  • @Value(value = "MyValue"),表示给属性注入值为 MyValue。

十三、完全注解开发

不需要使用 xml 文件去配置,仅使用注解,就可以实现创建对象和属性注入。

(1)创建配置类,替代 xml 配置文件:

package com.demo.config;import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;@Configuration // 作为配置类,代替 xml 配置文件
@ComponentScan(basePackages = {"com.demo"})
public class SpringConfig {}

(2)测试代码

import com.demo.config.SpringConfig;
import com.demo.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class AnnotationConfigTest {@Testpublic void test() {ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);UserService userService = context.getBean("userServiceImpl", UserService.class);userService.func();}}

(3)输出结果

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

c# 委托 事件 lambda表达式

委托 C/C中的函数指针实例&#xff1a; typedef int (*Calc)(int a, int b); //这里必须加括号 int Add(int a, int b) {return a b; } int Sub(int a, int b) {return a - b; } int main() {int x 100;int y 200;int z 0;Calc funcPoint1 &Add;Calc funcPoint2 &am…

全国排名前三的直播公司无锋科技入驻天府蜂巢成都直播产业基地

最近&#xff0c;全国排名前三的直播公司——无锋科技&#xff0c;正式宣布入驻位于成都的天府蜂巢直播产业基地&#xff0c;这一消息引起了业内人士的高度关注。成都直播产业基地一直是中国直播产业的重要地标之一&#xff0c;其强大的技术和资源优势为众多直播公司提供了广阔…

26 docker前后端部署

[参考博客]((257条消息) DockerNginx部署前后端分离项目(SpringBootVue)的详细教程_在docker中安装nginx实现前后端分离_这里是杨杨吖的博客-CSDN博客) (DockerNginx部署前后端分离项目(SpringBootVue)) 安装docker # 1、yum 包更新到最新 yum update # 2、安装需要的软件包…

csgo盲盒支付接口如何申请?

csgo盲盒支付接口如何申请&#xff1f;个人认为没什么特别难懂的&#xff01; 第一点&#xff1a;确定网站的基本功能&#xff01;每个网站的玩法大概都是一样的&#xff0c;无非是拆箱盲盒&#xff0c;ROLL房间、决斗、货物、生存和更换合同&#xff0c;然后有积分购物中心&am…

vue 实现数字验证码功能

需求&#xff1a;写了一个 手机发送验证码后 输入固定验证码的功能 封装成一个组件,如下: <template><div class"conts"><div class"box"><div class"code_list"><div :class"[ code_item, hideIndex 0 ? co…

Flutter笔记:滚动之-无限滚动与动态加载的实现

Flutter笔记 无限滚动与动态加载的实现 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://blog.csdn.net/qq_28550263/article/details/133342307 本文还…

分享10个必备的VS Code技巧和窍门,提高你的开发效率

目录 前言 1. 时间线视图&#xff1a;本地源代码控制 2. 自动保存&#xff1a;不再需要按Ctrl S 3. 使用命令面板进行任何操作 4、快速转到文件 5. 快速跳转指定行 6. 快速删除该行 7. 享受使用流畅的光标进行打字 8. 快速格式化代码 9. 使用多光标编辑功能节省时间…

【智能家居项目】裸机版本——项目介绍 | 输入子系统(按键) | 单元测试

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《智能家居项目》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 目录 &#x1f3c0;项目简介&#x1f3c0;输入子系统(按键)⚽应用层⚽设备层⚽ 内核层抽象层⚽…

flink选择slot

flink选择slot 在这个类里修改 package org.apache.flink.runtime.resourcemanager.slotmanager.SlotManagerImpl; findMatchingSlot(resourceProfile)&#xff1a;找到满足要求的slot&#xff08;负责从哪个taskmanager中获取slot&#xff09;对应上图第8&#xff0c;9&…

IDEA 使用

目录 Git.gitignore 不上传取消idea自动 add file to git撤销commit的内容本地已经有一个开发完成的项目&#xff0c;这个时候想要上传到仓库中 Git .gitignore 不上传 在项目根目录下创建 .gitignore 文件夹&#xff0c;并添加内容&#xff1a; .gitignore取消idea自动 add…

【OpenCV-Torch-dlib-ubuntu】Vm虚拟机linux环境摄像头调用方法与dilb模型探究

前言 随着金秋时节的来临&#xff0c;国庆和中秋的双重喜庆汇聚成一片温暖的节日氛围。在这个美好的时刻&#xff0c;我们有幸共同迎来一次长达8天的假期&#xff0c;为心灵充电&#xff0c;为身体放松&#xff0c;为未来充实自己。今年的国庆不仅仅是家国团聚的时刻&#xff…

STL容器

C STL STL实现原理及其实现 STL&#xff08;Standard Template Library&#xff0c;标准模板库&#xff09;&#xff0c;提供了六大组件&#xff0c;可以相互之间组合套用&#xff0c;这六大组件分别是&#xff1a;容器&#xff08;Containers&#xff09;&#xff0c;算法&a…

1.6.C++项目:仿muduo库实现并发服务器之channel模块的设计

项目完整版在&#xff1a; 文章目录 一、channel模块&#xff1a;事件管理Channel类实现二、提供的功能三、实现思想&#xff08;一&#xff09;功能&#xff08;二&#xff09;意义&#xff08;三&#xff09;功能设计 四、代码&#xff08;一&#xff09;框架&#xff08;二…

凉鞋的 Godot 笔记 103. 检视器 :节点的微观编辑和查看

在上一篇&#xff0c;笔者简单介绍了场景与节点的增删改查&#xff0c;如下所示: 在这一篇&#xff0c;我们接着往下学习。 我们知道在场景窗口&#xff0c;可以对节点进行增删改查。 在 Godot 引擎使用过程中&#xff0c;场景窗口的使用频率是非常高的。 但是场景窗口只能编…

macOS Sonoma 14 正式版(23A344)发布,附黑/白苹果镜像下载地址

系统介绍&#xff08;系统下载地址&#xff1a;http://www.imacosx.cn/115300.html&#xff09; 黑果魏叔9 月 27日消息&#xff0c;苹果今日向 Mac 电脑用户推送了 macOS Sonoma 14 正式版&#xff08;23A344&#xff09;。 macOS 14正式版系统发布&#xff1a;全新功能与改…

ChatGPT Prompting开发实战(十二)

一、如何开发prompts实现个性化的对话方式 通过设置“system”和“user”等roles&#xff0c;可以实现个性化的对话方式&#xff0c;并且可以结合参数“temperature”的设定来差异化LLM的输出内容。在此基础上&#xff0c;通过构建一个餐馆订餐对话机器人来具体演示对话过程。…

Arcgis克里金插值报错:ERROR 010079: 无法估算半变异函数。 执行(Kriging)失败。

Arcgis克里金插值报错&#xff1a;ERROR 010079: 无法估算半变异函数。 执行(Kriging)失败。 问题描述&#xff1a; 原因&#xff1a; shape文件的问题&#xff0c;此图可以看出&#xff0c;待插值的点有好几个都超出了地理范围之外&#xff0c;这个不知道是坐标系配准的问…

JAVA设计模式-代理模式

一.概念 在软件开发中&#xff0c;也有一种设计模式可以提供与代购网站类似的功能。由于某些原因&#xff0c;客户端不想或不能直接访问一个对象&#xff0c;此时可以通过一个称之为“代理”的第三者来实现间接访问&#xff0c;该方案对应的设计模式被称为代理模式。 ​ 代理模…

数据结构——堆(C语言)

本篇会解决一下几个问题&#xff1a; 1.堆是什么&#xff1f; 2.如何形成一个堆&#xff1f; 3.堆的应用场景 堆是什么&#xff1f; 堆总是一颗完全二叉树堆的某个节点总是不大于或不小于父亲节点 如图&#xff0c;在小堆中&#xff0c;父亲节点总是小于孩子节点的。 如图&a…

GO 比较两个对象是否相同

本文主要是来聊一聊关于 Golang 中的深度比较 DeepEqual 因为最近发现身边的小伙伴写 2 个或者多个 map 比较的时候&#xff0c;都是自己去实现去比较每一个结构&#xff0c;每一个节点的 key 和 value 是不是都相等&#xff0c;且根据不同的数据结构&#xff0c;都要去实现一…