当前位置: 首页 > news >正文

《Spring系列》第3章 基于注解管理Bean

基于注解方式管理Bean

1.通过注解管理Bean

1) 基础注解

@Component
@Service
@Controller
@Repository

2) 基于XML的注解扫描

a> 引入依赖

spring-aop-5.1.5.RELEASE.jar

b> 开启组件扫描

最简单的开启注解
<context:component-scan base-package="com.jianan" />

默认是4个注解都可以创建对象,但是我们也可以自定义,可以指定哪些组件,也可以排除哪些组件

可以详细设置一些内容
<!--use-default-filters 设置是否使用默认的创建注解-->
<context:component-scan base-package="com.jianan" use-default-filters="false"><!--规定哪些注解 不能 创建对象-->
<!-- <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Component"/>--><!--规定哪些注解 可以 创建对象--><context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

c> 在类上面添加注解创建注解

3) 基于注解开启注解扫描

@Configuration
// 开启注解扫描
@ComponentScan(basePackages = {"com.atguigu"})
public class SpringConfig { 
}

4) @ComponentScan

上面介绍到,@ComponentScan用于开始注解扫描,那么看一下该注解的源码:

1.@ComponentScan value指定要扫描的包
2.excludeFilters = Filter[] 指定扫描排除的组件
3.includeFilters = Filter[] 指定包含哪些组件
4.Filter 默认扫描注解类型,也可以自定义
5.当指定扫描组件的时候需要禁用默认扫描组件 useDefaultFilters = false
6.@ComponentScan注解类上有@Repeatable注解,代表是可重复注解
7.我们也可以通过ComponentScans[]来些多个注解扫描方式

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Repeatable(ComponentScans.class)// 这个的 @Repeatable代表是一个重复注解,即可以重复使用
public @interface ComponentScan {@AliasFor("value")String[] basePackages() default {};// 是否使用默认的4个注解boolean useDefaultFilters() default true;// 指定包含哪些组件ComponentScan.Filter[] includeFilters() default {};// 指定扫描排除的组件ComponentScan.Filter[] excludeFilters() default {};// 省略一些代码...
}

使用示例

@Configuration
// @ComponentScan value指定要扫描的包
// excludeFilters = Filter[] 指定扫描排除的组件
@ComponentScan(value = "com.jianan", excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class, Service.class})
})
// includeFilters = Filter[] 指定包含哪些组件
// 当指定扫描组件的时候需要禁用默认的扫描组件 useDefaultFilters = false
@ComponentScan(value = "com.jianan", includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class, Service.class})
},useDefaultFilters = false)
public class MainConfig {
}

FilterType

@ComponentScan,我们可以指定过滤的类型,按照注解、类等扫描,也可以按照自定义的扫描

public enum FilterType {ANNOTATION,// 按照注解扫描ASSIGNABLE_TYPE,// 按照给定的类型扫描ASPECTJ, // 使用ASPECTJ表达式REGEX, // 使用正则指定CUSTOM; // 使用自定义表达式private FilterType() {}
}

自定义过滤类型

1)创建类实现TypeFilter接口

public class MyTypeFilter implements TypeFilter {/**** @param metadataReader 读取到当前正在扫描的类的信息* @param metadataReaderFactory 可以获取到其它任何类的信息* @return* @throws IOException*/@Overridepublic boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {// 获取当前类注解的信息AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();// 获取当前正在扫描的类的类信息ClassMetadata classMetadata = metadataReader.getClassMetadata();// 获取当前类资源(类的路径)Resource resource = metadataReader.getResource();String className = classMetadata.getClassName();System.out.println("----->" + className);return false;}
}

2)配置类设置

@Configuration
@ComponentScan(value = "com.jianan", includeFilters = {@ComponentScan.Filter(type = FilterType.CUSTOM, classes = {MyTypeFilter.class})
},useDefaultFilters = false)
public class MainConfig {
}

3)测试

	public static void main(String[] args) {// 通过注解配置类AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);// 获取Person类在IOC容器中名字String[] names = applicationContext.getBeanDefinitionNames();for (String name : names) {System.out.println(name);//person1}}

5) @Configuration

上面可以注解 + 注解扫描来创建对象,那么其创建的都是通过调用无参构造方法,那么我们想在创建的时候,同时注入属性,可以通过

