小白入门基础 - Spring的Bean超详解

1.Spring工厂类的继承方式

从上面可以看出,创建工厂类,可以通过ClassPathXmlApplicationContext和FileSystemXmlApplicationContext这两种方式:
FileSystemXmlApplicationContext从磁盘加载配置文件,此时就需要使用绝对路径。

public void demo3(){//创建Spring的工厂类ApplicationContext applicationContext = new FileSystemXmlApplicationContext("C:\\applicationContext.xml");//通过工厂获得类UserService userService = (UserService) applicationContext.getBean("userService");userService.sayHello();
}

在之前老的版本中,同时通过BeanFactory来创建工厂类,这种方式虽然已经被弃用,但是依然可以使用:

@Test
public void demo4(){BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));UserService userService = (UserService) beanFactory.getBean("userService");userService.sayHello();
}

2.Bean的实例化三种方式

(1)使用类构造器实例化

public class Bean1 {public Bean1(){System.out.println("Bean1被实例化...");}
}<bean id="bean1" class="com.imooc.ioc.demo2.Bean1"></bean>@Test
public void demo1(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");Bean1 bean1 = (Bean1) applicationContext.getBean("bean1");
}

(2)使用构造工厂实例化

public class Bean2 {
}public class Bean2Factory {public static Bean2 createBean2(){System.out.println("Bean2Facyory方法已经执行");return new Bean2();}
}<bean id="bean2" class="com.imooc.ioc.demo2.Bean2Factory" factory-method="createBean2"></bean>@Test
public void demo2(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");Bean2 bean2 = (Bean2) applicationContext.getBean("bean2");
}

new ClassPathXmlApplicationContext("applicationContext.xml")会实例化applicationContext.xml配置文件中所有的构造类。

(3)使用实例工厂方法实例化

public class Bean3 {
}public class Bean3Factory {public Bean3 createBean3(){System.out.println("Bean3Factory已经实例化");return new Bean3();}
}<bean id="bean3Factory" class="com.imooc.ioc.demo2.Bean3Factory"/>
<bean id="bean3" factory-bean="bean3Factory" factory-method="createBean3"/>@Test
public void demo3() {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");Bean3 bean3 = (Bean3) applicationContext.getBean("bean3");
}

一般默认情况,我们会采用无参数的构造方法的方式。如果类的构造特别复杂,我们会使用第二种或者第三种方式。

3.Bean的配置

(1)id和name
  一般情况下,装配一个Bean时,通过指定一个id属性作为Bean的名称。
  id属性在IOC容器中必须是唯一的。
  如果Bean的名称中含有特殊字符,就需要使用name属性。
(2)class
  class用于设置一个类的完全路径名称,主要作用是IOC容器生成类的实例。 
(3)scope
  用于控制bean的作用域

scope常用的选项:

 request和session是针对web开发来说。

 默认采用singleton模式:

<bean id="person" class="com.imooc.ioc.demo3.Person" />public void demo1(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");Person person1 = (Person) applicationContext.getBean("person");Person person2 = (Person) applicationContext.getBean("person");System.out.println(person1);  //com.imooc.ioc.demo3.Person@544a2ea6System.out.println(person2);  //com.imooc.ioc.demo3.Person@544a2ea6
}

可以看到,每次创建的对象都指向一个实例。

<bean id="person" class="com.imooc.ioc.demo3.Person" scope="prototype"/>public void demo1(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");Person person1 = (Person) applicationContext.getBean("person");Person person2 = (Person) applicationContext.getBean("person");System.out.println(person1);  //com.imooc.ioc.demo3.Person@544a2ea6System.out.println(person2);  //com.imooc.ioc.demo3.Person@2e3fc542
}

如果采用prototype模式,每次都会生成一个新的对象。

4.Bean的生命周期

