Spirng-IOC零碎知识点

news2025/5/26 5:59:01

Spirng IOC

依赖注入

  • 根据名称注入
<?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"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/util
        http://www.springframework.org/schema/util/spring-util.xsd">
    <bean id="foo" class="com.liyong.learn.inject.Foo">
        <property name="name" value="liyong"></property>
        <property name="age" value="22"></property>
    </bean>
    <bean id="foo1" class="com.liyong.learn.inject.Foo">
        <property name="name" value="liyong1`"></property>
        <property name="age" value="221"></property>
    </bean>
    <bean id="bar" class="com.liyong.learn.inject.Bar">
        <property name="name" value="liyong"></property>
        <property name="age" value="22"></property>
        <property name="addr" value="cq"></property>
    </bean>
    <bean id="list" class="com.liyong.learn.inject.ListFoo">
        <property name="list">
        	<!-- 注入List -->
            <util:list>
                <ref bean="foo"></ref>
                <ref bean="foo1"></ref>
            </util:list>
        </property>
    </bean>
</beans>

注入的时候也可以直接注入:

<bean id="list" class="com.liyong.learn.inject.ListFoo" autowire="byType"></bean>
<?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"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
  <!-- 导入资源 -->
  <import resource="beans.xml"></import>
</beans>
public static void main(String[] args) {
    BeanFactory beanFactory = new ClassPathXmlApplicationContext("inject.xml");
    Bar bean = beanFactory.getBean(Bar.class);
    System.out.println(bean);
    ListFoo listFoo = beanFactory.getBean(ListFoo.class);
    listFoo.getList().stream().forEach(System.out::println);
}

重点关注util 注入和byType注入

  • 根据Bean类型注入
    • 单个Bean对象
    • 集合Bean对象
  • 注入非Bean对象
  • 注入容器内建Bean对象
  • 注入类型
    • 实时注入
    • 延迟注入
public class ListFoo {
  private Collection<Foo> list;
  private BeanFactory beanFactory;
  private ObjectFactory<ApplicationContext> objectFactory;
}
public static void main(String[] args) {
    BeanFactory beanFactory = new ClassPathXmlApplicationContext("inject.xml");
    Bar bean = beanFactory.getBean(Bar.class);
    System.out.println(bean);
    ListFoo listFoo = beanFactory.getBean(ListFoo.class);
    listFoo.getList().stream().forEach(System.out::println);
    System.out.println(listFoo.getBeanFactory());
    // false 这里注入的bean 并不是beanFactory
    System.out.println(beanFactory == listFoo.getBeanFactory());
    // 输出为 DefaultListableBeanFactory
    System.out.println(listFoo.getBeanFactory().getClass());
    // 会错误 没有这个bean 说明我们依赖注入和依赖查找并不是同源的
    beanFactory.getBean(BeanFactory.class);
    System.out.println(beanFactory == listFoo.getObjectFactory().getObject());
}

SpirngIOC 依赖来源

  • 自定义Bean(配置的bean xml 或者注解)
  • 容器内建对象(例如Environment Bean 容器默认初始化)
  • 容器内建依赖(比如上面例子中的BeanFactory就是内建依赖)

Spring配置元信息

  • bean定义配置
    • 基于XML
    • 基于Properties文件
    • 基于Java注解
    • 基于JavaAPI
  • IOC容器配置
    • 基于XML文件
    • 基于Java注解
    • 基于JavaAPI
  • 外部化配置
    基于Java注解

BeanFactory还是ApplicationContext?

// 为什么这个表达式不会成立呢?因为他们是两个不同的对象 他们只是复用同一个接口
System.out.println(beanFactory == listFoo.getBeanFactory());

ApplicationContext是BeanFactory的一个超集,提供了更多企业级的功能。通过源码也可以看到我们下面的ApplicationContext是通过组合进来了一个BeanFactory。
在这里插入图片描述

BeanFactory 与 ApplicationContext的对比
官网推荐我们使用ApplicationContext,因为BeanFactory 有的能力BeanFactory都有