@Configuration //作为配置类,替代 xml 配置文件
@ComponentScan(basePackages = {"com.atguigu"})
public class SpringConfig { @Beanpublic User user(){User user = new User();// 可以在这里设置对象属性user.setId(1);return user;        }
}

该注解存在2个属性:

  1. value()属性很好理解,对应@Component注解的value

  2. proxyBeanMethods() 从注释上看到是从5.2开始推出的,意思就是代理Bean的方法,当属性值不同时,代表两种模式

    Full(proxyBeanMethods = true)、全量模式【保证每个@Bean方法被调用多少次返回的组件都是单实例的】

    Lite(proxyBeanMethods = false)、增量模式【每个@Bean方法被调用多少次返回的组件都是新创建的】

    组件依赖必须使用Full模式。也就是在一个配置类里面,一个组件的注册依赖了另外一个类,此时必须保证组件是单实例,也就是在获取的时候需要先检查是否已经创建了

    其他默认是Lite模式,这样容器在启动的时候就没有必要检测是否已经存在该实例,可以加快容器启动速度

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component // 这里有@Component 代表配置类里面的@Bean会注册组件,同时配置类本身也是组件
public @interface Configuration {// 该注解代表将value值映射到@Component@AliasFor(annotation = Component.class)String value() default "";/*** Specify whether {@code @Bean} methods should get proxied in order to enforce* bean lifecycle behavior, e.g. to return shared singleton bean instances even* in case of direct {@code @Bean} method calls in user code. This feature* requires method interception, implemented through a runtime-generated CGLIB* subclass which comes with limitations such as the configuration class and* its methods not being allowed to declare {@code final}.* <p>The default is {@code true}, allowing for 'inter-bean references' via direct* method calls within the configuration class as well as for external calls to* this configuration's {@code @Bean} methods, e.g. from another configuration class.* If this is not needed since each of this particular configuration's {@code @Bean}* methods is self-contained and designed as a plain factory method for container use,* switch this flag to {@code false} in order to avoid CGLIB subclass processing.* <p>Turning off bean method interception effectively processes {@code @Bean}* methods individually like when declared on non-{@code @Configuration} classes,* a.k.a. "@Bean Lite Mode" (see {@link Bean @Bean's javadoc}). It is therefore* behaviorally equivalent to removing the {@code @Configuration} stereotype.* @since 5.2*/boolean proxyBeanMethods() default true;
}

proxyBeanMethods 测试

@SpringBootApplication
public class BootApplication {public static void main(String[] args) {// 1.获取容器SpringApplication application = new SpringApplication(BootApplication.class);// 2.容器启动,返回启动启动后的IOC容器ConfigurableApplicationContext context = application.run(args);// 获取到配置类,因为配置类也是组件UserConfig userConfig = context.getBean(UserConfig.class);// 调用方法获取组件User user1 = userConfig.user();User user2 = userConfig.user();// 根据proxyBeanMethods配置的不同来判断 多次创建的组件是否为单实例System.out.println(user1 == user2);}}

proxyBeanMethods 原理

该属性的实现原理,根据这个属性名就猜到肯定是用到了代理,

如果proxyBeanMethods = true,那么肯定会经过代理,中间会先尝试从容器中获取Bean,获取到直接返回,否则就是第一次创建,这样就保证了单实例

如果proxyBeanMethods = false,那么就不用代理了,直接最简单调用依次创建一个

使用示例

在Spring的声明式事务中,@EnableTransactionManagement注解会向容器中导入两个类,AutoProxyRegistrarProxyTransactionManagementConfiguration

其中引入的第2个类就用到了proxyBeanMethods ,这里设置的是false,因为事务注解@Transaction是加在方法上的,这样每个方法的注解属性就可能不一样,所以就不能设置单例的

// 因为每个方法可能需要回滚的方式不同,所以这里使用的false
@Configuration(proxyBeanMethods = false)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)@Role(BeanDefinition.ROLE_INFRASTRUCTURE)public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor(TransactionAttributeSource transactionAttributeSource, TransactionInterceptor transactionInterceptor) {BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();advisor.setTransactionAttributeSource(transactionAttributeSource);advisor.setAdvice(transactionInterceptor);if (this.enableTx != null) {advisor.setOrder(this.enableTx.<Integer>getNumber("order"));}return advisor;}@Bean@Role(BeanDefinition.ROLE_INFRASTRUCTURE)public TransactionAttributeSource transactionAttributeSource() {return new AnnotationTransactionAttributeSource();}@Bean@Role(BeanDefinition.ROLE_INFRASTRUCTURE)public TransactionInterceptor transactionInterceptor(TransactionAttributeSource transactionAttributeSource) {TransactionInterceptor interceptor = new TransactionInterceptor();interceptor.setTransactionAttributeSource(transactionAttributeSource);if (this.txManager != null) {interceptor.setTransactionManager(this.txManager);}return interceptor;}}

6) @Bean