Spring初始化bean或销毁bean时,有时需要做一些处理工作,
因此spring可以在创建和销毁bean的时候调用bean的两个生命周期方法。
在创建的时候可以使用init-method参数来指定创建方法。
在销毁的时候可以使用destory-method参数来指定销毁方法,同时必须scope="singleton"

public class Man {public Man(){System.out.println("Man被实例化");}public void setup(){System.out.println("Man被初始化了");}public void teardown(){System.out.println("Man被销毁了");}
}<bean id="man" class="com.imooc.ioc.demo3.Man" init-method="setup" destroy-method="teardown"/>public void demo2(){ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");Man man = (Man) applicationContext.getBean("man");applicationContext.close();
}

打印结果:
  Man被实例化
  Man被初始化了
  Man被销毁了

5.Bean的生命周期的完整过程

(1)instantiate bean对象实例化
(2)populate properties封装属性
(3)如果Bean实现BeanNameAware执行setBeanName(获取当前类在spring中的配置名称,也就是id值)
(4)如果Bean实现BeanFactoryAware或者ApplicationContextAware,
设置工厂setBeanFactory或者上下文对象setApplicationContext。(了解工厂信息)
(5)如果存在类实现BeanPostProcessor(后处理Bean),执行postProcessBeforeInitialization
(6)如果Bean实现了InitializingBean执行afterPropertiesSet
(7)调用<bean init-method="init">指定初始化方法init
(8)如果存在类实现BeanPostProcessor(处理Bean),执行postProcessAfterInitialization
(9)执行业务处理
(10)如果Bean实现了DisposableBean执行destroy
(11)调用<bean destroy-method="customerDestroy">指定销毁方法customerDestroy,这个是用户自定义的销毁方法

<bean id="man" class="com.imooc.ioc.demo3.Man" init-method="setup" destroy-method="teardown"><property name="name" value="ming"/>
</bean>
<!--这个类不需要定义id,因为这是spring帮我们自动定义-->
<bean class="com.imooc.ioc.demo3.MyBeanPostProcessor"/>

package com.imooc.ioc.demo3;import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;public class Man implements BeanNameAware, ApplicationContextAware, InitializingBean, DisposableBean {private String name;public void setName(String name) {System.out.println("第二步:设置属性");this.name = name;}public Man(){System.out.println("第一步:初始化...");}public void setup(){System.out.println("第七步:Man被初始化了");}public void teardown(){System.out.println("第十一步:Man被销毁了");}public void setBeanName(String s) {System.out.println("第三步:设置Bean的名称" + s);}public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {System.out.println("第四步:了解工厂信息");}public void afterPropertiesSet() throws Exception {System.out.println("第六步:属性设置后");}public void run(){System.out.println("第九步:执行业务方法");}public void destroy() throws Exception {System.out.println("第十步:执行Spring的销毁方法");}
}
package com.imooc.ioc.demo3;import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;public class MyBeanPostProcessor implements BeanPostProcessor {public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println("第五步:初始化前方法...");return bean;}public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {System.out.println("第八步:初始化后方法...");return bean;}
}public void demo2(){ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");Man man = (Man) applicationContext.getBean("man");man.run();applicationContext.close();
}

6.BeanPostProcessor——增强类方法

实现接口类:

public interface UserDao {public void findAll();public void save();public void update();public void delete();
}

创建实现类:

public class UserDaoImpl implements UserDao {public void findAll() {System.out.println("查询用户");}public void save() {System.out.println("保存用户");}public void update() {System.out.println("修改用户");}public void delete() {System.out.println("删除用户");}
}

调用类方法

<bean class="com.imooc.ioc.demo3.MyBeanPostProcessor"/>
<bean id="userDao" class="com.imooc.ioc.demo3.UserDaoImpl"/>public void demo3(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");UserDao userDao= (UserDao)applicationContext.getBean("userDao");userDao.findAll();userDao.save();userDao.update();userDao.delete();
}

方法增强:

如果我们想增强一个方法,当然我们单独再定义一个方法,再此之前调用,
但是如果调用的次数非常多,这样就非常麻烦,这样我们可以使用BeanPostProcessor