ApplicationContext 除了IOC容器角色还提供那些特性?
  • 面向切面AOP
  • 配置元信息
  • 资源管理
  • 事件
  • 国际化
  • 注解
  • Environment抽象
使用BeanFactory 与 ApplicationContext

1 XML的方式使用
直接使用,但是这样的话就不会提供事件机制比如BeanPostProcessor

DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions("inject.xml");
Bar bean = factory.getBean(Bar.class);
// 如果需要支持BeanPostProcessor 通过下面的方式进行设置
factory.addBeanPostProcessor(new MyBeanPostProcessor());

2 注解的方式使用

@Configuration
public class Main {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        context.register(Main.class);
        context.refresh();
        Bar bean = context.getBean(Bar.class);
        System.out.println(bean);
    }
    @Bean
    public Bar initBar() {
        return new Bar();
    }
}

SpringIOC容器生命周期

1 启动

public void refresh() throws BeansException, IllegalStateException {
// 加锁 因为不确定是单线程还是在多线程的环境中会创建 ApplicationContext
synchronized (this.startupShutdownMonitor) {
	// Prepare this context for refreshing.
	prepareRefresh();

	// Tell the subclass to refresh the internal bean factory.
	ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

	// Prepare the bean factory for use in this context.
	// 内建对象
	prepareBeanFactory(beanFactory);
	try {
		// Allows post-processing of the bean factory in context subclasses.
		postProcessBeanFactory(beanFactory);

		// Invoke factory processors registered as beans in the context.
		invokeBeanFactoryPostProcessors(beanFactory);

		// Register bean processors that intercept bean creation.
		registerBeanPostProcessors(beanFactory);

		// Initialize message source for this context.
		initMessageSource();

		// Initialize event multicaster for this context.
		initApplicationEventMulticaster();

		// Initialize other special beans in specific context subclasses.
		onRefresh();

		// Check for listener beans and register them.
		registerListeners();

		// Instantiate all remaining (non-lazy-init) singletons.
		finishBeanFactoryInitialization(beanFactory);

		// Last step: publish corresponding event.
		finishRefresh();
	}

	catch (BeansException ex) {
		if (logger.isWarnEnabled()) {
			logger.warn("Exception encountered during context initialization - " +
					"cancelling refresh attempt: " + ex);
		}

		// Destroy already created singletons to avoid dangling resources.
		destroyBeans();

		// Reset 'active' flag.
		cancelRefresh(ex);

		// Propagate exception to caller.
		throw ex;
	}

	finally {
		// Reset common introspection caches in Spring's core, since we
		// might not ever need metadata for singleton beans anymore...
		resetCommonCaches();
	}
}
}

2 停止

protected void doClose() {
		// Check whether an actual close attempt is necessary...
		if (this.active.get() && this.closed.compareAndSet(false, true)) {
			if (logger.isDebugEnabled()) {
				logger.debug("Closing " + this);
			}
			LiveBeansView.unregisterApplicationContext(this);
			try {
				// Publish shutdown event.
				publishEvent(new ContextClosedEvent(this));
			}
			catch (Throwable ex) {
				logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", ex);
			}
			// Stop all Lifecycle beans, to avoid delays during individual destruction.
			if (this.lifecycleProcessor != null) {
				try {
					this.lifecycleProcessor.onClose();
				}
				catch (Throwable ex) {
					logger.warn("Exception thrown from LifecycleProcessor on context close", ex);
				}
			}
			// Destroy all cached singletons in the context's BeanFactory.
			destroyBeans();
			// Close the state of this context itself.
			closeBeanFactory();
			// Let subclasses do some final clean-up if they wish...
			onClose();
			// Reset local application listeners to pre-refresh state.
			if (this.earlyApplicationListeners != null) {
				this.applicationListeners.clear();
				this.applicationListeners.addAll(this.earlyApplicationListeners);
			}
			// Switch to inactive.
			this.active.set(false);
		}
	}