@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Bean {@AliasFor("name")String[] value() default {};@AliasFor("value")String[] name() default {};/** @deprecated */@DeprecatedAutowire autowire() default Autowire.NO;boolean autowireCandidate() default true;// 初始化方法String initMethod() default "";// 销毁方法String destroyMethod() default "(inferred)";
}

2.Bean注解

@Autowired

1.  该注解属于`org.springframework.beans.factory.annotation`,也就是它是Spring框架提供的
2.  默认优先按照类型去容器中找对应的组件 application.getBean(Car.class)
3.  如果找到多个相同类型的组件,再将属性的名称作为组件的id去容器中查找
4.  @Qualifier() 使用该注解指定需要装配的组件id 而不是使用属性名
5.  自动装配一定要将属性赋值好,没有就报错
6.  @Autowired(required = false) 代表找到类型赋值最好,找不到就报错
7.  @Primary 当我们需要获取的对象存在多个时,我们可以通过该注解标注首选,代表哪个的优先级最高
public @interface Autowired {// 设置是否允许Null值boolean required() default true;
}
@Component
@Primary //代表当获取的对象存在多个时,可以通过注解标注首选
public class User {
}

@Qualifier

如果我们要使用名称装备,@Autowired可以结合@Qualifier注解进行使用
例如: @Autowired
@Qualifier(“life”)//按照byName来自动注入
private Life life;

@Resource

  1. 该注解属于javax.annotation,它是JDK提供的
  2. 如果没有指定name属性,当注解写在字段上时,默认取字段名进行安装名称查找
  3. 如果name属性一旦指定,就只会按照名称进行装配

@Value

  1. 基本数据
  2. 可以写SpEL表达式; #{}
  3. 可以写 ${} 取出配置文件中的值
@Value("张三")
private String name;@Value("#{20-2}")
private Integer age;@Value("${spring.sex}")
private String sex;

@PropertySource

加载配置文件

@Configuration
@PropertySource(value = {"classpath:/jdbc.properties"})
public class UserConfig {
}

@Scope 作用域

默认通过@Bean注入IOC容器的对象都是单实例的,但是可以通过@Scope注解来修改
@Scope(scopeName = “prototype”) 代表多实例, 获取对象的时候才会创建
@Scope(scopeName = “singleton”) 代表单实例, IOC容器启动的时候就会创建对象

@Configuration
public class MaiConfig2 {@Scope(scopeName = "prototype")@Bean(name = "person2")public Person person() {Person person = new Person();person.setName("王五");person.setAge(30);return person;}
}

@Lazy 懒加载

单实例bean:默认在容器启动的时候创建对象
懒加载: 容器启动不创建对象,第一次使用(获取)Bean创建对象,并初始化

	@Scope(scopeName = "singleton")@Lazy@Bean(name = "person2")public Person person() {System.out.println("person 添加到 IOC容器------");Person person = new Person();person.setName("王五");person.setAge(30);return person;}

@Conditional

按照一定的条件进行判断,满足条件给容器中注册,该注解可以添加到方法 / 类 中,此注解需要的值是实现Condition接口的类
1.当添加到@Bean上代表满足指定条件才注册该对象
2.当添加到类上代表满足条件才注册所有的bean

@Import