public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException {System.out.println("第八步:初始化后方法...");if ("userDao".equals(beanName)){  //匹配到对应的类Object proxy = Proxy.newProxyInstance(bean.getClass().getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler() {public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {if ("save".equals(method.getName())){  //对于sava方法添加一点配置System.out.println("权限校验");return method.invoke(bean,args);}return method.invoke(bean,args);}});return proxy;}return bean;
}

7.属性注入方法及构造方法的属性注入

(1)构造方法注入

package com.imooc.ioc.demo4;public class User {private String name;private Integer age;public User() {}public User(String name, Integer age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", age=" + age +'}';}
}<bean id="user" class="com.imooc.ioc.demo4.User"><constructor-arg name="name" value="ming"/><constructor-arg name="age" value="18"/>
</bean>@Test
public void demo1(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");User user = (User) applicationContext.getBean("user");System.out.println(user);
}

(2)Set方法注入

  使用set方法注入,在Spring配置文件中,通过<property>设置注入的属性。

public class Person {private String name;private Integer age;public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}<bean id="person" class="com.imooc.ioc.demo4.Person"><property name="name" value="ming"/><property name="age" value="18"/>
</bean>public void demo1(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");Person person = (Person) applicationContext.getBean("person");System.out.println(person);
}

如果我现在将注入一个关联类,该如何处理了?
比如我现在给人添加一只宠物吗?

public class Cat {private String name;
}public class Person {private String name;private Integer age;private Cat cat;@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +", cat=" + cat.getName() +'}';}
}

在属性注入的时候,使用关联注入即可。

<bean id="person" class="com.imooc.ioc.demo4.Person"><property name="name" value="ming"/><property name="age" value="18"/><property name="cat" ref="cat"/>
</bean>
<bean id="cat" class="com.imooc.ioc.demo4.Cat"><property name="name" value="huahua"/>
</bean>

(3)P名称空间的属性注入

使用P命名空间。
为了简化XML文件配置,Spring从2.5开始引入一个新的P名称空间。
如果是一般属性,这样书写:
  p:<属性名>="xxx" 引入常量值
  p:<属性名>-ref="xxx"引入其他Bean对象
上面实例就可以这样些:

<bean id="person" class="com.imooc.ioc.demo4.Person" p:name="ming" p:age="18" p:cat-ref="cat"/>
<bean id="cat" class="com.imooc.ioc.demo4.Cat" p:name="huahua"/>

(4)SpEL属性注入

SpEL:spring expression language,spring表达式语言,对依赖注入进行简化的语法:#{表达式}
<bean id="" value="#{表达式}">
SpEL表达式语言:
  语法:#{}
  #{ ‘hello’ }:使用字符串
  #{beanId}:使用另一个bean
  #{beanId.content.toUpperCase()}:使用指定名属性,并使用方法
  #{T(java.lang.Math).PI}:使用静态字段或方法

创建关联类:

public class Category {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return name;}
}

创建实例类:

public class ProductInfo {public Double discountPrice(){return 188.8;}
}public class Product {private String name;private Double price;private Category category;public String getName() {return name;}public void setName(String name) {this.name = name;}public Double getPrice() {return price;}public void setPrice(Double price) {this.price = price;}public Category getCategory() {return category;}public void setCategory(Category category) {this.category = category;}@Overridepublic String toString() {return "Product{" +"name='" + name + '\'' +", price=" + price +", category=" + category +'}';}
}

Bean管理:

<bean id="category" class="com.imooc.ioc.demo4.Category"><property name="name" value="#{'服装'}"/>
</bean>
<bean id="productInfo" class="com.imooc.ioc.demo4.ProductInfo"/>
<bean id="product" class="com.imooc.ioc.demo4.Product"><property name="name" value="#{'男装'}"/><property name="price" value="#{productInfo.discountPrice()}"/>  引用工厂类的方法<property name="category" value="#{category}"/>
</bean>