BeanFactory 是容器 区别于 FactoryBean
FactoryBean 是 Spring 框架提供的一种特殊的工厂 Bean 接口,用于创建复杂的 Bean 对象。与普通的 Bean 不同,FactoryBean 实现类不直接返回实例化的 Bean 对象,而是通过工厂方法来创建 Bean 实例。这样可以为 Bean 的创建和初始化过程提供更多的灵活性和控制。
下面是一些 FactoryBean 的主要用途和特点:

  • 定制化实例化逻辑:通过实现 FactoryBean 接口,你可以自定义创建 Bean 实例的逻辑,包括可能需要的条件判断、初始化过程和配置管理等。
  • 延迟初始化:FactoryBean 可以实现延迟加载,即在需要时才实际创建对象,而不是在应用启动时就建。
  • 装饰器模式:通过 FactoryBean,你可以实现装饰器模式,对原始 Bean 进行一些额外的处理或包装。
  • 对象的复用:FactoryBean 可以控制对象的创建与返回,从而实现对象的重用,避免重复创建实例。
  • 提供灵活性:FactoryBean 的存在使得 Spring 容器中的 Bean 创建更加灵活,可以根据需求定制不同的创建逻辑。

BeanDefinition 元信息

在这里插入图片描述
1 定义bean

// 1 通过 BeanDefinitionBuilder 构建
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(Foo.class);
builder.addPropertyValue("name", "liyong");
builder.addPropertyValue("age", 11);
// 这里还可以对 beanDefinition 进行修改
BeanDefinition beanDefinition = builder.getBeanDefinition();
//2  通过 AbstractBeanDefinition 以及派生类
GenericBeanDefinition genericBeanDefinition = new GenericBeanDefinition();
// 设置Bean类型
genericBeanDefinition.setBeanClass(Foo.class);
MutablePropertyValues values = new MutablePropertyValues();
values.addPropertyValue("name", "liyong");
values.addPropertyValue("age", 11);
genericBeanDefinition.setPropertyValues(values);

2 命名Bean

  • 命名规范可以按照参数的命名规范(xml一般自定义名称比较多)
  • DefaultBeanNameGenerator 是Spirng提供的一个API用于生成BeanName
  • AnnotationBeanNameGenerator 基于注解扫描的BeanNameGenerator实现

3 别名Bean

<!--  将 foo -> 映射别名 aliasFoo  -->
<alias name="foo" alias="aliasFoo"></alias>
BeanFactory beanFactory = new ClassPathXmlApplicationContext("beans.xml");
Foo aliasFoo = (Foo) beanFactory.getBean("aliasFoo");
Foo foo = (Foo) beanFactory.getBean("foo");
System.out.println(foo == aliasFoo);

注册BeanDefinition

1 xml配置
2 注解配置元信息
@Bean
@Component
@Import
通过注解我们的Bean,Spring容器不会重复注册同样的bean

@Import({Demo.Config.class})
public class Demo {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        context.register(Demo.class);
        context.refresh();
        // 通过 命名生产器生成的 如果没有生成兜底策略为类名称
        Map<String, Config> beansOfType = context.getBeansOfType(Config.class);
        System.out.println(beansOfType);
        Map<String, Bar> barMap = context.getBeansOfType(Bar.class);
        System.out.println(barMap);
        context.close();
    }
    @Component
    static class Config {
        @Bean
        public Bar userBean() {
            Bar bar = new Bar();
            bar.setAddr("fdsa");
            bar.setName("li");
            bar.setAge(10);
            return bar;
        }
    }
}

在这里插入图片描述
3 Java Api 配置元信息

  • BeanDefinitionRegistry#registerBeanDefinition (用于命名方式)
  • BeanDefinitionReaderUtils#registerWithGeneratedName (用于非命令方式)
  • AnnotatedBeanDefinitionReader(配置类的方式)
  public static void registerFooBeanDefinition(BeanDefinitionRegistry registry, String beanName) {
        BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(Bar.class);
        builder.addPropertyValue("name", "liyong");
        builder.addPropertyValue("age", 20);
        if (StringUtils.hasText(beanName)) {
            registry.registerBeanDefinition(beanName, builder.getBeanDefinition());
        } else {
            BeanDefinitionReaderUtils.registerWithGeneratedName(builder.getBeanDefinition(), registry);
        }
    }