给容器中注册组件方式:

  1. 包扫描+组件标志注册(@Controller/@Service/@Repository/@Component) 【自己写的】
  2. @Bean【导入的第三方包里面的组件】
  3. @Import【快速给容器中导入一个组件】
    1. @Import(要导入到容器中的组件);容器就会自动注册这个组件,组件名默认是全类名
    2. ImportSelector 返回需要导入的组件的全类名数组
    3. ImportBeanDefinitionRegistrar
  4. 使用Spring提供的FactoryBean(工厂Bean)
    1. 默认获取到的是工程bean调用getObject创建的对象
    2. 要获取对象Bean本身,我们需要给id前面加一个&

生命周期 的4种方式

通过@Bean指定生命周期

@Configuration
public class MainConfigOfLifeCycle {@Bean(initMethod = "init",destroyMethod = "destory")public Car car(){return new Car();}
}

通过接口

通过调用 InitializingBean, DisposableBean 接口来分别实现创建和销毁方法

public class Cat implements InitializingBean, DisposableBean {public Cat(){System.out.println("Cat 执行初始化方法");}@Overridepublic void destroy() throws Exception {System.out.println("执行 Cat destroy方法");}@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("执行 Cat afterPropertiesSet方法");}
}

通过注解

@PostConstruct 在bean创建完成并且属性赋值完成,来执行初始化方法
@PerDestroy 在容器销毁bean之前通过我们进行清理工作

通过后置处理器 BeanPostProcessor

这个在上面已经介绍了接口的使用

@Profile

Spring为我们提供的可以根据当前环境,动态的激活和切换一系列组件的功能

  1. 加了环境标识的bean 只有这个环境被激活的时候,才能注入这个组件,默认是default环境
  2. 写在配置类上,只有是指定的环境的时候,整个配置类里面的所有配置才能开始生效
  3. 没有表示环境表示的bean 在任何环境下都是加载的

激活配置环境的方式:

  1. 使用命令行动态参数 -Dspring.profiles.active=dev
  2. 使用代码的方式

@AliasFor

该注解有2个功能:

  1. 给属性提供别名
  2. 继承注解

注意点:

1.属于隐性别名组中的每一个属性必须使用@AliasFor进行注释,并且attribute必须引用相同元注解中的同一个属性
2.别名化的属性必须声明相同的返回类型
3.别名化的属性必须定义默认值
4.别名化的属性必须声明相同的默认值
5.注解必须引用合适的元注解
6.被引用的元注解必须放置在声明了@AliasFor的注解上

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Documented
public @interface AliasFor {// 属性的别名@AliasFor("attribute")String value() default "";@AliasFor("value")String attribute() default "";// Class<? extends Annotation> annotation() default Annotation.class;
}

RequestMapping示例

// 两个属性互为别名,代表设置哪个都可以
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {String name() default "";@AliasFor("path")String[] value() default {};@AliasFor("value")String[] path() default {};RequestMethod[] method() default {};String[] params() default {};String[] headers() default {};String[] consumes() default {};String[] produces() default {};}

注解继承

像我们使用的@Controller@Service@Repository都是继承的@Component

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {// 继承注解@AliasFor(annotation = Component.class)String value() default "";
}

@SpringBootApplication是一个组合注解,里面的属性也继承到每个子注解中

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {@AliasFor(annotation = EnableAutoConfiguration.class)Class<?>[] exclude() default {};@AliasFor(annotation = EnableAutoConfiguration.class)String[] excludeName() default {};@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")String[] scanBasePackages() default {};@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")Class<?>[] scanBasePackageClasses() default {};@AliasFor(annotation = ComponentScan.class, attribute = "nameGenerator")Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;@AliasFor(annotation = Configuration.class)boolean proxyBeanMethods() default true;}

@ImportResource

如果项目使用的XML来注册Bean,那么可以使用该注解来导入xml文件到配置类,然后就会解析当前xml文件

@Configuration(proxyBeanMethods = false)
@ImportResource(locations = "classpath:spring.xml") // 自动将xml文件注入到配置类
public class UserConfig {@Beanpublic User user() {return new User();}
}

@ConfigurationProperties

实现配置绑定有两种方式

  1. 通过 @Component + @ConfigurationProperties
  2. 通过 @EnableConfigurationProperties + @ConfigurationProperties

两种方式实现的功能一样,只不过是组件的注入地方,第2种方式多应用于第三方jar包,因为我们导入的jar包上面可能没有添加@Component,同时jar包又不可以修改,所以通过@EnableConfigurationProperties来添加