调用:

public void demo1(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");Product product = (Product) applicationContext.getBean("product");System.out.println(product);
}

(5)负责类型的属性注入

数组类型的属性注入
List集合类型的属性注入
Set集合类型的属性注入
Map集合类型的属性注入
Properties类型的属性注入

创建实例类:

public class CollectionBean {private String[] arrs;  //数组类型private List<String> list;  //List集合类型private Set<String> set; //Set集合类型private Map<String,Integer> map;  //Map集合类型private Properties properties;  //属性类型public String[] getArrs() {return arrs;}public void setArrs(String[] arrs) {this.arrs = arrs;}public List<String> getList() {return list;}public void setList(List<String> list) {this.list = list;}public Set<String> getSet() {return set;}public void setSet(Set<String> set) {this.set = set;}public Map<String, Integer> getMap() {return map;}public void setMap(Map<String, Integer> map) {this.map = map;}public Properties getProperties() {return properties;}public void setProperties(Properties properties) {this.properties = properties;}@Overridepublic String toString() {return "CollectionBean{" +"arrs=" + Arrays.toString(arrs) +", list=" + list +", set=" + set +", map=" + map +", properties=" + properties +'}';}
}

Bean管理:

<bean id="collectionBean" class="com.imooc.ioc.demo5.CollectionBean"><!--数组类型的属性注入--><property name="arrs"><list><value>a</value><value>b</value><value>c</value></list></property><!--List集合类型的属性注入--><property name="list"><list><value>11</value><value>22</value><value>33</value></list></property><!--Set集合类型的属性注入--><property name="set"><set><value>10</value><value>20</value><value>30</value></set></property><!--map集合类型的属性注入--><property name="map"><map><entry key="a" value="1"></entry><entry key="b" value="2"></entry><entry key="c" value="3"></entry></map></property><!--properties属性注入--><property name="properties"><props><prop key="username">ming</prop><prop key="password">123456</prop></props></property>
</bean>

调用:

public void demo1(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");CollectionBean collectionBean = (CollectionBean) applicationContext.getBean("collectionBean");System.out.println(collectionBean);//CollectionBean{arrs=[a, b, c], list=[11, 22, 33], set=[10, 20, 30], map={a=1, b=2, c=3}, properties={password=123456, username=ming}}
}

8.Bean管理的注解方式

(1)简单使用

Spring2.5引入使用注解去定义Bean。
  @Component 描述Spring框架中Bean,这样就无需在XML文件中进行配置
除了@Component外,Spring提供了3个基本功能和@Component等效的注解:
  @Repository 用于对DAO实现类进行标注
  @Service 用于对Service实现类进行标注
  @Controller 用于对Controller实现类进行标注

比如:

import org.springframework.stereotype.Component;@Component("userService")
public class UserService {public String sayHello(String name){return "Hello" + name;}
}public void demo1(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");UserService userService = (UserService) applicationContext.getBean("userService");System.out.println(userService.sayHello("ming"));
}

注解会帮我们完成XML的Bean配置。

(2)属性注入

使用@Autowored进行自动注入
@Autowired默认按照类型进行注入
  如果存在两个相同Bean,则按照名称注入
@Autowired注入时可以针对成员变量或者set方法
通过@Autowired的required属性,设置一定要找到匹配的Bean。
使用@Qualifier指定注入Bean的名称

@Component("userService")
public class UserService {@Value("鱼")  //常规属性注入private String food;@Autowired  //对象注入private UserDao userDao;public String sayHello(String name){return "Hello" + name;}public void eat(){System.out.println("eat: " + food);}public void save(){System.out.println("Service中保存用户");userDao.save();  //将对象注入之后,才能调用其中的方法}
}

使用@Qualifier按照名称才能完成注入

@Autowired  //对象注入
@Qualifier("userDao")
private UserDao userDao;

@Resource相当于@Autowired+@Qualifier的功能。