实例化Spring Bean

  • Bean 实例化
    • 常规方式
      • 通过构造器(配置元信息:XML,Java注解和Java API)
      • 通过静态工厂方法(配置元信息:XML 和 Java API)
      • 通过Bean工厂方法(配置元信息:XML 和 Java API)
      • 通过FactoryBean (配置元信息:XML,Java注解和Java API)
    • 特殊方式
      • 通过ServiceLoaderFactoryBean(配置元信息:XML,Java注解和Java API)
      • 通过AutowireCapableBeanFactory#createBean(Class,boolean)
      • 通过BeanDefinitionRegistry#registerBeanDefinition(String,BeanDefiniton)
        通过静态方法
 <bean id="developer" class="com.liyong.learn.createbean.HighDeveloper" factory-method="createDeveloper"></bean>

在类里面定义静态的构造Bean的方法如下,省略get,set

public class HighDeveloper {
    private String name;
    private Integer salary;
    public HighDeveloper() {
    }
    public HighDeveloper(String name, Integer salary) {
        this.name = name;
        this.salary = salary;
    }
    @Override
    public String toString() {
        return "HighDeveloper{" +
                "name='" + name + '\'' +
                ", salary=" + salary +
                '}';
    }
    public static HighDeveloper createDeveloper() {
        HighDeveloper developer = new HighDeveloper();
        developer.setName("ly");
        developer.setSalary(15 * 15);
        return developer;
    }
}

通过Bean工厂方法

<bean id="developer" class="com.liyong.learn.createbean.HighDeveloper" factory-method="createDeveloper"></bean>
<bean id="developerFactory" class="com.liyong.learn.createbean.DefaultDeveloperCreateFactory"></bean>
<bean id="developerByFc" class="com.liyong.learn.createbean.HighDeveloper" factory-bean="developerFactory" factory-method="createDeveloper"></bean>
BeanFactory beanFactory = new ClassPathXmlApplicationContext("bean-create.xml");
HighDeveloper developer = beanFactory.getBean("developer", HighDeveloper.class);
HighDeveloper developerFc = beanFactory.getBean("developerByFc", HighDeveloper.class);
System.out.println(developer);
System.out.println(developerFc);
System.out.println(developer == developerFc);

通过FactoryBean
这里和上面有所区别,这里我们只需要定义工厂就行了,不需要先定义工厂,然后还要定义具体的bean来指定实现工厂。

<bean id="developer-by-factory-bean"  class="com.liyong.learn.createbean.DeveloperFactoryBean"></bean>
HighDeveloper developerFcBean = beanFactory.getBean("developer-by-factory-bean", HighDeveloper.class);

通过ServiceLoaderFactoryBean的方式

public static void main(String[] args) {
   BeanFactory beanFactory = new ClassPathXmlApplicationContext("bean-create.xml");
   // 基于xml配置的bean
   ServiceLoader<DeveloperCreateFactory> bean = beanFactory.getBean(ServiceLoader.class);
   Iterator<DeveloperCreateFactory> it = bean.iterator();
   while (it.hasNext()) {
       DeveloperCreateFactory next = it.next();
       System.out.println(next.createDeveloper());
   }
   // ServiceLoader 加载的bean
   ServiceLoader<DeveloperCreateFactory> load = ServiceLoader.load(DeveloperCreateFactory.class, Thread.currentThread().getContextClassLoader());
   Iterator<DeveloperCreateFactory> iterator = load.iterator();
   while (iterator.hasNext()) {
       DeveloperCreateFactory next = iterator.next();
       System.out.println(next.createDeveloper());
   }
}

基于xml

<bean id="developerFactoryServiceLoader" class="org.springframework.beans.factory.serviceloader.ServiceLoaderFactoryBean">
   <property name="serviceType" value="com.liyong.learn.createbean.DeveloperCreateFactory"></property>
</bean>

基于ServiceLoader也就是SPI机制,需要再这个目录下放置文件:
在这里插入图片描述
AutowireCapableBeanFactory

