การแคชสามารถกล่าวได้ว่าเป็นวิธีที่มีประสิทธิภาพและง่ายมากในการเพิ่มความเร็วในการตอบสนองการบริการ ในสนามแคชมีเฟรมเวิร์กที่รู้จักกันดีมากมายเช่น Ehcache, Guava, Hazelcast ฯลฯ เป็นฐานข้อมูลคีย์-ค่า Redis ได้กลายเป็นเครื่องมือแคชข้อมูลยอดนิยมเนื่องจากคุณสมบัติของมัน
ด้วยวิธีดั้งเดิมรหัสการประมวลผลแคชจะป่องมาก
ตัวอย่างเช่น: เราจำเป็นต้องเพิ่มฟังก์ชั่นการสืบค้นลงในฟังก์ชั่นแคชซึ่งต้องใช้ประมาณสามขั้นตอน
1. ก่อนที่จะดำเนินการฟังก์ชั่นเราต้องตรวจสอบว่ามีข้อมูลในแคชหรือไม่ หากมีอยู่ให้ส่งคืนข้อมูลแคช
2. หากไม่มีอยู่จะต้องสอบถามในข้อมูลฐานข้อมูล
3. ในที่สุดเก็บข้อมูลในแคช เมื่อฟังก์ชั่นนี้เรียกว่าในครั้งต่อไปคุณสามารถใช้ข้อมูลแคชโดยตรงเพื่อลดแรงกดดันในฐานข้อมูล
ดังนั้นจำเป็นต้องใช้รหัสมากแค่ไหนในการใช้สามขั้นตอนข้างต้น? นี่คือตัวอย่าง:
ส่วนสีแดงในภาพด้านบนคือรหัสเทมเพลตทั้งหมด แต่รหัสที่เกี่ยวข้องกับฟังก์ชั่นนี้จริงๆเท่านั้นที่บัญชีสำหรับ 1/5 สำหรับฟังก์ชั่นทั้งหมดที่จำเป็นต้องใช้ฟังก์ชั่นแคชจำเป็นต้องใช้รหัสเทมเพลตป่อง มันเป็นวิธีแก้ปัญหาที่ไม่เหมาะสมอย่างยิ่ง
แล้วเราจะได้รับรหัสป่องกลับไปเป็นเวลาที่สดใหม่ได้อย่างไร?
AOP ไม่ใช่ทางออกที่ดีที่สุดสำหรับรหัสสไตล์เทมเพลตนี้หรือไม่? โชคดีที่เราไม่จำเป็นต้องใช้ส่วนด้วยตัวเองอีกต่อไป SpringCache ทำให้เรามีส่วนที่ดี เราจำเป็นต้องทำการกำหนดค่าอย่างง่ายเพื่อกลับไปที่แบบดั้งเดิมเช่นต่อไปนี้:
คุณจะต้องเพิ่มคำอธิบายประกอบเท่านั้น คุณไม่จำเป็นต้องเปลี่ยนรหัสต้นฉบับ คุณกระตือรือร้นที่จะลองหรือไม่?
มีเพียงสามขั้นตอนในการกำหนดค่า SpringCache:
ขั้นตอนที่ 1: เพิ่มการพึ่งพาที่เกี่ยวข้อง:
<การพึ่งพา> <roupId> redis.Clients </groupId> <ratifactid> Jedis </artifactid> <version> 2.9.0 </เวอร์ชัน> </การพึ่งพา> <การพึ่งพา> <roupid> org.springframework.data </groupid> <การพึ่งพา> <roupId> org.apache.Commons </groupId> <ratifactId> Commons-Lang3 </artifactId> <version> 3.3.2 </Serve> </การพึ่งพา>
ขั้นตอนที่ 2: กำหนดค่า SpringCache การเชื่อมต่อ Redis และข้อมูลอื่น ๆ
ApplicationContext-redis.xml
<? xml version = "1.0" การเข้ารหัส = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://ww.w3.org/2001/xml xmlns: p = "http://www.springframework.org/schema/p" xmlns: context = "http://www.springframework.org/schema/mvc" xmlns: cache = "http:/ XSI: schemalocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http:/www.springframwork http://www.springframework.org/schema/mvc http://www.springframework.org/schema/MVC/SPRING-MVC-4.2.XSD http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-4.2.xsd "> <! cache-manager = "cachemanager" /> <!-Redis Connection Pool-> <bean id = "poolconfig"> <property name = "maxidle" value = "$ {redis.maxidle}" /> <property name = "maxwaitmillis" value = "$ {redis.maxwait}" />> value = "$ {redis.testonborrow}"/> </ebean> <!-การเชื่อมต่อโรงงาน-> <bean id = "jedisconnectionFactory" p: host-name = "$ {redis.host}" P: port = "$ {redis.port}" เทมเพลต redis-> <bean id = "redistemplate"> <property name = "connectionFactory" ref = "jedisconnectionfactory" /> </ebean> <bean id = "cachemanager"> <property name = "caches"> <et> <! value = "content"/> <!-ชื่อที่สอดคล้องกับชื่อควรใช้ในคำอธิบายประกอบของคลาสหรือวิธีการ-> </ebean> </et> </porement> </ebean> </ebeans>ไฟล์ redis.properties:
# การตั้งค่า redis # เซิร์ฟเวอร์ ip redis.host = 192.168.100.55 # พอร์ตเซิร์ฟเวอร์ redis.port = 6379 # เซิร์ฟเวอร์ผ่าน redis.pass = # ใช้ dbindex redis.database = 0 #max idel อินสแตนซ์ของ jedisredis.maxidle = 300 # อินสแตนซ์ของเจไดส์สิ่งที่คุณได้รับคือทั้งหมดที่เป็นประโยชน์
ขั้นตอนที่สามคือการเขียนคลาสการใช้งานอินเตอร์เฟสแคช
สปริงให้เฉพาะอินเทอร์เฟซนามธรรมสำหรับแคชและฟังก์ชั่นการโทรผ่านอินเตอร์เฟส ไม่มีคลาสการใช้งานที่เฉพาะเจาะจงดังนั้นเราจำเป็นต้องใช้การดำเนินการเฉพาะด้วยตนเอง
ในการกำหนดค่าข้างต้นเราจะเห็นว่าแต่ละคลาสการใช้งานจะฉีดอินสแตนซ์ redistemplate และเราสามารถใช้งาน REDIS ผ่าน Redistemplate
แพ็คเกจ com.cky.rest.utils; นำเข้า java.io.serializable; นำเข้า org.apache.commons.lang3.serializationutils; นำเข้า org.springframework.cache.cache; นำเข้า org.springframework.cache.support.simplev org.springframework.dao.dataaccessexception; นำเข้า org.springframework.data.redis.connection.redisconnection; นำเข้า org.springframework.data.redis.core.rediscallback; Redistemplate <String, Object> Redistemplate; ชื่อสตริงส่วนตัว; @Override โมฆะสาธารณะ Clear () {System.out.println ("---------------"); redistemplate.execute (ใหม่ rediscallback <string> () {@Override สตริงสาธารณะ doinredis (การเชื่อมต่อ redisconnection) พ่น dataAccessException {connection.flushdb (); return "ok";}}); } @Override โมฆะสาธารณะ Evict (คีย์วัตถุ) {System.out.println ("-----------------"); สตริงสุดท้าย keyf = key.toString (); redistemplate.execute (ใหม่ rediscallback <long> () {@Override สาธารณะยาว doinredis (การเชื่อมต่อ redisconnection) พ่น dataAccessException {return connection.del (keyf.getBytes ());}}); } @Override ValueWrapper รับ (คีย์วัตถุ) {System.out.println ("-----------------------"+key.toString ()); สตริงสุดท้าย keyf = key.toString (); วัตถุวัตถุ = null; Object = redistemplate.execute (ใหม่ retiscallback <Ojrop> () {@Override วัตถุสาธารณะ doinredis (การเชื่อมต่อการเชื่อมต่อ redisconnection) โยน dataAccessException {byte [] key = keyf.getBytes (); byte [] value = connection.get (key); ถ้า (value == null) serializationutils.deserialize (ค่า);}}); ValueWrapper OBJ = (Object! = null? ใหม่ SimpleValuewRapper (วัตถุ): NULL); System.out.println ("---------------------------------"+OBJ); คืน OBJ; } @Override โมฆะสาธารณะใส่ (คีย์วัตถุค่าวัตถุ) {system.out.println ("-----------------------"); System.out.println ("คีย์ ----:"+คีย์); System.out.println ("คีย์ ----:"+ค่า); คีย์สตริงสุดท้าย = key.toString (); ค่าวัตถุสุดท้าย = ค่า; LIVETIME สุดท้าย = 86400; redistemplate.execute (ใหม่ retiscallback <long> () {@Override สาธารณะยาว doinredis (การเชื่อมต่อการเชื่อมต่อ redisconnection) พ่น dataAccessException {byte [] keyb = keystring.getBytes (); byte [] valueB = serializationutils.serialize (serializable) การเชื่อมต่อ expire (keyb, livetime); } @Override สาธารณะ <t> t get (Object Arg0, คลาส <t> arg1) {// วิธีการที่สร้างขึ้นอัตโนมัติ todo stub return null; } @Override สตริงสาธารณะ getName () {return this.name; } @Override วัตถุสาธารณะ getNativeCache () {return this.redistemplate; } @Override Public ValueWrapper Putifabsent (Object Arg0, Object arg1) {// วิธีการที่สร้างขึ้นอัตโนมัติ todo stub return null; } Public Redistemplate <String, Object> GetRedistemplate () {return redistemplate; } โมฆะสาธารณะ setredIstemplate (redistemplate <string, object> redistemplate) {this.redistemplate = redistemplate; } โมฆะสาธารณะ setName (ชื่อสตริง) {this.name = name; -มีข้อผิดพลาดสองข้อในระหว่างกระบวนการกำหนดค่า:
1.xxxx.classNotFoundException ในที่สุดฉันพบว่าการดาวน์โหลด JAR นั้นไม่สมบูรณ์ เพียงแค่ลบโฟลเดอร์แพ็คเกจ JAR ที่สอดคล้องกันของที่เก็บ Maven Local และดาวน์โหลดอีกครั้ง
2.xxxx.methodnotFoundException สถานการณ์นี้เป็นเวอร์ชันที่ไม่ถูกต้องเพียงแค่เปลี่ยนเป็นเวอร์ชันในขั้นตอนแรก
การใช้คำอธิบายประกอบทั่วไปใน SpringCache:
@คำอธิบายประกอบ
คำอธิบายประกอบที่ใช้กันมากที่สุดจะแคชค่าส่งคืนของวิธีการใส่คำอธิบายประกอบ วิธีการทำงานคือ: ค้นหาก่อนในแคชหากไม่มีการดำเนินการวิธีการและผลลัพธ์จะถูกแคชแล้วข้อมูลจะถูกส่งคืน ชื่อแคชของคำอธิบายประกอบนี้จะต้องระบุและสอดคล้องกับค่าชื่อของแคชในแคชใน CacheManager สามารถระบุได้โดยใช้ค่าหรือชื่อ cachenames
หากไม่มีการระบุแอตทริบิวต์คีย์สปริงจะใช้เครื่องกำเนิดคีย์หลักเริ่มต้นเพื่อสร้างคีย์หลัก คุณยังสามารถปรับแต่งคีย์หลักและสามารถใช้นิพจน์ Spel ได้ในคีย์ ดังนี้:
@Cacheable (cachenames =” เนื้อหา”, key =”#user.userid”) ผู้ใช้สาธารณะ GetUser (ผู้ใช้ผู้ใช้) {xxxxx}คุณสามารถใช้แอตทริบิวต์เงื่อนไขเพื่อเพิ่มเงื่อนไขลงในแคชดังนี้:
@Cacheable (cachenames =” เนื้อหา”, key =”#user.userid”, เงื่อนไข =”#user.age <40”) ผู้ใช้สาธารณะ Getuser (ผู้ใช้ผู้ใช้) {xxxxx}@CachePut คำอธิบายประกอบ
ดำเนินการวิธีการก่อนจากนั้นนำค่าคืนกลับเข้าไปในแคช สามารถใช้เป็นการอัปเดตแคช
@CacheEvict คำอธิบายประกอบ
คำอธิบายประกอบนี้มีหน้าที่ในการลบข้อมูลออกจากแคชอย่างชัดเจน โดยปกติแล้วข้อมูลแคชจะมีวันหมดอายุและข้อมูลจะถูกลบออกเมื่อหมดอายุ
คำอธิบายประกอบนี้มีสองแอตทริบิวต์เพิ่มเติม:
ไม่ว่าจะเป็นการลบรายการแคชทั้งหมดหรือไม่
ก่อนหน้านี้: เสร็จสิ้นการดำเนินการลบก่อนหรือหลังวิธีการเรียก จริง/เท็จ
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น