总结下来 @EnableConfigurationProperties这个注解有两个功能,第1就是注入该组件,第2实现配置绑定

@ConfigurationProperties

@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface ConfigurationProperties {// 前缀@AliasFor("prefix")String value() default "";@AliasFor("value")String prefix() default "";boolean ignoreInvalidFields() default false;boolean ignoreUnknownFields() default true;}

方式一

第1步:需要使用Spring的功能,必须注入到容器中

地2步:通过@ConfigurationProperties注解

@Data
@Component
@ConfigurationProperties(prefix = "jia")
public class User {private String id;private String name;}

方式二

第1步:添加@ConfigurationProperties注解

@Data
@ConfigurationProperties(prefix = "jia")
public class User {private String id;private String name;}

第2步:配置添加@EnableConfigurationProperties

@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(User.class)
public class UserConfig {}

相关文章:

《Spring系列》第3章 基于注解管理Bean

基于注解方式管理Bean 1.通过注解管理Bean 1) 基础注解 Component Service Controller Repository 2) 基于XML的注解扫描 a> 引入依赖 spring-aop-5.1.5.RELEASE.jarb> 开启组件扫描 最简单的开启注解 <context:component-scan base-package"com.jianan&q…...

【Redis】十大数据类型(下篇)

文章目录redis位图(bitmap) --- 底子还是string基本命令图示setbit key offset value setbit 键 偏移位 只能零或者1getbit key offset 查看获取字符串长度 strlen统计key中包含1的个数 bitcount keybitop 统计两个比特key是否都为1技术落地&#xff1a;打卡签到&#xff0c;频…...

【第十一届“泰迪杯”数据挖掘挑战赛】B题产品订单的数据分析与需求预测“解题思路“”以及“代码分享”

【第十一届泰迪杯B题产品订单的数据分析与需求预测产品订单的数据分析与需求预测 】第一大问代码分享&#xff08;后续更新LSTMinformer多元预测多变量模型&#xff09; PS: 代码全写有注释&#xff0c;通俗易懂&#xff0c;包看懂&#xff01;&#xff01;&#xff01;&…...

Python入门到高级【第一章】

预计更新第一章. Python 简介 Python 简介和历史Python 特点和优势安装 Python 第二章. 变量和数据类型 变量和标识符基本数据类型&#xff1a;数字、字符串、布尔值等字符串操作列表、元组和字典 第三章. 控制语句和函数 分支结构&#xff1a;if/else 语句循环结构&#…...

【泰凌微TLSR8258 zigbee】OTA升级操作方法

目录 程序启动模式多地址启动模式Bootloader 启动模式多地址启动模式 Flash 分布Bootloader 启动模式Flash分布模式OTA升级OTA初始化OTA ServerOTA ClientOTA升级固件生成程序启动模式 在介绍OTA升级操作方法前,我们先介绍一下程序的启动模式,以及不同启动模式的优缺点。 多…...

网络基础设施监控

在过去的几十年里&#xff0c;网络基础设施在规模和功能方面都变得复杂起来。不断增长的业务需求和不断增长的技术能力推动了这种快速增长&#xff0c;监控网络基础设施以确保其最佳性能和最大效率已成为任何希望成为行业领跑者的组织不可或缺的优先事项。 什么是网络基础设施…...

OPNET Modeler 例程——创建一个包交换网络

文章目录一、例程简介二、创建新的包格式三、创建新的链路模型四、创建中心交换节点模型五、创建中心交换节点的进程模型六、创建周边节点模型七、创建周边节点进程模块八、创建网络模型九、收集统计量十、配置并仿真总结一、例程简介 本例程将仿真一个简单的包交换网络&#…...

JSON 基础结构

什么是JSON JSON&#xff0c;说白了就是JavaScript用来处理数据的一种格式&#xff0c;这种格式非常简单易用。 JSON&#xff0c;大部分都是用来处理JavaScript和web服务器端之间的数据交换&#xff0c;把后台web服务器的数据传递到前台&#xff0c;然后使用JavaScript进行处…...

雷达基础知识