ApplicationContext context = new ClassPathXmlApplicationContext("bean-create.xml");
AutowireCapableBeanFactory autowireCapableBeanFactory = context.getAutowireCapableBeanFactory();
HighDeveloper developer = autowireCapableBeanFactory.createBean(HighDeveloper.class);
System.out.println(developer);

Bean初始化

  • @PostConstruct
  • 实现InitializingBean 接口的afterPropertiesSet()方法
  • 自定义初始化方法
    • xml 指定 inti-method
    • 注解 @Bean(initMethod = ‘init’)
    • Java API AbstractBeanDefinition#setInitMethodName(String)

在bean中指定init方法,在创建bean的时候回去调用这个初始化方法

@PostConstruct
public void init() {
    System.out.println("init ing");
}

@Bean 指定initMethod

@Bean(initMethod = "initMethod")
public HighDeveloper highDeveloper() {
   return new HighDeveloper();
}
// 在类中添加方法
public void initMethod() {
     System.out.println("@Bean inti ing");
 }

通过InitializingBean 的实现

public class HighDeveloper implements InitializingBean {
 @Override
 public void afterPropertiesSet() throws Exception {
     System.out.println("InitializingBean init ing");
 }

三者的顺序:PostConstruct -> InitializingBean -> @Bean
在这里插入图片描述
通过AbstractBeanDefinition的方式

AnnotationConfigApplicationContext beanFactory = new AnnotationConfigApplicationContext();
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(HighDeveloper.class);
AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
beanDefinition.setInitMethodName("initMethod");
BeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinition, beanFactory);
beanFactory.refresh();
HighDeveloper developer = beanFactory.getBean(HighDeveloper.class);
System.out.println(developer);

延迟初始化SpringBean

  • xml配置 (Lazy-init=“true”)

  • Java 注解 @Lazy(true)
    不使用延迟初始化

public static void main(String[] args) {
     AnnotationConfigApplicationContext beanFactory = new AnnotationConfigApplicationContext();
     beanFactory.register(Client.class);
     beanFactory.refresh();
     System.out.println("context finish");
     HighDeveloper developer = beanFactory.getBean(HighDeveloper.class);
     System.out.println(developer);
 }
 @Bean(initMethod = "initMethod")
 @Lazy(value = false)
 public HighDeveloper highDeveloper() {
     return new HighDeveloper();
 }

在这里插入图片描述

使用延迟初始化

@Lazy(value = true)
public HighDeveloper highDeveloper() {
    return new HighDeveloper();
}

在这里插入图片描述
总结:对比上面我们可以发现,如果不使用延迟加载在上下文刷新的时候Bean的初始化已经完成了。延迟加载的话,在真正使用的时候才会进行初始化。

Bean的销毁阶段

1 通过标注 注解 @PreDestory
2 实现DisposableBean 接口的destory()方法
3 自定义销毁方法

  • XML配置 bean destory=‘destory’
  • Java注解 @Bean(destory=‘destory’)
  • Java API:AbstractBeanDefiniton#setDestoryMethodName()
public class Client implements DisposableBean {
    public Client(){

    }
    private String name;
    private Integer age;
    public Client(String name, Integer age) {
        this.age = age;
        this.name = name;
    }

    @PreDestroy
    public void preDestroy () {
        System.out.println("PreDestroy ......");
    }
    @Override
    public String toString() {
        return "Client{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    public void beanDestroy() {
        System.out.println("beanDestroy ....");
    }
    @Override
    public void destroy() throws Exception {
        System.out.println("disposableDestroy ...");
    }
}
@Configuration
public class BeanDemo  {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        context.register(BeanDemo.class);
        context.refresh();
        Object demo = context.getBean("demo");
        System.out.println(demo);
        context.close();
    }
    @Bean(destroyMethod = "beanDestroy")
    public Client demo() {
        return new Client();
    }
}

在这里插入图片描述

Bean 垃圾回收

1 关闭上下文
2 调用GC
3 覆盖Object finalize() 方法

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
 context.register(BeanDemo.class);
 context.refresh();
 Object demo = context.getBean("demo");
 System.out.println(demo);
 context.close();
 Thread.sleep(5000L);
 System.gc();
 Thread.sleep(5000L);