类中如果有setter方法,那么注解需要加到setter方法上边。

(3)生命周期的注解

Spring初始化bean或销毁bean时,有时候需要一些处理工作,
因此Spring可以在创建和拆卸bean的时候,调用bean的两个生命周期方法。
那么如何使用注解的方式来完成了?
init-method初始化的时候,可以用@PostConstruct来代替。
destory-method销毁对象时,可以使用@PreDestroy

@Component("bean1")
public class Bean1 {@PostConstructpublic void init(){System.out.println("initBean...");}public void say(){System.out.println("say...");}@PreDestroypublic void destory(){System.out.println("destroyBean...");}
}public void demo2() {ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");Bean1 bean1 = (Bean1) classPathXmlApplicationContext.getBean("bean1");bean1.say();classPathXmlApplicationContext.close();
}

(4)注入范围的注解

使用注解配置的Bean和<bean>配置的一样,默认作用范围都是singleton。
使用@Scope注解用于指定Bean的作用范围。

@Component("bean2")
public class Bean2 {
}public void demo2() {ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");Bean2 bean1 = (Bean2) classPathXmlApplicationContext.getBean("bean2");Bean2 bean2 = (Bean2) classPathXmlApplicationContext.getBean("bean2");System.out.println(bean1);  //com.imooc.demo2.Bean2@79ca92b9System.out.println(bean2);  //com.imooc.demo2.Bean2@79ca92b9
}

如果指定作用范围:

@Component("bean2")
@Scope("prototype")
public class Bean2 {
}

结果将完全不同:

public void demo2() {ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");Bean2 bean1 = (Bean2) classPathXmlApplicationContext.getBean("bean2");Bean2 bean2 = (Bean2) classPathXmlApplicationContext.getBean("bean2");System.out.println(bean1);  //com.imooc.demo2.Bean2@1198b989System.out.println(bean2);  //com.imooc.demo2.Bean2@7ff95560
}

9.传统XML配置和注解整合开发

XML方式的优势:
  结构清晰,易于阅读
注解方式的优势:
  开发便捷,属性注入方便

XML与注解和整合开发
  1.引入context命名空间
  2.在配置文件中添加context:annotation-config标签

(1)传统方式

public class CategoryDao {public void save(){System.out.println("CategoryDao中sava方法执行了");}
}
public class ProductDao {public void save(){System.out.println("ProductDao中sava方法执行了");}
}public class ProductService {private CategoryDao categoryDao;private ProductDao productDao;public CategoryDao getCategoryDao() {return categoryDao;}public void setCategoryDao(CategoryDao categoryDao) {this.categoryDao = categoryDao;}public ProductDao getProductDao() {return productDao;}public void setProductDao(ProductDao productDao) {this.productDao = productDao;}public void save(){System.out.println("ProductService的save方法");categoryDao.save();productDao.save();}
}<bean id="productService" class="com.imooc.demo3.ProductService"><property name="categoryDao" ref="categoryDao"/><property name="productDao" ref="productDao"/>
</bean>
<bean id="categoryDao" class="com.imooc.demo3.CategoryDao"/>
<bean id="productDao" class="com.imooc.demo3.ProductDao"/>public void demo1(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");ProductService productService = (ProductService) applicationContext.getBean("productService");productService.save();
}

(2)混合开发

如果此时属性注入想使用注解方式,那么可以这样:

<context:annotation-config/>
<bean id="productService" class="com.imooc.demo3.ProductService">
</bean>
<bean id="categoryDao" class="com.imooc.demo3.CategoryDao"/>
<bean id="productDao" class="com.imooc.demo3.ProductDao"/>public class ProductService {@Resource(name="categoryDao")  //属性注入private CategoryDao categoryDao;@Resource(name="productDao")private ProductDao productDao;public void save(){System.out.println("ProductService的save方法");categoryDao.save();productDao.save();}
}public void demo1(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");ProductService productService = (ProductService) applicationContext.getBean("productService");productService.save();
}

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

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

