學習spring Bean的生命周期

完整項目結構

├── pom.xml
└── src/├── main/│   ├── java/│   │   └── com/│   │       └── zhang/│   │           ├── bean/│   │           │   ├── Address.java│   │           │   ├── MyBeanPostProcessor.java│   │           │   └── Person.java│   │           └── factory/│   │               ├── MyFactoryBean.java│   │               ├── PersonInstanceFactory.java│   │               └── PersonStaticFactory.java│   └── resources/│   │  ├── db.properties│       └── ioc.xml└── test/└── java/└── MyTest.java

項目主要內容和學習方面

這個項目是一個Spring框架的學習練習demo,主要學習了以下幾個方面:

  1. Spring IoC容器基礎

    • 通過ClassPathXmlApplicationContext加載配置文件并創建IoC容器
    • 學習了從容器中獲取Bean的多種方式(根據id、根據類型)
  2. Bean的作用域

    • 測試了Spring中Bean的單例模式
  3. 依賴注入

    • 通過配置文件實現PersonAddress等實體類的依賴注入
  4. Bean的生命周期

    • 實現了MyBeanPostProcessor類,學習Bean的后置處理器機制
  5. 工廠模式

    • 學習了多種工廠創建Bean的方式:
      • 靜態工廠(PersonStaticFactory
      • 實例工廠(PersonInstanceFactory
      • FactoryBean(MyFactoryBean
  6. 數據源配置

    • 項目中包含了Druid數據源的配置測試

主要Java類說明

  • 實體類Person.java(人員實體)、Address.java(地址實體)
  • 后置處理器MyBeanPostProcessor.java(Bean生命周期處理器)
  • 工廠類PersonStaticFactory.java(靜態工廠)、PersonInstanceFactory.java(實例工廠)、MyFactoryBean.java(FactoryBean實現)
  • 測試類MyTest.java(用于測試Spring的各種功能)

項目依賴包括Spring框架的核心模塊、MySQL驅動和Druid數據源。

代碼

bean

public class Address {private String province;private String city;private String town;public Address() {System.out.println("Address被創建");}public String getProvince() {return province;}public void setProvince(String province) {this.province = province;}public String getCity() {return city;}public void setCity(String city) {this.city = city;}public String getTown() {return town;}public void setTown(String town) {this.town = town;}@Overridepublic String toString() {return "Address{" +"province='" + province + '\'' +", city='" + city + '\'' +", town='" + town + '\'' +'}';}
}import java.util.*;public class Person {private Integer id;private String name;private Integer age;private String gender;
//    private Date date;private String[] hobbies;private Address address;private List<Address> lists;
private Set<String> sets;
private Map<String,Object> maps;
private Properties properties;public void init(){
//    先寫n行代碼完成初始化功能System.out.println("person對象初始化完成");
}
public void destroy(){System.out.println("person對象被銷毀");
}public Person() {System.out.println("person被創建");}public Person(Address address) {this.address = address;}public Person(Integer id, String name, Address address) {this.id = id;this.name = name;this.address = address;}//    public Person(Integer id, String name, Integer age, String gender, Date date) {
//        this.id = id;
//        this.name = name;
//        this.age = age;
//        this.gender = gender;
//        this.date = date;
//    }public Person(Integer id, String name, Integer age, String gender) {this.id = id;this.name = name;this.age = age;this.gender = gender;}public Person(Integer id, String name, String gender) {this.id = id;this.name = name;this.gender = gender;System.out.println("gender... ...");}public Person(Integer id, String name, Integer age) {this.id = id;this.name = name;this.age = age;System.out.println("age... ...");}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}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;}public String getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}public String[] getHobbies() {return hobbies;}public void setHobbies(String[] hobbies) {this.hobbies = hobbies;}public Address getAddress() {return address;}public void setAddress(Address address) {this.address = address;}public List<Address> getLists() {return lists;}public void setLists(List<Address> lists) {this.lists = lists;}public Set<String> getSets() {return sets;}public void setSets(Set<String> sets) {this.sets = sets;}public Map<String, Object> getMaps() {return maps;}public void setMaps(Map<String, Object> maps) {this.maps = maps;}public Properties getProperties() {return properties;}public void setProperties(Properties properties) {this.properties = properties;}
//    public Date getDate() {
//        return date;
//    }
//
//    public void setDate(Date date) {
//        this.date = date;
//    }@Overridepublic String toString() {return "Person{" +"id=" + id +", name='" + name + '\'' +", age=" + age +", gender='" + gender + '\'' +", hobbies=" + Arrays.toString(hobbies) +", address=" + address +", lists=" + lists +", sets=" + sets +", maps=" + maps +", properties=" + properties +'}';}}
初始化的時候做事情
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("postProcessBeforeInitialization:"+beanName);return bean;}/*** 在每一個對象的初始化方法之后執行* @param bean 表示創建的具體對象* @param beanName  表示bean的id屬性* @return* @throws BeansException*/public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {if (bean instanceof Person){System.out.println();}else {System.out.println();}System.out.println("postProcessAfterInitialization:"+beanName);return bean;}
}
工廠

單例模式


import com.zhang.bean.Person;
import org.springframework.beans.factory.FactoryBean;
/*此方式是spring創建bean方式的一種補充,用戶可以按照需求創建對象,
* 創建的對象交由spring IOC容器來進行管理,無論是否是單例,都是在
* 用到的時候才會創建該對象,不用該對象不會創建*/
public class MyFactoryBean implements FactoryBean<Person> {/*返回獲取的bean*/public Person getObject() throws Exception {Person person=new Person();person.setId(3);person.setName("王五");return person;}
/*獲取返回bean的類型*/public Class<?> getObjectType() {return Person.class;}
/*判斷當前bean是否是單例的*/public boolean isSingleton() {return true;}
}import com.zhang.bean.Person;
//*實例工廠類*/
public class PersonInstanceFactory {public  Person getInstance(String name){Person person = new Person();person.setId(2);person.setName(name);person.setAge(22);return person;}}import com.zhang.bean.Person;
/*靜態工廠類*/
public class PersonStaticFactory {public static Person getInstance(String name){Person person = new Person();person.setId(1);person.setName(name);person.setAge(11);return person;}
}
測試
import com.alibaba.druid.pool.DruidDataSource;
import com.zhang.bean.Address;
import com.zhang.bean.Person;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class MyTest {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("ioc.xml");/*根據bean標簽的id來獲取對象*/
//        Person person = context.getBean("person", Person.class);
//        Person person1 = context.getBean("person", Person.class);
//        System.out.println(person==person1);
//        System.out.println(person);/*根據bean的類型來獲取對象* 注意:當通過類型進行獲取的時候,如果存在兩個相同類型對象,將無法完成獲取工作* */
//        Person bean = context.getBean(Person.class);
//        System.out.println(bean);/*當需要從容器中獲取對象的時候,最好要保留無參構造方法,因為底層的實現是反射*Object obj = clazz.newInstance() ;默認調用無參的構造方法,此方法已經被棄用Object obj = clazz.newConstructorInstance();*/
//        Person bean = context.getBean("person6",Person.class);
//        System.out.println(bean);
//        Address address2 = context.getBean("address2", Address.class);
//        System.out.println(address2);
//        Person son = context.getBean("son",Person.class);
//        System.out.println(son);
//        Person parent = context.getBean("parent",Person.class);
//        System.out.println(parent);
//        Person person2 = context.getBean("person2", Person.class);
//        Person person3 = context.getBean("person2", Person.class);
//        System.out.println(person2==person3);
//        Person person = context.getBean("person", Person.class);
//        System.out.println(person);
//        Person person2 = context.getBean("person2", Person.class);
//        System.out.println(person2);
//        Person myFactoryBean = context.getBean("myFactoryBean", Person.class);
//        System.out.println(myFactoryBean);Person person = context.getBean("person2", Person.class);System.out.println(person);
// 關閉ioc容器
//        ((ClassPathXmlApplicationContext) context).close();
//        DruidDataSource dataSource = context.getBean("dataSource2", DruidDataSource.class);
//        System.out.println(dataSource);
//        System.out.println(dataSource.getCloseCount());}
}
配置文件
<?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:p="http://www.springframework.org/schema/p"xmlns:cont="http://www.springframework.org/schema/context"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><!--7到149一起注釋掉--><!--    &lt;!&ndash;在進行框架配置的時候,可以使用xml文件,也可以使用注解的方式--><!--    很多同學覺得xml的方式比較麻煩,但是xml的配置方式還是要學習的,因為在項目開發過程中,--><!--    很多情況下是xml和注解一起工作,而且xml配置的方式比較完整&ndash;&gt;--><!--    &lt;!&ndash;<bean id="person" class="com.zhang.bean.Person" scope="prototype">&ndash;&gt;--><!--    &lt;!&ndash;    scope="prototype"改為分單例&ndash;&gt;--><!--    <bean id="person" class="com.zhang.bean.Person">--><!--        &lt;!&ndash;根據屬性值設置的時候,name的名稱取決于set方法后面的參數首字符小寫的名稱&ndash;&gt;--><!--        <property name="id" value="1"></property>--><!--        <property name="name" value="zhangsan"></property>--><!--        <property name="age" value="20"></property>--><!--        <property name="gender" value="男"></property>--><!--        &lt;!&ndash;     <property name="date" ref="now"></property>&ndash;&gt;--><!--        &lt;!&ndash;        <property name="date" value="2020/02/06"></property>&ndash;&gt;--><!--    </bean>--><!--    <bean id="now" class="java.util.Date">--><!--    </bean>--><!--    &lt;!&ndash;使用構造器方法賦值的時候,參數的name屬性是由什么來決定的?由構造方法的參數名稱決定的--><!--    name:表示參數列表的名稱--><!--    value:表示實際的具體值--><!--    type:表示值的類型--><!--    index:表示值的下標,從0開始--><!--    &ndash;&gt;--><!--    <bean id="person2" class="com.zhang.bean.Person">--><!--        <constructor-arg name="id" value="2"></constructor-arg>--><!--        <constructor-arg name="name" value="lisi"></constructor-arg>--><!--        <constructor-arg name="age" value="20"></constructor-arg>--><!--        <constructor-arg name="gender" value="男"></constructor-arg>--><!--    </bean>--><!--    &lt;!&ndash;當通過構造器方法賦值的時候,可以把name屬性省略不寫,但是要注意必須要保證參數值跟構造器的參數列表的順序一致,--><!--    如果非要不一致的話,可以通過index的下標方式來標注,從0開始 &ndash;&gt;--><!--    <bean id="person3" class="com.zhang.bean.Person">--><!--        <constructor-arg value="2" index="2"></constructor-arg>--><!--        <constructor-arg value="lisi"></constructor-arg>--><!--        <constructor-arg value="22" index="0"></constructor-arg>--><!--        <constructor-arg value="男"></constructor-arg>--><!--    </bean>--><!--    &lt;!&ndash;當有多個相同參數的構造方法存在的時候,默認情況下是覆蓋的過程,后面的構造方法會覆蓋前面的構造方法,--><!--    如果非要賦值給另外一個構造方法的話,可以使用type的參數來進行指定&ndash;&gt;--><!--    <bean id="person4" class="com.zhang.bean.Person">--><!--        <constructor-arg value="4"></constructor-arg>--><!--        <constructor-arg value="wangwu"></constructor-arg>--><!--        <constructor-arg value="22" type="java.lang.Integer"></constructor-arg>--><!--    </bean>--><!--    &lt;!&ndash;總結:--><!--    在日常工作中,一般都是用name, value的方式,很少有人去使用index或者type的方式,但是要注意各種情況出現的問題--><!--    &ndash;&gt;--><!--    &lt;!&ndash; 使用p命名空間來給屬性命名--><!--    &ndash;&gt;--><!--    <bean id="person5" class="com.zhang.bean.Person" p:id="5" p:name="zhaoliu" p:age="25" p:gender="女"></bean>--><!--    &lt;!&ndash;    給復雜類型進行賦值&ndash;&gt;--><!--    <bean id="person6" class="com.zhang.bean.Person">--><!--        <property name="id" value="6"></property>--><!--        <property name="name" value="zhangsan6"></property>--><!--        <property name="age" value="20"></property>--><!--        <property name="gender" value="男"></property>--><!--        &lt;!&ndash; 給數組賦值 使用array標簽&ndash;&gt;--><!--        &lt;!&ndash; <property name="hobbies" value="book,girl,movie"></property>&ndash;&gt;--><!--        <property name="hobbies">--><!--            <array>--><!--                <value>book</value>--><!--                <value>girl</value>--><!--                <value>movie</value>--><!--            </array>--><!--        </property>--><!--        &lt;!&ndash;        引用類型賦值,可以使用ref引入外部bean&ndash;&gt;--><!--        <property name="address" ref="address"></property>--><!--        &lt;!&ndash; 給list 賦值&ndash;&gt;--><!--        &lt;!&ndash;  <property name="lists" value="1,2,3"></property>&ndash;&gt;--><!--        <property name="lists">--><!--            <list>--><!--                &lt;!&ndash;使用內部bean,無法從IOC容器中直接獲取對象的值&ndash;&gt;--><!--                <bean id="address2" class="com.zhang.bean.Address">--><!--                    <property name="province" value="北京"></property>--><!--                </bean>--><!--                <bean class="com.zhang.bean.Address">--><!--                    <property name="province" value="上海"></property>--><!--                </bean>--><!--                &lt;!&ndash;使用外部bean,可以隨意從IOC容器獲取對象的值&ndash;&gt;--><!--                <ref bean="address"></ref>--><!--            </list>--><!--        </property>--><!--        <property name="sets">--><!--            <set>--><!--                <value>zhangsan</value>--><!--                <value>zhangsan</value>--><!--                <value>wangwu</value>--><!--            </set>--><!--        </property>--><!--        <property name="maps">--><!--            <map>--><!--                <entry key="a" value="aaa"></entry>--><!--                <entry key="address" value-ref="address"></entry>--><!--                <entry key="address2">--><!--                    <bean class="com.zhang.bean.Address">--><!--                        <property name="province" value="廣東"></property>--><!--                    </bean>--><!--                </entry>--><!--                <entry>--><!--                    <key>--><!--                        <value>hehe</value>--><!--                    </key>--><!--                    <value>haha</value>--><!--                </entry>--><!--                <entry key="list">--><!--                    <list>--><!--                        <value>11</value>--><!--                        <value>22</value>--><!--                    </list>--><!--                </entry>--><!--            </map>--><!--        </property>--><!--        <property name="properties">--><!--            <props >--><!--                <prop key="111">aaa</prop>--><!--                <prop key="222">bbb</prop>--><!--            </props>--><!--        </property>--><!--    </bean>--><!--    <bean id="address" class="com.zhang.bean.Address">--><!--        <property name="province" value="河北省"></property>--><!--        <property name="city" value="邯鄲"></property>--><!--        <property name="town" value="武安"></property>--><!--    </bean>--><!--&lt;!&ndash;bean之間的繼承關系&ndash;&gt;--><!--&lt;!&ndash;    可以使用abstract標簽定義抽象bean,無法進行實例化&ndash;&gt;--><!--    <bean id="parent" class="com.zhang.bean.Person" abstract="false">--><!--    &lt;!&ndash;根據屬性值設置的時候,name的名稱取決于set方法后面的參數首字符小寫的名稱&ndash;&gt;--><!--    <property name="id" value="1"></property>--><!--    <property name="name" value="zhangsan"></property>--><!--    <property name="age" value="20"></property>--><!--    <property name="gender" value="男"></property>--><!--    </bean>--><!--&lt;!&ndash;    可以通過parent屬性來獲取父bean中的某些屬性值&ndash;&gt;--><!--<bean id="son" class="com.zhang.bean.Person" parent="parent">--><!--    <property name="name" value="haha"></property>--><!--</bean>--><!-- 創建bean的時候依賴關系當bean對象被創建的時候,是按照xml配置文件定義的順序創建的,誰在前誰就先被創建,如果需要干擾創建的順序,可以使用 depends-on屬性一般在實際工作中不必在意bean創建的順序,無論依賴的對象在創建完成之后都會進行賦值操作--><!--    <bean id="person" class="com.zhang.bean.Person" depends-on="address">  </bean>--><!--    <bean id="address" class="com.zhang.bean.Address" ></bean>--><!-- 設置bean對象的生命周期通過scope屬性可以指定當前bean的作用域singleton:單例模式、從ioc容器中獲取的都是同一個對象,默認的作用域prototype:多例模式、從IOC容器中獲取的對象每次都是新創建的在spring4.x的版本中還包括另外兩個作用域:request:每次發送請求都會有一個新的對象session:每次會話都會由一個新的對象幾乎不用,從來沒有用過,因此在5版本的時候就被淘汰了--><!--    注意:如果是單例作用域的話,每次在創建ioc容器完成之前此對象就已經創建完成如果是prototype作用域的話,每次是在需要用到此對象的時候才會創建--><!--    <bean id="person2" class="com.zhang.bean.Person" scope="singleton"></bean>--><!--利用工廠方式創建bean--><!--靜態工廠類名.靜態方法()--><!--    <bean id="person" class="com.zhang.factory.PersonStaticFactory" factory-method="getInstance">--><!--        <constructor-arg value="zhangsan"></constructor-arg>--><!--    </bean>--><!--實例工廠:先創建工廠實例,然后調用工廠實例的方法factory-bean:表示具體工程類的實例factory-method:表示具體工廠實例方法--><!--    <bean id="instanceFactory" class="com.zhang.factory.PersonInstanceFactory"></bean>--><!--    <bean id="person2" class="com.zhang.bean.Person" factory-bean="instanceFactory" factory-method="getInstance">--><!--        <constructor-arg value="lisi"></constructor-arg>--><!--    </bean>--><!--    <bean id="myFactoryBean" class="com.zhang.factory.MyFactoryBean"></bean>--><!-- spring容器在創建對象的時候可以指定具體的初始化和銷毀方法init-method:在對象創建完成之后會調用初始化方法destroy-method:在容器關閉的時候會調用銷毀方法--><!-- 初始化和銷毀的方法跟scope屬性也是相關聯的如果是singleton的話,初始化和銷毀的方法都存在如果是prototype的話,初始化會調用,但是銷毀的方法不會調用--><!--    <bean id="person" class="com.zhang.bean.Person" init-method="init" destroy-method="destroy"></bean>--><!--    <bean id="myBeanPostProcessor" class="com.zhang.bean.MyBeanPostProcessor"></bean>--><!--    <bean id="address" class="com.zhang.bean.Address"></bean>--><!--    &lt;!&ndash;spring管理第三方bean&ndash;&gt;-->
<!--    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">-->
<!--        <property name="username" value="root"></property>-->
<!--        <property name="password" value="1234"></property>-->
<!--        <property name="url" value="jdbc:mysql://localhost:3306/exam"></property>-->
<!--        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>-->
<!--    </bean>-->
<!--    &lt;!&ndash;    當需要引入外部的配置文件的時候,需要導入一些context的命名空間&ndash;&gt;--><!--    <context:property-placeholder location="classpath:db.properties"></context:property-placeholder>-->
<!--    &lt;!&ndash;在配置文件編寫屬性的時候需要注意,-->
<!--    spring容器在進行啟動的時候,會讀取當前系統的某些環境變量的配置,-->
<!--    當前系統的用戶名是用username來表示的,所以最好的方式是添加前綴來做區分&ndash;&gt;-->
<!--    <bean id="dataSource2" class="com.alibaba.druid.pool.DruidDataSource">-->
<!--        <property name="username" value="${jdbc.username}"></property>-->
<!--        <property name="password" value="${jdbc.password}"></property>-->
<!--        <property name="url" value="${url}"></property>-->
<!--        <property name="driverClassName" value="${driverClassName}"></property>-->
<!--    </bean>-->
<!--    <bean id="person" class="com.zhang.bean.Person">-->
<!--        <property name="name" value="${jdbc.username}"></property>-->
<!--    </bean>-->
<!--    spring中的自動裝配--><bean id="address" class="com.zhang.bean.Address"><property name="province" value="河北"></property><property name="city" value="邯鄲"></property><property name="town" value="武漢"></property></bean>
<!--    <bean id="address2" class="com.zhang.bean.Address">-->
<!--        <property name="province" value="河北2"></property>-->
<!--        <property name="city" value="邯鄲2"></property>-->
<!--        <property name="town" value="武漢2"></property>-->
<!--    </bean>-->
<!--    在spring中,可以使用自動裝配的功能,spring會把某些bean注入到另外的bean中
可以使用autowire屬性來實現自動裝配,有一下幾種情況
default/no:不裝配
byName:按照id進行裝配,根據set方法的后面的名稱首字母小寫決定的,不是參數列表的名稱
byType:按照bean的類型來進行裝配,但是如果有多個類型,就會報錯,不知道選擇哪一個具體的類型
constructor:按照構造器進行裝配,首先按照類型進行判斷,如果有多個類型相同的bean,再按照id進行判斷
--><!--    為什么使用bytype的時候會加載環境變量出來
環境變量中存儲的就是key:valve會放到那里面,換一種類型就不會了
--><!--    <bean id="person" class="com.zhang.bean.Person" autowire="constructor"></bean>-->
<!--    SpEL表達式語言的使用--><bean id="person2" class="com.zhang.bean.Person">
<!--可以引入bean對象的屬性-->
<property name="name" value="#{address.province}"></property>
<!--可以支持運算符的所有操作--><property name="age" value="#{2*3}"></property>
<!--可以使用外部bean--><property name="address" value="#{address}"></property>
<!-- 可以調用靜態方法-->
<property name="hobbies" value="#{T(java.util.UUID).randomUUID().toString().substring(0,4)}"></property>
<!--調用非靜態方法--><property name="gender" value="#{address.getCity()}"></property></bean>
</beans>

properties

jdbc.username=root
jdbc.password=1234
url=jdbc:mysql://localhost:3306/test
driverClassName=com.mysql.jdbc.Driver
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.zhang</groupId><artifactId>spring_study02</artifactId><version>1.0-SNAPSHOT</version><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.5</version></dependency><!-- https://mvnrepository.com/artifact/com.alibaba/druid --><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.6</version></dependency><!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.48</version></dependency></dependencies>
</project>

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/920233.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/920233.shtml
英文地址,請注明出處:http://en.pswp.cn/news/920233.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

elasticsearch 7.17.23 使用spring data es實現高亮分頁,scroll查詢分頁查詢

一 介紹 1.1 工程結構 1.2 啟動elasticsearch服務 1.3 高亮分頁 DeepSeek 代碼 效果&#xff1a; 1.4 scroll分頁 代碼 2.效果 后臺日志 1.5 完整代碼 https://gitee.com/jurf-liu/es-2.17.x-demo.git

onlyoffice整合springboot+vue實現文檔在線編輯保存

項目上需要用到在線word、excel文檔編輯功能&#xff0c;通過游覽器在線打開一個遠程的word文檔編輯保存&#xff0c;這里記錄下整合思路。 onlyoffice簡介 ONLYOFFICE 是一款開源的辦公套件&#xff0c;提供了一系列在線文檔編輯和協作工具&#xff0c;適用于團隊和個人使用…

Linux筆記10——shell編程基礎-4

補充$#——取參數個數“$n”,有值取值&#xff0c;無值取空字符&#xff0c;一般都會加引號&#xff0c;在某些情況下避免報語法錯誤一、read接收鍵盤輸入[rootlocalhost ~]# cat demo.sh #!/bin/bash echo -n "請輸入你的姓名&#xff1a;" read nameecho "你…

(Redis)過期刪除策略

1. 背景Redis 支持為 Key 設置過期時間&#xff08;TTL&#xff09;&#xff0c;讓數據在一定時間后自動失效。 例如&#xff1a;SET session:1001 "userA" EX 60 # 60 秒后過期但是問題來了&#xff1a;Key 到期后&#xff0c;Redis 什么時候、如何刪除它&#xf…

nodejs 集成mongodb實現增刪改查

初始化項目: npm init -y npm install mongoose -save 安裝mongoose 插件 mongoose 鏈接數據庫語法&#xff1a; mongodb://[username:password]host1[:poert1],host2[:port2]…/[databsase]?[options…] userame&#xff1a; 用戶名 passwrod: 密碼 host1:port1,host2:port…

音視頻學習(五十八):STAP-A模式

什么是 STAP-A&#xff1f; STAP-A 是一種特殊的 RTP 封裝機制&#xff0c;專為 H.264 和 H.265 這類視頻編碼協議設計。它的核心目的只有一個&#xff1a;將多個小的 NALU&#xff08;網絡抽象層單元&#xff09;打包進一個 RTP 包中&#xff0c;以此來減少網絡開銷&#xff0…

管理型交換機通過VLAN劃分實現不同IP跨網段通信配置方法

管理型交換機應用場景豐富&#xff0c;如果要實現不同IP跨網段通信(比如172.22.106.X和192.168.100.X實現通信)&#xff0c;通過VLAN劃分是可以滿足&#xff0c;下面分享基于弱三層交換機RTL9301方案核心模塊SW-24G4F-301EM配置方法&#xff01; 1. 一般結合交換機的應用場景&a…

什么是高防服務器?如何進行防御?

高防服務器是指能為用戶提供防御網絡攻擊&#xff0c;是主要針對DDOS等流量型攻擊能力的服務器&#xff0c;通過部署專業的硬件設備與軟件系統&#xff0c;具備高帶寬、大流量清洗能力&#xff0c;能有效抵御各類惡意流量沖擊&#xff0c;確保服務器穩定運行&#xff0c;保障網…

SW - 增加導出STL數據中的三角面數,增加別人逆向建模的難度

文章目錄SW - 增加導出STL數據中的三角面數&#xff0c;增加別人逆向建模的難度概述筆記SW版本導出時&#xff0c;選擇STL的導出選項默認導出(精細)導出粗糙自定義導出 - 將誤差和角度改為最大自定義導出 - 將誤差,角度,三角面數改為最大備注這幾天的感想關于我不參考人家零件&…

四十一、【高級特性篇】API 文檔驅動:OpenAPI/Swagger 一鍵導入測試用例

四十一、【高級特性篇】API 文檔驅動:OpenAPI/Swagger 一鍵導入測試用例 前言 準備工作 第一部分:后端實現 - OpenAPI 解析與批量創建 API 1. 創建 OpenAPI 解析服務 2. 創建批量用例導入 API 3. 注冊新 API 路由 第二部分:前端實現 - OpenAPI 導入界面 1. 更新 `api/testca…

K8S-Service資源對象

一、概述在kubernetes中&#xff0c;pod是應用程序的載體&#xff0c;我們可以通過pod的ip來訪問應用程序&#xff0c;但是pod的ip地址不是固定的&#xff0c;這也就意味著不方便直接采用pod的ip對服務進行訪問。為了解決這個問題&#xff0c;kubernetes提供了Service資源&…

【STM32】CubeMX(十三):RT-THREAD

本篇博客描述的是 RT-Thread STM32 CubeMX 的使用方法。本文也為大家提供了基于 STM32 使用 CubeMX 添加 RT-Thread 并創建閃爍 LED 任務 的操作流程。 便于您更好的理解。 一、RT-Thread 是什么&#xff1f; RT-Thread 是一個開源、輕量級的實時操作系統&#xff0c;適用于…

基于Ubuntu22.04系統PaddleX和PaddleClas訓練推理MMAFEDB人臉表情識別數據集(詳細教程)

目錄 基于Ubuntu22.04系統PaddleX和PaddleClas訓練推理MMAFEDB人臉表情識別數據集(詳細教程) 超實用的Paddle圖像分類訓練推理教程&#xff0c;助力深度學習研究&#xff01; 1、環境準備(重要???) 構建虛擬環境 安裝PaddlePaddle 安裝PaddleX 安裝PaddleClas插件 2…

Mistral AI音頻大模型Voxtral解讀

1. 引言 傳統的語音處理系統(如OpenAI的Whisper)在ASR任務上取得了巨大成功,能將語音高精度地轉換為文本。但這只是第一步。真正的“語音理解”意味著: 內容推理:不僅知道說了什么,還能理解話語背后的含義、情感和意圖。 長篇摘要:能夠聽完一段長達數十分鐘的播客或會議…

使用Docker+WordPress部署個人博客

一、通過docker compose 自動一鍵部署WordPress 1. 準備工作 安裝 Docker 和 Docker Compose確保服務器有公網 IP&#xff08;如果需要外部訪問&#xff09;域名&#xff08;可選&#xff0c;用于綁定網站&#xff09; 2. 創建 Docker Compose 配置文件 創建一個docker-compose…

http與https配置

Web 服務詳解&#xff1a;HTTP 與 HTTPS 配置 一、HTTP 服務概述 HTTP&#xff08;Hypertext Transfer Protocol&#xff0c;超文本傳輸協議&#xff09;是用于在網絡上傳輸網頁數據的基礎協議&#xff0c;默認使用80 端口&#xff0c;以明文形式傳輸數據。常見的 HTTP 服務軟件…

Python爬蟲實戰:研究amazon-scrapy,構建亞馬遜電商數據采集和分析系統

1 引言 1.1 研究背景 電子商務的高速發展使電商平臺成為數據價值的核心載體。亞馬遜作為全球領先的電商生態,截至 2024 年第二季度,其平臺商品總量突破 1.5 億,日均活躍用戶超 3 億,每日產生 PB 級的交易數據與用戶行為記錄。這些數據包含商品特征(價格、規格、品牌)、…

基于ERNIE 4.5的多智能體協作的自動化視頻輿情分析報告生成器

多智能體協作的自動化視頻輿情分析報告生成器 1. 項目的意義與價值 從“非結構化視頻”中挖掘“結構化洞察”的通用挑戰 在當今的數字生態中&#xff0c;視頻已成為信息傳播、知識分享和消費者意見表達的核心媒介。從企業內部的會議錄屏、技術培訓&#xff0c;到外部的市場宣傳…

Java全棧開發面試實錄:從基礎到實戰的深度解析

Java全棧開發面試實錄&#xff1a;從基礎到實戰的深度解析 面試官與應聘者的對話記錄 第一輪&#xff1a;基礎問題與項目背景 面試官&#xff08;中年男性&#xff0c;穿著整潔&#xff09;&#xff1a; 你好&#xff0c;歡迎來到我們公司。我是今天的面試官&#xff0c;可以先…

如何清除webview138、139版本軟鍵盤占用的區域

好的&#xff0c;這個問題非常具體且關鍵。在 Android System WebView 的 138 和 139 版本&#xff08;基于 Chromium 113&#xff09;的上下文中&#xff0c;“清除軟鍵盤占用的區域”通常意味著&#xff1a;在軟鍵盤收起后&#xff0c;WebView 的布局或視口沒有正確恢復&…