@Override
public void finalize() throws Throwable {
    System.out.println("finalize");
}

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

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

相关文章

鸿蒙ArkUI开发:常用布局【弹性布局方向图】

弹性布局方向图 Flex({ direction: FlexDirection.Row }) FlexDirection.Row&#xff08;默认值&#xff09;&#xff1a;主轴为水平方向&#xff0c;子组件从起始端沿着水平方向开始排布FlexDirection.RowReverse&#xff1a;主轴为水平方向&#xff0c;子组件从终点端沿着F…

Hystrix服务熔断

服务熔断 熔断机制是应对雪崩效应的一种微服务链路保护机制。当某个微服务不可用或者响应时间太长时&#xff0c; 会进行服务降级&#xff0c;进而熔断该节点微服务的调用&#xff0c;快速返回“错误”的响应信息。当检测到该节点微 服务调用响应正常后恢复调用链路。 在Spri…

NCL绘制WRF domain区域并添加气象站点

读取文件 根据官网例子Using gsn_csm_contour_map to plot WRF-ARW data绘制&#xff1a; ; It shows how to use gsn_csm_xxxx scripts to do the plotting. ; ; You can use the map projection settings on the WRF file, or you ; can use your own map projection. See …

在excel的内置瀑布图模板中,能在数据标签里同时显示数值和百分比吗?

瀑布图是由麦肯锡顾问公司所创的图表类型&#xff0c;因为形似瀑布流水而称之为瀑布图( Waterfall Plot)。这种图表常用于表达数个特定数值之间的数量增减变化关系。 在Excel中&#xff0c;瀑布图是可以通过簇状柱形图来完成创建。从excel2016版起&#xff0c;excel添加了内置…

【UE5 C++】基础学习笔记——01 UObject的创建与使用

目录 步骤 一、创建UObject 二、创建基于UObject的蓝图类 三、在UObject中使用变量和函数 步骤 一、创建UObject 在内容浏览器中新建一个C类 父类选择“Object” 类的类型设置为公有&#xff0c;这里就命名为“MyObject”&#xff0c;点击“创建类”来创建头文件和源文…

【网络基础】TCP协议2

TCP建立连接 什么是TCP连接 用于保证可靠性和流量控制维护的某些状态信息&#xff0c;这些信息的组合&#xff0c;包括 Socket、序列号和窗口大小称为连接。 Socket&#xff1a;由 IP 地址和端口号组成 序列号&#xff1a;用来解决乱序问题等 窗口大小&#xff1a;用来做流量…

Web 安全漏洞之文件上传

目录 文件上传漏洞及危害 文件名 HTML 和 SVG 软链 服务器磁盘 防御方法 网络安全学习路线 &#xff08;2024最新整理&#xff09; 学习资料的推荐 1.视频教程 2.SRC技术文档&PDF书籍 3.大厂面试题 特别声明&#xff1a; 文件上传漏洞及危害 文件上传漏洞…

基于SpringBoot + Vue的兼职网站管理系统设计与实现+毕业论文+答辩PPT

系统介绍 本系统包含管理员、用户、企业三个角色。 管理员角色&#xff1a;前台首页、个人中心、用户管理、企业管理、兼职信息管理、职位申请管理、留言板管理、系统管理。 用户角色&#xff1a;前台首页、个人中心、职位申请管理。 企业角色&#xff1a;前台首页、个人中心、…

【异常处理】(中北大学-程序设计基础(2))

目录 题目 源码 结果示例 题目 求一元二次方程式ax^2bxc0的实根&#xff0c;如果方程没有实根&#xff0c;则输入有关警告信息。要求&#xff1a;建立一元二次方程类&#xff0c;利用异常技术处理。 源码 #include <iostream> #include <cmath>using namespa…

JVM的垃圾回收算法有哪些?从可达性分析算法开始,深入解读三大核心垃圾回收算法