相关文章

RK3568 学习笔记 : 解决 linux_sdk 编译 python 版本报错问题

前言 最近买了 【正点原子】 的 RK3568 开发板&#xff0c;下载了 开发板的资料&#xff0c;包括 Linux SDK&#xff0c;这个 Linux SDK 占用的空间比较大&#xff0c;扩展了一下 VM 虚拟机 ubuntu 20.04 的硬盘空间&#xff0c;编译才正常通过。 编译 RK3568 Linux SDK 时&am…

使用Python+selenium3.0实现第一个自动化测试脚本

这篇文章主要介绍了使用Pythonselenium实现第一个自动化测试脚本&#xff0c;文中通过示例代码介绍的非常详细&#xff0c;对大家的学习或者工作具有一定的参考学习价值&#xff0c;需要的朋友们下面随着小编来一起学习学习吧 最近在学web自动化&#xff0c;记录一下学习过程。…

Pandas数据可视化

pandas库是Python数据分析的核心库 它不仅可以加载和转换数据&#xff0c;还可以做更多的事情&#xff1a;它还可以可视化 pandas绘图API简单易用&#xff0c;是pandas流行的重要原因之一 Pandas 单变量可视化 单变量可视化&#xff0c; 包括条形图、折线图、直方图、饼图等 …

JWT 详解

前言&#xff1a; 本博客为转载整合博客&#xff08;主打一个&#xff1a;我们只做博客的搬运工&#xff09;&#xff0c;参考博客主要有&#xff1a; https://blog.csdn.net/weixin_45070175/article/details/118559272?ops_request_misc%257B%2522request%255Fid%2522%253A…

[ComfyUI进阶教程] 使用IPAdapater FaceID换脸

IPapapter 的团队推出IP-Adapter-FaceID模型,相较于旧模型大幅提高从图片还原人像的相似度。一张照片换脸现在可以更精准了。 使用人脸识别模型中的人脸 ID 嵌入代替 CLIP 图像嵌入,此外,使用 LoRA 来提高 ID 一致性。 IP-Adapter-FaceID 只需文字提示即可生成以人脸为条件的…

【基础篇】九、程序计数器 JVM栈

文章目录 0、运行时数据区域1、程序计数器2、JVM栈3、JVM栈--栈帧--局部变量表4、JVM栈--栈帧--操作数栈5、JVM栈--栈帧--桢数据6、栈溢出7、设置栈空间大小8、本地方法栈 0、运行时数据区域 JVM结构里&#xff0c;类加载器下来&#xff0c;到了运行时数据区域&#xff0c;即Ja…

视图与索引连表查询(内/外联)和子查询

目录 一、视图 1.1、概念&#xff1a; 1.2、场景&#xff1a; 1.3、用视图的意义 1.2、创建(增加)视图 1.3、修改视图 1.4、删除视图 1.5、查看视图 ​编辑 二、索引 2.1、概念 2.2、优缺点 优点&#xff1a; 缺点&#xff1a; 2.3、应用场景 2.4、会失效 2.5、…

JavaWeb——新闻管理系统(Jsp+Servlet)之jsp新闻查询

java-ee项目结构设计 1.dao:对数据库的访问&#xff0c;实现了增删改查 2.entity:定义了新闻、评论、用户三个实体&#xff0c;并设置对应实体的属性 3.filter&#xff1a;过滤器&#xff0c;设置字符编码都为utf8&#xff0c;防止乱码出现 4.service:业务逻辑处理 5.servlet:处…

【WPF】使用 WriteableBitmap 提升 Image 性能

【WPF】使用 WriteableBitmap 提升 Image 性能 前言WriteableBitmap 背景WriteableBitmap 渲染原理WriteableBitmap 使用技巧案例核心源码测试结果 前言 由于中所周不知的原因&#xff0c;WPF 中想要快速的更新图像的显示速率一直以来都是一大难题。在本文中&#xff0c;我将分…

