9. spring整合其他第三方框架
阿新 • • 發佈:2019-01-12
github原始碼地址:https://github.com/Streamhu/spring_integration
目錄
- 一、MVC框架
1.springMVC - 二、持久層框架
1.mybatis
2.hibernate - 三、快取
1.redis
2.ehcache - 四、定時任務
1.spring-task
2.quartz - 五、校驗框架
1.hibernate validator
一、MVC框架
1.springMVC
1)引入相關jar包
<!-- spring --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.2.5.RELEASE</version > </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.2.5.RELEASE</version> </dependency> <!-- spring-mvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.2.5.RELEASE</version> </dependency>
2)resource目錄下新建spring.xml檔案
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd "> </beans>
3)web.xml配置
<!-- 監聽器啟動spring容器 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- springMVC --> <servlet> <servlet-name>spring-mvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:spring-mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>spring-mvc</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
4)resource目錄下新建spring-mvc.xml檔案,新增如下配置
<!-- 自動掃描的包名 -->
<context:component-scan base-package="com.hh" ></context:component-scan>
<!-- 預設的註解對映的支援 -->
<mvc:annotation-driven />
<!-- 設定預設的靜態資源處理器,不設定配了檢視解析器會報404錯誤 -->
<mvc:default-servlet-handler/>
<!-- 配置檢視解析器,專案中用不到也可以不配 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/html/" />
<property name="suffix" value=".html" />
</bean>
5)新建測試類
@Controller
@RequestMapping(value="/springMVC")
public class SpringmvcController {
@RequestMapping(value="/test")
public String test(){
System.out.println("springMVC配置成功");
return "springMVC";
}
}
二、持久層框架
1.mybatis
1)引入相關jar包
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.2.3</version>
</dependency>
<!-- spring jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<!-- msyql的驅動 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.25</version>
</dependency>
2)新建spring-mybatis.xml配置檔案
<!-- 引入資料庫配置引數檔案jdbc.properties -->
<context:property-placeholder location="classpath:jdbc.properties" ignore-unresolvable="true"/>
<!-- 資料來源,載入jdbc驅動引數 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!-- mybatis檔案配置,mapper.xml檔案掃描 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 自動掃描mapper.xml檔案 -->
<property name="mapperLocations" value="classpath:mapper/*.xml"></property>
<!-- mybatis的config物件,一定要有 -->
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
</bean>
<!-- Mapper介面所在包名,Spring會自動查詢其下的類 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 和對映檔案關聯的dao層 -->
<property name="basePackage" value="com.hh.mybatis.dao" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
</bean>
3)新建jdbc.properties
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/hh?characterEncoding=utf-8
jdbc.username=root
jdbc.password=
4)新建mybatis-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
</configuration>
5)spring.xml檔案中新增
<!-- 引入mybatis配置 -->
<import resource="classpath*:spring-mybatis.xml"/>
6)新建mapper.xml檔案示例
<!-- namespace是和dao介面關聯的地方 -->
<mapper namespace="com.hh.mybatis.dao.UserDao">
<!-- 定義好返回型別 -->
<resultMap type="com.hh.mybatis.User" id="userResultMap" >
<!-- 對映資料庫的欄位 -->
<id property="id" column="id"></id>
<result property="name" column="name"></result>
<result property="address" column="address"></result>
<result property="city" column="city"></result>
</resultMap>
<!-- 查詢所有記錄 -->
<select id="selectAll" resultMap="userResultMap">
select * from user
</select>
</mapper>
2.hibernate
1)引入相關jar包
<!-- hibernate核心包 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.2.5.Final</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
2)新建spring-hibernate檔案題
<!-- 引入資料庫配置引數檔案jdbc.properties -->
<context:property-placeholder location="classpath:jdbc.properties" ignore-unresolvable="true"/>
<!-- 資料來源,載入jdbc驅動引數 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" lazy-init="false">
<!-- 注入datasource,給sessionfactoryBean內setdatasource提供資料來源 -->
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:hibernate.cfg.xml"></property>
<!-- 載入實體類的對映檔案位置及名稱 -->
<property name="mappingLocations" value="classpath:hibernate/*.hbm.xml"></property>
</bean>
<!-- 配置sessionFactory, 這個配合jpa, 在entity層加jpa註解配合使用,從而不需要對映檔案了-->
<!-- <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<!– hibernate自動掃描 實體類–>
<property name="packagesToScan">
<list>
<value>com.hh.hibernate</value>
</list>
</property>
<!– hibernate屬性 –>
<property name="hibernateProperties">
<value>
hibernate.hbm2ddl.auto=${jdbc.hibernate.hbm2ddl.auto}
hibernate.dialect=${jdbc.hibernate.dialect}
hibernate.show_sql=${jdbc.hibernate.show_sql}
</value>
</property>
</bean>-->
3)新建hibernate.cfg.xml檔案
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- 這裡也可以配資料庫相關配置 -->
<!-- 資料庫方法配置,hibernate在執行的時候,會根據不同的方言生成符合當前資料庫語法的sql -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 2. 其他相關配置 -->
<!-- 2.1 顯示hibernate在執行時候執行的sql語句 -->
<property name="hibernate.show_sql">true</property>
<!-- 2.2 格式化sql -->
<property name="hibernate.format_sql">true</property>
<!-- 2.3 自動建表 -->
<property name="hibernate.hbm2ddl.auto">update</property>
</session-factory>
</hibernate-configuration>
4)spring.xml檔案中新增
<!-- 引入hibernate配置 -->
<import resource="classpath*:spring-hibernate.xml"/>
5)新建示例hbm.xml檔案
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2016-3-15 16:30:05 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="com.hh.hibernate.User" table="user">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="native" />
</id>
<property name="name" type="java.lang.String">
<column name="name" />
</property>
<property name="address" type="java.lang.String">
<column name="address" />
</property>
<property name="city" type="java.lang.String">
<column name="city" />
</property>
</class>
</hibernate-mapping>
6) 測試類
@Repository
public class HibernateUserDao {
@Resource
SessionFactory sessionFactory;
public List<User> getUserList(){
Session session = sessionFactory.openSession();
String hsql = "from User";
Query query = session.createQuery(hsql);
List<User> userList= query.list();
return userList;
}
}
三、快取
1.redis(有3種方式,目前用的是redisTemplate)
1) 引入相關jar包
<!-- redis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.6.1.RELEASE</version>
</dependency>
2)新建spring-redis.xml
<!-- 引入資料庫配置引數檔案jdbc.properties -->
<context:property-placeholder location="classpath:redis.properties" ignore-unresolvable="true"/>
<!-- redis 的配置資訊 -->
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!-- 最大連線數 -->
<property name="maxTotal" value="${redis.pool.maxTotal}"></property>
<!-- 最大空閒數:空閒連結數大於maxIdle時,將進行回收 -->
<property name="maxIdle" value="${redis.pool.maxIdle}"/>
<!-- 最大等待時間:單位ms -->
<property name="maxWaitMillis" value="${redis.pool.maxWait}"></property>
<!-- 逐出連線的最小空閒時間 :單位ms -->
<property name="minEvictableIdleTimeMillis" value="${redis.pool.minEvictableIdleTimeMillis}"></property>
<!-- 每次逐出檢查時 逐出的最大數目 -->
<property name="numTestsPerEvictionRun" value="${redis.pool.numTestsPerEvictionRun}"></property>
<!-- 逐出掃描的時間間隔(毫秒) -->
<property name="timeBetweenEvictionRunsMillis" value="${redis.pool.timeBetweenEvictionRunsMillis}"></property>
</bean>
<!-- redis 伺服器中心 -->
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" destroy-method="destroy">
<property name="poolConfig" ref="jedisPoolConfig"></property>
<!-- Redis伺服器地址 -->
<property name="hostName" value="${redis.host}"></property>
<!-- 服務埠 -->
<property name="port" value="${redis.port}"></property>
<!-- 授權密碼 -->
<property name="password" value=""></property>
<!-- 超時時間:單位ms -->
<property name="timeout" value="${redis.timeout}"></property>
<!--啟用使用者執行緒池 -->
<property name="usePool" value="true"></property>
</bean>
<!-- redis操作模板,面向物件的模板 -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory" />
</bean>
3) 新建redis.properties
# redis 伺服器 IP
redis.host=127.0.0.1
# redis 伺服器埠
redis.port=6379
# 超時時間
redis.timeout=3000
#redis.password=123//沒有密碼就不用設定
# 連線池中最大連線數。高版本:maxTotal,低版本:maxActive
redis.pool.maxTotal=200
# 連線池中最大空閒的連線數,控制一個 pool 最多有多少個狀態為 idle 的jedis例項
redis.pool.maxIdle=20
# 連線池中最少空閒的連線數
redis.pool.minIdle=5
# 當連線池資源耗盡時,呼叫者最大阻塞的時間,超時將丟擲異常。單位,毫秒數;預設為-1.表示永不超時。高版本:maxWaitMillis,低版本:maxWait
# 當borrow一個jedis例項時,最大的等待時間,如果超過等待時間,則直接丟擲JedisConnectionException;
redis.pool.maxWait=15000
# 連線空閒的最小時間,達到此值後空閒連線將可能會被移除。負值(-1)表示不移除
redis.pool.minEvictableIdleTimeMillis=30000
# 對於“空閒連結”檢測執行緒而言,每次檢測的連結資源的個數。預設為3
redis.pool.numTestsPerEvictionRun=3
#“空閒連結”檢測執行緒,檢測的週期,毫秒數。如果為負值,表示不執行“檢測執行緒”。預設為-1
redis.pool.timeBetweenEvictionRunsMillis=60000
# 向呼叫者輸出“連結”資源時,是否檢測是有有效,如果無效則從連線池中移除,並嘗試獲取繼續獲取。預設為false。建議保持預設值
# 在borrow一個jedis例項時,是否提前進行alidate操作;如果為true,則得到的jedis例項均是可用的;
redis.pool.testOnBorrow=true
4) 在spring.xml中新增
<!-- 引入redis配置 -->
<import resource="classpath*:spring-redis.xml" />
5)測試類
@Controller
@RequestMapping(value="redis")
public class RedisTemplateController {
@Autowired
protected RedisTemplate redisTemplate;
@RequestMapping(value="template/test")
public String test(){
/*
RedisTemplate提供的常用方法
opsForValue方法:操作具有簡單值的條目
opsForList方法:操作具有list值的條目
opsForSet方法:操作具有set值的條目
opsForZSet方法:操作具有ZSet值(排序的set)的條目
opsForHash方法:操作具有hash值的條目
boundValueOps方法:以繫結指定key的形式,操作具有簡單值的條目
boundListOps方法:以繫結指定key的形式,操作具有list值的條目
boundSetOps方法:以繫結指定key的形式,操作具有set值的條目
boundZSet方法:以繫結指定key的形式,操作具有ZSet值(排序的set)條目
boundHashOps方法:以繫結指定key的形式,操作具有hash值得條目
*/
redisTemplate.boundValueOps("zhangsan").set("張三");
redisTemplate.boundValueOps("hh").set("hello world");
String str = (String) redisTemplate.boundValueOps("hh").get();
System.out.println(str);
System.out.println("redisTemplate配置成功");
return "redisTemplate";
}
}
2. ehcache
1) 引入相關jar包
<!-- ehcache 相關依賴 -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
2)新建spring-ehcache檔案
<!-- 啟用快取註解開關 -->
<cache:annotation-driven />
<!-- 宣告cacheManager -->
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
<property name="cacheManager" ref="ehcache"></property>
</bean>
<!-- cacheManager工廠類,指定ehcache.xml的位置 -->
<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:ehcache-setting.xml"></property>
</bean>
3)新建ehcache-setting.xml檔案
<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
<!-- 磁碟快取位置 -->
<diskStore path="java.io.tmpdir"/>
<!-- 設定快取的預設資料過期策略 -->
<!-- maxElementsInMemory:記憶體中最大快取物件數 -->
<defaultCache
maxElementsInMemory="10000"
eternal="false"
overflowToDisk="true"
timeToIdleSeconds="10"
timeToLiveSeconds="20"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"/>
<!-- 測試快取 -->
<cache name="cacheTest"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="true"
timeToIdleSeconds="10"
timeToLiveSeconds="20"/>
</ehcache>
4)spring.xml中新增如下配置
<!-- 引入ehcache配置 -->
<import resource="classpath*:spring-ehcache.xml" />
5)測試類
@Service
public class EhcacheTestServiceImpl implements EhCacheTestService{
@Override
@Cacheable(value="cacheTest", key="#param")
public String getTimestamp(String param) {
Long timestamp = System.currentTimeMillis();
return timestamp.toString();
}
}
@Controller
@RequestMapping(value="/ehcache")
public class EhcacheController {
@Autowired
private EhCacheTestService ehCacheTestService;
@RequestMapping(value="/test")
public String test() throws InterruptedException {
System.out.println("第一次呼叫:" + ehCacheTestService.getTimestamp("param"));
Thread.sleep(2000);
System.out.println("2秒之後呼叫:" + ehCacheTestService.getTimestamp("param"));
Thread.sleep(11000);
System.out.println("再過11秒之後呼叫:" + ehCacheTestService.getTimestamp("param"));
return "ehcache";
}
}
四、定時任務
1.spring-task
1)不需要引用jar包,spring直接有的,新建spring-task.xml檔案
<!-- 自動掃描的包名 -->
<context:component-scan base-package="com.hh.springTask" ></context:component-scan>
<!-- 不是必配項,但是Spring scheduled-tasks預設是序列執行,時常發生task任務太多,而導致執行任務排隊等待,此時就需要配置並行執行 -->
<task:executor id="executor" pool-size="5" />
<task:scheduler id="scheduler" pool-size="10" />
<!-- 開啟任務註解 -->
<task:annotation-driven executor="executor" scheduler="scheduler" />
<!-- 任務列表(這是xml配置,註解配置是直接在類中寫corn表示式) -->
<bean id="springTaskController" class="com.hh.springTask.SpringTaskController" />
<task:scheduled-tasks>
<task:scheduled ref="springTaskController" method="firstCron" cron="0 0 0 * * ?"/>
</task:scheduled-tasks>
2)spring.xml中引入
<!-- 引入springTask配置 -->
<import resource="classpath*:spring-task.xml" />
3)註解方式程式碼示例:
@Component("TaskJob")
public class SpringTaskAnnotationController {
@Scheduled(cron = "0 0 0 * * ?")
public void job1() {
System.out.println("spring-task註解方式定時任務進行中。。。");
}
}
2. quartz
1)引入相關jar包
<!-- quartz相關依賴-->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
2)新建spring-quartz.xml檔案
<!-- 要執行任務的任務類。 -->
<bean id="testQuartz" class="com.hh.quartz.QuartzController"></bean>
<!-- 將需要執行的定時任務注入JOB中。 -->
<bean id="testJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="testQuartz"></property>
<!-- 任務類中需要執行的方法 -->
<property name="targetMethod" value="doSomething"></property>
<!-- 上一次未執行完成的,要等待有再執行。 -->
<property name="concurrent" value="false"></property>
</bean>
<!-- 基本的定時器,會繫結具體的任務。 -->
<bean id="testTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="testJob"></property>
<property name="cronExpression" value="0 0 0 * * ?"/>
</bean>
<!--配置排程工廠-->
<bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="testTrigger"></ref>
</list>
</property>
</bean>
3)spring.xml中引入
<!-- 引入quartz配置 -->
<import resource="classpath*:spring-quartz.xml" />
4)測試類
public class QuartzController {
public void doSomething() {
System.out.println("quartz定時任務執行中");
}
}
五、校驗框架
1.hibernate validator
1)不需要jar包,直接在springMVC.xml檔案中新增如下配置
<!-- 校驗器 -->
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<!-- hibernate校驗器-->
<property name="providerClass" value="org.hibernate.validator.HibernateValidator" />
<!-- 指定校驗使用的資原始檔,在檔案中配置校驗錯誤資訊,如果不指定則預設使用classpath下的ValidationMessages.properties -->
<property name="validationMessageSource" ref="messageSource" />
</bean>
<!-- 校驗錯誤資訊配置檔案 -->
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<!-- 資原始檔名, 可以不配用預設的,也可以配用自己自定義的 -->
<!-- <property name="basenames">
<list>
<value></value>
</list>
</property>-->
<!-- 資原始檔編碼格式 -->
<property name="fileEncodings" value="utf-8" />
<!-- 對資原始檔內容快取時間,單位秒 -->
<property name="cacheSeconds" value="120" />
</bean>
<!-- 校驗器注入到處理器介面卡中 -->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"/>
<mvc:annotation-driven conversion-service="conversionService" validator="validator"></mvc:annotation-driven>
2)測試實體類
public class Items {
private int id;
@Size(min=1,max=30,message="name字串必須在1到30之間")
private String name;
@NotNull(message="生產日期不能為空")
private Date createtime;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getCreatetime() {
return createtime;
}
public void setCreatetime(Date createtime) {
this.createtime = createtime;
}
}
3)測試controller
@Controller
@RequestMapping(value="/validator")
public class ValidatorController {
@RequestMapping(value="/test")
public String test(@Validated Items items, BindingResult bindingResult){
System.out.println("validator配置成功");
// 獲取檢驗錯誤資訊
if(bindingResult.hasErrors()){
List<ObjectError> allErrors = bindingResult.getAllErrors();
for(ObjectError objectError : allErrors){
System.out.println(objectError.getDefaultMessage());
}
return "validator_error";
}
return "validator_success";
}
}
參考網址
spring整合redis(sping-data-redis)
java之redis篇(spring-data-redis整合)
spring整合redis,整合redis叢集(3種方式都有)
【SpringMVC學習06】SpringMVC中的資料校驗
注:文章是經過參考其他的文章然後自己整理出來的,有可能是小部分參考,也有可能是大部分參考,但絕對不是直接轉載,覺得侵權了我會刪,我只是把這個用於自己的筆記,順便整理下知識的同時,能幫到一部分人。
ps : 有錯誤的還望各位大佬指正,小弟不勝感激