导航&#xff1a; 【Java笔记踩坑汇总】Java基础JavaWebSSMSpringBootSpringCloud瑞吉外卖/黑马旅游/谷粒商城/学成在线设计模式面试题汇总性能调优/架构设计源码-CSDN博客 目录 一、概念准备 1.1 GC Roots 1.2 可达性分析算法 1.3 非可达对象被回收过程中的两次标记 1.4…

【数据结构与算法 刷题系列】环形链表的约瑟夫问题

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 ⏩ 文章专栏&#xff1a;数据结构与算法刷题系列&#xff08;C语言&#xff09; 目录 一、问题描述 二、解题思路详解 解题思路 解题步骤 三、C语言代码…

文件流-ASCII文件(中北大学-程序设计基础(2))

目录 题目 源码 结果示例 题目 编写程序实现以下功能&#xff1a;【要求处理ASCII文件】 &#xff08;1&#xff09;按职工号由小到大的顺序将5个员工的数据&#xff08;包括号码、姓名、年龄和工资&#xff09;输出到磁盘文件中保存&#xff1b; &#xff08;2&#xff…

服务器3389端口,服务器3389端口风险提示的应对措施

3389端口是Windows操作系统中远程桌面协议&#xff08;RDP&#xff09;的默认端口。一旦该端口被恶意攻击者利用&#xff0c;可能会导致未经授权的远程访问和数据泄露等严重安全问题。 针对此风险&#xff0c;强烈建议您采取以下措施&#xff1a; 1. 修改默认端口&#xff1a;…

八、e2studio VS STM32CubeIDE之内存使用情况窗口

目录 一、概述/目的 二、STM32CubeIDE Build Analyzer 三、e2studio Memory Usage 八、e2studio VS STM32CubeIDE之内存使用情况窗口 一、概述/目的 1、嵌入开发最大特点之一就是资源受限&#xff0c;关注芯片资源使用详情是优秀工程师的技能之一 2、Keil和IAR都不支持内存…

Linux性能压测指标信息

1、CPU使用 服务器CPU整体负载信息 可以查看top命令输出的第三行数据 查看多核CPU命令 mpstat -P ALL 和 sar -P ALL top命令执行后输入1 2、内存使用 top命令或者free命令来查看内存的信息&#xff0c;第一行是物理内存使用&#xff0c;第二行是虚拟内存使用(交换空间)。…

WebSocket建立网络连接——小案例

WebSocket是一种实现全双工通信的网络技术标准&#xff0c;它允许在用户的浏览器和服务器之间进行持久的、双向的通信。以下是对WebSocket的具体介绍&#xff1a; 实时性&#xff1a;与传统HTTP请求相比&#xff0c;WebSocket提供了更高效的实时数据交换方式。一旦建立连接&am…

【cpp】并发多线程 Unique

1. unique_lock 何时锁定资源。 unique_lock lock1 时候&#xff0c;还没有锁住资源。 实际是后面&#xff0c;显式的出发&#xff1a; 比如&#xff0c; lock.lock, 或 std::lock(lk1,lk2), 或者条件变量CV.wait(mtx, []{!re})。 #include <iostream> #include <mu…

虚拟仿真云平台在教育应用中的优势和意义

虚拟仿真云实验教学平台作为一种新型的教学方法&#xff0c;近年来在高校教育中得到了十分广泛的应用。它通过模拟真实的实验场景和实验操作&#xff0c;让学生在计算机上进行实验操作和数据处理&#xff0c;为学生提供了更加便捷、可靠、有效的实验学习环境。本文&#xff0c;…

ssm123基于java web的网上书城系统的设计与实现+vue

基于java web的网上书城系统的设计与实现vue 摘 要 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff0c;商品交易当然也不能排除在外&#xff0c;随着商品交易管理的不断成熟&#xff0c;它彻底改变了…

基于SpringBoot + Vue实现的考编(考研)论坛网站设计与实现+毕业论文

系统介绍 系统包含用户和管理员两个角色 用户&#xff1a;登录、注册、经验交流平台、发布帖子、回复帖子、查看公告信息、跳蚤市场&#xff08;商品购买、商品出售、商品评价&#xff09;、个人中心等功能 管理员&#xff1a;登录、个人中心、管理员管理、用户管理、基础数据管…