Android学习(一):Android Studio安装与配置

Android学习&#xff08;一&#xff09;&#xff1a;Android Studio安装与配置 一、安装 下载地址 下载zip文件&#xff0c;免安装。 二、下载资源 启动后&#xff0c;出现该弹框&#xff0c;点击Cancel。 点击Next 默认&#xff0c;点击Next。 点击Next。 点击Finish 开始…

性能优化-OpenMP基础教程(二)

本文主要介绍OpenMP并行编程技术&#xff0c;编程模型、指令和函数的介绍、以及OpenMP实战的几个例子。希望给OpenMP并行编程者提供指导。 &#x1f3ac;个人简介&#xff1a;一个全栈工程师的升级之路&#xff01; &#x1f4cb;个人专栏&#xff1a;高性能&#xff08;HPC&am…

学习Redis缓存

学习Redis缓存 NoSQL和SQL的区别缓存缓存作用缓存成本添加Redis缓存 Redis特征Redis中数据结构Redis通用命令String类型Key的层级格式Hash类型Redis的Java客户端 NoSQL和SQL的区别 缓存 缓存就是数据交换的缓冲区&#xff0c;是存储数据的临时地方&#xff0c;一般读写性比较高…

async和await关键字

目录 async 关键字await 关键字使用 async 和 await 解决回调地狱问题错误处理总结 在JavaScript中&#xff0c; async和 await是用于简化基于 Promise的异步编程的关键字。在ES2017&#xff08;也称为ES8&#xff09;中引入后&#xff0c;它们迅速成为管理异步代码的首选方…

SQL高级:事务

在前面的内容中,我们学习了很多SQL的高级语法,包括窗口函数,存储过程等。在这篇文章中,我们要学习一个很重要的概念,事务。 事务的定义 为了讲清楚事务,很多人拿银行转账来举例,不得不说这真的是一个非常恰当的例子。一个账户要增加对应的金额,另一个账户需要减少对应…

RT-DETR Gradio 前端展示页面

效果展示 使用方法 Gradio 是一个开源库,旨在为机器学习模型提供快速且易于使用的网页界面。它允许开发者和研究人员轻松地为他们的模型创建交互式的演示,使得无论技术背景如何的人都可以方便地试用和理解这些模型。使用Gradio,你只需几行代码就可以生成一个网页应用程序,…

【C程序设计】C函数指针与回调函数

函数指针 函数指针是指向函数的指针变量。 通常我们说的指针变量是指向一个整型、字符型或数组等变量&#xff0c;而函数指针是指向函数。 函数指针可以像一般函数一样&#xff0c;用于调用函数、传递参数。 函数指针变量的声明&#xff1a; typedef int (*fun_ptr)(int,i…

mysql之视图mysql连接案例索引

文章目录 一、视图1.1 含义1.2 操作1.2.1 创建视图1.2.2 视图的修改1.2.3 删除视图1.2.4 查看视图 二、连接案例01)查询" 01 "课程比" 02 "课程成绩高的学生的信息及课程分数02)查询同时存在" 01 "课程和" 02 "课程的情况03&#xff0…

【信息论与编码】习题-判断题-第二部分

目录 判断题 第二部分24. 信道矩阵 代表的信道的信道容量C125. 信源熵具有严格的下凸性。26. 率失真函数对允许的平均失真度具有上凸性。27. 信道编码定理是一个理想编码的存在性定理&#xff0c;即&#xff1a;信道无失真传递信息的条件是信息率小于信道容量 。28. 信道的输出…

修改 Ubuntu 的配置

目录 一、修改地址 1. 修改本机IP 二、修改网关 1. 查看网关地址 2. 设置默认网关 三、重启网络 1. 重启网络 2. 刷新网络 四、修改主机名 1. 查看主机名 2. 修改主机名 一、修改地址 1. 修改本机IP sudo ifconfig en…