雷达频率划分 以下是按照频率和波长划分雷达频段的表格&#xff1a; 波段名称频率范围&#xff08;GHz&#xff09;波长范围&#xff08;cm&#xff09;应用领域VHF0.03 - 0.3100 - 10气象雷达、空管雷达、航空雷达UHF0.3 - 3100 - 10航空雷达、海上雷达、地面雷达、火控雷达…...

【二阶锥规划】考虑气电联合需求响应的气电综合能源配网系统协调优化运行【IEEE33节点】(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

qt 编译器 调试器

电脑版本&#xff1a;win10 64位 qt版本&#xff1a;based on Qt 5.14.0&#xff08;msvc 2017&#xff0c; 32位&#xff09; Qt Creator 4.11.0 qt安装包&#xff1a;qt-opensource-windows-x86-5.9.9.exe 安装过程一路next&#xff0c;安装完成后&#xff0c;默认使用的…...

低代码平台助力AIGC:让人工智能技术更加普及和高效

今年人工智能的风是吹了一波又一波&#xff0c;从ChatGPT到文心一言&#xff0c;短短四个多月的时间&#xff0c;GPT完成了从3.0、3.5到4.0的推新发布&#xff0c;一步步刷新了民众对于目前人工智能技术发展的认知底线&#xff0c;让人们直观地感受到了人工智能技术的蓬勃发展。…...

Qt中Model/View结构

Qt中Model/View结构 Model/View框架的核心思想是模型&#xff08;数据&#xff09;与视图&#xff08;显示&#xff09;相分离&#xff0c;模型对外提供标准接口存取数据&#xff0c;不关心数据如何显示&#xff0c;视图自定义数据的显示方式&#xff0c;不关心数据如何组织存…...

中纬ZOOM35全站仪参数和使用说明书

免棱镜测程采用全新EDM&#xff0c;明显提升测距功能。极细可见激光免棱镜测程最高可达1000m&#xff0c;同等测程下无棱镜精度较高。 绝对编码度盘中纬静态条码式码盘测角&#xff0c;开机无需初始化&#xff0c;利用同样技术的徕卡全站仪&#xff0c;测角精度可高达0.5&#…...

【Note5】网络,并发/IO,内存,linux/vi命令,正则,Hash,iNode,文件查找与读取,linux启动/构建

文章目录1.局域网&#xff1a;CSMA/CD2.互联网&#xff1a;ARP&#xff0c;DHCP&#xff0c;NAT3.TCP协议&#xff1a;telnet&#xff0c;tcpdump&#xff0c;syn/accept队列4.HTTPS协议&#xff1a;摘要&#xff08;sha、md5、crc&#xff09;。win对文件进行MD5校验用自带的c…...

华为MRS_HADOOP集群 beeline使用操作

背景 由于项目测试需要&#xff0c;计划在华为hadoop集群hive上创建大量表&#xff0c;并且每表植入10w数据&#xff0c;之前分享过如何快速构造hive大表&#xff0c;感兴趣的可以去找一下。本次是想要快速构造多表并载入一些数据。 因为之前同事在构造相关测试数据时由于创建…...

PCB模块化设计10——PCI-E高速PCB布局布线设计规范

目录PCB模块化设计10——PCI-E高速PCB布局布线设计规范1、PCI-E管脚定义2、PCI-E叠层和参考平面3、 PCB设计指南1、阻抗要求2、线宽线距3、长度匹配4、走线弯曲角度5、测试点、过孔、焊盘6、AC去耦电容放置方法7、金手指和连接器的注意事项8、其他的注意事项PCB模块化设计10——…...

Java简介

Java简介 Java是一种面向对象的编程语言&#xff0c;由Sun Microsystems于1995年发布。Java设计的初衷是为了开发可移植、高性能的应用程序。Java代码可以在不同的操作系统上运行&#xff0c;包括Windows、Linux、Mac等。 Java是一种广泛使用的编程语言&#xff0c;用于开发各…...

python框架有哪些,常用的python框架代码

Python的应用已经相当广泛了&#xff0c;可以做很多事情&#xff0c;而 Python本身就是一个应用程序&#xff0c;我们也可以说 Python是一个高级语言。由于 Python有很多包&#xff0c;所以我们不能把所有的 Python包都了解一下&#xff0c;也不能把所有的包都读一遍&#xff0…...

jsp设计简单的购物车应用案例

代码解释 <%request.setCharacterEncoding("UTF-8");if (request.getParameter("c1")!null)session.setAttribute("s1",request.getParameter("c1"));if (request.getParameter("c2")!null)session.setAttribute("…...

VueX是什么?好处?何时使用?

VueX相关1、VueX是什么&#xff1f;2、使用VueX统一管理状态的好处3、什么样的数据适合存储到Vuex中&#xff1f;1、VueX是什么&#xff1f; VueX是实现组件全局状态&#xff08;数据&#xff09;管理的一种机制&#xff0c;可以方便的实现组件之间数据的共享。 如果没有VueX…...

第2章 封装组件初级篇(上)

1.环境搭建&#xff0c;在 vite 脚手架基础上集成 typescript 和 element-plus https://cn.vitejs.dev/guide/ 以下是开发过程中过使用到的包和版本号&#xff1a;package.json {"name": "m-components","version": "0.0.0","…...

uniapp image标签图片跑偏终极解决办法

目录uniapp image 的mode常用属性aspectFit 缩放显示图片全部aspectFill 缩放填满容器&#xff0c;但是图片可能显示不全widthFix 以宽度为基准&#xff0c;等比缩放长heightFix 以高度为基准&#xff0c;等比缩放宽uniapp image 的mode常用属性 uniapp当中&#xff0c;在imag…...

SpringMVC的响应处理

文章目录一、传统同步业务数据响应1. 请求资源转发2. 请求资源重定向3. 响应模型数据4. 直接回写数据二、前后端分离异步业务数据响应一、传统同步业务数据响应 Spring响应数据给客户端&#xff0c;主要分为两大部分&#xff1a; ⚫ 传统同步方式&#xff1a;准备好模型数据&am…...

静态词向量预训练模型

1、神经网络语言模型从语言模型的角度来看&#xff0c;N 元语言模型存在明显的缺点。首先&#xff0c;模型容易受到数据稀疏的影响&#xff0c;一般需要对模型进行平滑处理&#xff1b;其次&#xff0c;无法对长度超过 N 的上下文依赖关系进行建模。神经网络语言模型 (Neural N…...

永久免费CRM怎么选?有什么好用的功能?

在当今商业环境下&#xff0c;企业经营者们都希望能够找到一种方法来提高自己的生产力和盈利能力。一种非常有效的方法就是实现客户关系管理&#xff08;CRM&#xff09;。然而&#xff0c;由于很多传统的CRM解决方案价格昂贵&#xff0c;小企业和创业公司很难承担。那么&#…...

leetcode重点题目分类别记录(二)基本算法:二分,位图,回溯,动态规划,图论基础,拓扑排序

layout: post title: leetcode重点题目分类别记录&#xff08;二&#xff09;基本算法&#xff1a;二分&#xff0c;位图&#xff0c;回溯&#xff0c;动态规划&#xff0c;拓扑排序 description: leetcode重点题目分类别记录&#xff08;二&#xff09;基本算法&#xff1a;二…...

【JaveEE】多线程之定时器(Timer)

目录 1.定时器的定义 2.标准库中的定时器 2.1构造方法 2.2成员方法 3.模拟实现一个定时器 schedule()方法 构造方法 4.MyTimer完整代码 1.定时器的定义 定时器也是软件开发中的一个重要组件. 类似于一个 "闹钟". 达到一个设定的时间之后, 就执行某个指…...

【理论推导】变分自动编码器 Variational AutoEncoder(VAE)

变分推断 (Variational Inference) 变分推断属于对隐变量模型 (Latent Variable Model) 处理的一种技巧&#xff0c;其概率图如下所示 我们将 X{x1,...xN}X\{ x_1,...x_N \}X{x1​,...xN​} 看作是每个样本可观测的一组数据&#xff0c;而将对应的 Z{z1,...,zN}Z\{z_1,...,z_N…...

【哈希表:哈希函数构造方法、哈希冲突的处理】

预测未来的最好方法就是创造它&#x1f4a6; 目录 一、什么是Hash表 二、Hash冲突 三、Hash函数的构造方法 1. 直接定址法   2. 除余法   3. 基数转换法   4. 平方取中法   5. 折叠法   6. 移位法   7. 随机数法 四、处理冲突方法 1. 开放地址法    • 线性探测法 …...