الفصل 1 تحليل متطلبات
من المخطط إضافة redis لتنفيذ معالجة ذاكرة التخزين المؤقت في مشروع المصدر المفتوح للفريق. نظرًا لأن وظائف العمل قد تم تنفيذها جزئيًا ، من خلال كتابة فصول أدوات REDIS ثم الإشارة إليها ، فإن مقدار التغييرات كبير ، ولا يمكن تحقيق فك الارتباط ، لذلك فكرت في AOP (البرمجة المتجهزة المقطوعة) لإطار الربيع.
مشروع مفتوح المصدر: https://github.com/U014427391/jeepatform
الفصل 2 مقدمة إلى سبرينغ بوت
باعتباره إطارًا مهمًا مفتوح المصدر في مجال Javaee Framework ، يلعب Spring Framework دورًا مهمًا في تطوير تطبيقات المؤسسة. في الوقت نفسه ، فإن إطار عمل الربيع والإطارات الفرعية له كثيرًا ، وبالتالي فإن مقدار المعرفة واسع للغاية.
Springboot: إطار فرعي من Framework Spring ، يسمى أيضًا MicrofRamework ، هو إطار تم إطلاقه في عام 2014 يجعل تطوير Spring Framework سهلاً. بعد تعلم جميع المعرفة بأطر الربيع ، تتطلب أطر الربيع حتماً الكثير من XML. إذا كنت تستخدم Springboot Frameworks ، فيمكنك استخدام تطوير التعليقات التوضيحية لتبسيط التطوير بشكل كبير استنادًا إلى أطر الربيع. يستفيد Springboot الكامل لوضع تكوين JavaconFig ومفهوم "الاتفاقية أفضل من التكوين" ، والذي يمكن أن يبسط بشكل كبير تطوير تطبيقات الويب وخدمات REST استنادًا إلى SpringMVC.
الفصل 3 مقدمة إلى redis
3.1 Redis تركيب ونشر (Linux)
لتثبيت Redis ونشره ، يرجى الرجوع إلى مدونتي (Redis مكتوب على أساس C ، لذلك قم بتثبيت برنامج التحويل البرمجي قبل التثبيت): //www.vevb.com/article/79096.htm
3.2 مقدمة إلى Redis
أصبحت Redis الآن واحدة من أكثر قواعد البيانات شعبية في مجتمع تطوير الويب. مع التطوير السريع لـ Web2.0 وزيادة نسبة البيانات شبه المنظمة ، فإن المواقع الإلكترونية لديها المزيد والمزيد من المطالب للأداء الفعال.
علاوة على ذلك ، تحتوي المواقع الكبيرة بشكل عام على مئات أو أكثر من خوادم Redis. كنظام قوي ، يتمتع Redis باستخدامه الخاص ، سواء كان نظام التخزين أو قائمة الانتظار أو ذاكرة التخزين المؤقت.
للبدء في Springboot Framework ، يرجى الرجوع إلى المقالة السابقة: http://www.vevb.com/article/111197.htm
الفصل 4 تنفيذ ذاكرة التخزين المؤقت
4.1 مخطط الهيكل التالي
مخطط هيكل المشروع:
4.2 تكوين ملف YML من Springboot
أضف Application.YML تكوين أسفل المورد ، حيث يتم تكوين MySQL و Druid و Redis بشكل أساسي
الربيع: DataSource: # متجر مصدر البيانات الرئيسي: url: jdbc: mysql: //127.0.0.1: 3306/jeepatform؟ autoreConnect = true & useUnicod com.Alibaba.druid.pool.druiddatasource # إعدادات تجمع الاتصال Druid: الحجم الأولي: 5 دقائق من المعدل: 5 أقصى نشاط: 20 # تكوين الوقت للحصول على الوقت في انتظار المهلة ، max-wait: 60000 # التكوين كم من الوقت يستغرق أداء فاصل الاكتشاف لاكتشاف الاتصالات الخاطئة التي تحتاج إلى أن تكون مغلقة في الميل. قم بتكوين الحد الأدنى للوقت للبقاء على قيد الحياة في التجمع ، بالمللي ثانية من القدر من الأوقات غير القابلة للتطبيق: 300000 # Oracle يرجى استخدام SELECT 1 من مسابقة التحقق من الصحة المزدوجة: حدد "X 'Test-the-idle: True Test-On Barrow: False-on-on-in-in-return Max-Pool-Pool-Proped-Statement-Per-Connection-Size: 20 # تكوين مرشحات لمراقبة إحصائيات اعتراض. بعد إزالة واجهة المراقبة ، لا يمكن حساب SQL ، يتم استخدام "الجدار" في مرشحات جدار الحماية: STAT ، الجدار ، SLF4J # Open MergesQl من خلال خاصية ConnectProperties ؛ سجلات SQL SQL البطيئة-droperties: druid.stat.mergesql = true ؛ druid.stat.slowsqlmillis = 5000 # Derge Monitoring Data of MultivedDataSource Use-Global-data-Source: true jpa: database: mysql hibernate: show_sql. تسمية: strategy الفيزيائية: org.hibernate.boot.model.naming.physicalnamingstrategystandArdImpl MVC: عرض: بادئة:/web-inf/jsp/faceix MaxWaitMillis: 100000
اكتب فئة التكوين لبدء التكوين jedisconfig.java:
package org.muses.jeepatform.config ؛ استيراد org.springframework.beans.factory.annotation. org.springframework.boot.autoconfigure.condition.conditionalonmissingbean ؛ استيراد org.springframework.boot.context.properties.configurationProperties ؛ استيراد org.springframework.context.annotation.bean ؛ org.springframework.context.annotation.configuration ؛ import redis.clients.jedis.jedispool ؛ import redis.clients.jedis.jedispoolconfig ؛@configuration //@configroperties (prefix = jedisconfig.jedis_prefix) = "جيديس" ؛ bean (name = "jedispool") Autowired العامة jedispool jedispool (QAlifier ("jedispoolconfig") value ("$ {spring.jedis.pool.timeout}") int timeout ، value ("$ {spring.jedis.pool.password}") سلسلة كلمة مرور) } bean (name = "jedispoolconfig") العامة jedispoolconfig jedispoolconfig ( @value ("$ {spring.jedis.pool.config.maxtotal}") int maxtotal ، @value ($ {spring.jedis.pool.pool.maxidle} ") int maxid value ("$ {spring.jedis.pool.config.maxwaitmillis}") int maxwaitmillis) {jedispoolconfig config = new jedispoolconfig () ؛ config.setMaxTotal (maxtotal) ؛ config.setMaxidle (maxidle) ؛ config.setMaxWaitMillis (maxwaitmillis) ؛ إرجاع التكوين. }}4.3 كتابة فئة التعريف
اكتب فئة التعليقات التوضيحية meta rediscache.java. يتم تنفيذ جميع الفئات المحددة بواسطة التعليقات التوضيحية المعدلة تلقائيًا في معالجة ذاكرة التخزين المؤقت AOP.
package org.muses.jeepatform.annotation ؛ استيراد org.muses.jeepatform.common.rediscachenamespace ؛ استيراد java.lang.annotation. {// rediscachenamespace اسم اسم الاسم () ؛} بالإضافة إلى الاستبقاء ، هناك ثلاثة تعليقات توضيحية أخرى مقدمة من JDK 5 ، وهي الهدف والورث والتوثيق. بناءً على ذلك ، يمكننا تنفيذ تعليقات التعريف المخصصة
قمنا بتعيين Rediscache إلى الإشارة بناءً على مستوى الطريقة.
1.TreentionPolicy.Source هذا النوع من التعليقات التوضيحية محفوظة فقط على مستوى الكود المصدر وسيتم تجاهله أثناء التجميع.
2. attreencepolicy.class يتم الاحتفاظ بهذا النوع من التعليقات التوضيحية أثناء التجميع ويوجد في ملف الفصل ، لكن JVM سوف يتجاهله.
3. attreencepolicy.runtime سيتم حجز هذا النوع من التعليقات التوضيحية من قبل JVM ، بحيث يمكن قراءتها واستخدامها من قبل JVM أو رمز آخر يستخدم آليات الانعكاس في وقت التشغيل.
4.4 استدعاء Jedispool لتنفيذ معالجة ذاكرة التخزين المؤقت
package org.muses.jeepatform.cache ؛ استيراد org.springframework.beans.factory.Antow.autowired ؛ استيراد org.springframework.stereotype.component ؛ import org.springframework.stereopee.service ؛ import. javax.annotation.resource ؛ @component ("rediscache") الفئة العامة rediscache {autowired jedispool jedispool ؛ الخاص jedispool getjedispool () {return jedispool ؛ } public void setjedispool (jedispool jedispool) {this.jedispool = jedispool ؛ } / ** * احصل على بيانات من Redis Cache * param rediskey * @return * / كائن عام getDataFromredis (string rediskey) {jedis jedis = jedispool.getResource () ؛ byte [] bytearray = jedis.get (rediskey.getBytes ()) ؛ if (bytearray! = null) {return serializeutil.unserialize (bytearray) ؛ } إرجاع فارغ ؛ } / ** * حفظ البيانات إلى redis * param rediskey * / السلسلة العامة saveAdatatorEdis (string rediskey ، object obj) {byte [] bytes = serializeutil.serialize (obj) ؛ jedis jedis = jedispool.getResource () ؛ رمز السلسلة = jedis.set (rediskey.getBytes () ، بايت) ؛ رمز الإرجاع ؛ }}فئة أداة التسلسل الكائن:
حزمة org.muses.jeepatform.cache ؛ استيراد java.io.* ؛ الطبقة العامة serializeutil { / *** كائن تسلسلي* param obj* regurn* / public static byte [] Serialize (object obj) {objectutputstream oos = null ؛ bytearrayoutputstream baos = null ؛ حاول {baos = new bytearrayoutputStream () ؛ OOS = جديد ObjectOutputStream (BAOS) ؛ OOS.WriteObject (OBJ) ؛ byte [] bytearray = baos.tobytearray () ؛ إرجاع bytearray ؛ } catch (ioException e) {E.PrintStackTrace () ؛ } إرجاع فارغ ؛ } / ** * deserialize object * param bytearray * @return * / كائن ثابت public donserialize (byte [] bytearray) {bytearrayinputStream bais = null ؛ حاول {// deserialize to object bais = new bytearrayinputStream (bytearray) ؛ ObjectInputStream OIS = New ObjectInputStream (BAIS) ؛ إرجاع OIS.ReadObject () ؛ } catch (استثناء e) {E.PrintStackTrace () ؛ } إرجاع فارغ ؛ }} هنا أتذكر أن فصول VO يجب أن تنفذ قابلة للتسلسل
على سبيل المثال ، فئة VO معلومات القائمة ، هذه فئة كيان من رسم الخرائط JPA
package org.muses.jeepatform.core.entity.admin ؛ استيراد javax.persistence.* ؛ استيراد java.io.serializable ؛ استيراد java.util.list ؛/*** @ @ @ @ @intity intity serial intity serialize intity serialize serialize serialize serialize serialize serialize serialize serialize serialize serialize serialible / ** معرف القائمة ** / private int menuid ؛ / ** معرف Superior **/ Private Int ParentId ؛ / ** اسم القائمة **/ سلسلة خاصة menuname ؛ / ** أيقونة القائمة **/ السلسلة الخاصة menuicon ؛ / ** url url **/ private string menuurl ؛ / ** نوع القائمة **/ سلسلة خاصة menutype ؛ / ** القائمة فرز **/ سلسلة السلسلة الخاصة ؛ / ** حالة القائمة **/ سلسلة خاصة menustatus ؛ قائمة خاصة <menu> القائمة الفرعية ؛ هدف السلسلة الخاصة ؛ خاص منطقي Hassubmenu = خطأ ؛ القائمة العامة () {super () ؛ } idgeneratedValue (strategy = genertype.Identity) public int getMenuid () {return this.menuid ؛ } public void setMenuid (int menuid) {this.menuid = menuid ؛ } column (length = 100) public int getParentId () {return parentId ؛ } public void setParentId (int parentId) {this.parentId = parentId ؛ } column (length = 100) سلسلة عامة getMenUname () {return this.menuname ؛ } public void setMenuname (String menuname) {this.menuname = menuname ؛ } column (length = 30) سلسلة عامة getMenuicon () {return this.menuicon ؛ } public void setMenuicon (String menuicon) {this.menuicon = menuicon ؛ } column (length = 100) سلسلة عامة getMenuurl () {return this.menuurl ؛ } public void setMenuurl (String menuurl) {this.menuurl = menuurl ؛ } column (طول = 100) سلسلة عامة getMenUtype () {return this.menutype ؛ } public void setMenUtype (String menutype) {this.menUtype = menutype ؛ } column (طول = 10) سلسلة عامة getMenuorder () {return menuorder ؛ } public void setMenuOrder (String menuorder) {this.menuorder = menuorder ؛ } column (طول = 10) سلسلة عامة getMenustatus () {return menustatus ؛ } public void setMenustatus (String menustatus) {this.menustatus = menustatus ؛ } transient public list <MANE> GETUBMENU () {return submenu ؛ } public void setSubMenu (قائمة <Mens> submenu) {this.submenu = submenu ؛ } public void settarget (سلسلة الهدف) {this.target = target ؛ } transient public string getTarget () {return target ؛ } public void sethassubmenu (boolean hassubmenu) {this.hassubmenu = hassubmenu ؛ } transient public boolean gethassubmenu () {return hassubmenu ؛ }}4.5 الربيع AOP ينفذ طريقة ذاكرة التخزين المؤقت التي تراقب جميعها المشروح بواسطة RERESCACHER
احصل أولاً على ذاكرة التخزين المؤقت من redis. إذا لم تتمكن من الاستعلام عنها ، فقم بالاستعلام عن قاعدة بيانات MySQL ، ثم احفظها على ذاكرة التخزين المؤقت Redis. في المرة القادمة التي تستفسر فيها ، اتصل بـ Redis Cache مباشرة.
package org.muses.jeepatform.cache ؛ import org.aspectj.lang.proceedingjoinpoint ؛ import org.aspectj.lang.annotation.around ؛ import org.aspectj.lang.annotation.aspect org.slf4j.loggerfactory ؛ استيراد org.springframework.beans.factory.Antow.autowired ؛ استيراد org.springframework.beans.factory.annotation.qualifier redisaspect {private static final logger = loggerfactory.getLogger (redisaspect.class) ؛ AUTOWIRED QALIFIER ("rediscache") private rediscache rediscache ؛ /*** طرق لاعتراض جميع شرح التعليقات التوضيحية التعليقات التعليقات التوضيحية* / @pointcut (" @enrotation (org.muses.jeepatform.annotation.rediscache)") pincecutmethod public void () {} /*** للمعالجة المحيطة ، احصل أولاً على cache من redis. إذا لم تتمكن من الاستعلام ، فأنت تستفسر عن قاعدة بيانات MySQL ، * ثم احفظها على إعادة ذاكرة التخزين المؤقت * param JoinPoint * @REGRUNT */AROUND ("PointCutMethod ()") كائن عام حول (systemjoinpoint joinpoint) {// السابق: الحصول على cache من إعادة // أولاً الحصول على طريقة التشغيل المستهدفة سلسلة applid = null ؛ Object [] args = joinpoint.getargs () ؛ if (args! = null && args.length> 0) {applid = string.valueof (args [0]) ؛ } // احصل على الفئة حيث توجد طريقة الهدف الهدف من الهدف = joinpoint.getTarget (). toString className = target.split ("@") [0] ؛ // احصل على اسم طريقة سلسلة الأسلوب الهدف methodName = JoinPoint.getSignature (). getName () ؛ // redis مفتاح التنسيق: applid: method name string rediskey = applid + ":" + className + "." + methodname ؛ Object obj = rediscache.getDataFromredis (rediskey) ؛ if (obj! = null) {logger.info ("************ بيانات موجودة من redis ****************") ؛ logger.info ("redis مفتاح القيمة:"+rediskey) ؛ logger.info ("قيمة redis قيمة:"+obj.toString ()) ؛ إرجاع OBJ ؛ } long endtime = system.currentTimeMillis () ؛ logger.info ("Redis Cache AOP الوقت:"+(Endtime-StartTime)) ؛ logger.info ("*************** لا توجد بيانات موجودة من redis ******************") ؛ حاول {obj = joinpoint.proceed () ؛ } catch (throwable e) {E.PrintStackTrace () ؛ } logger.info ("*************** ابدأ في الاستعلام عن البيانات من mysql *************") ؛ // post-set: احفظ البيانات الموجودة في قاعدة البيانات لإعادة تشغيل رمز السلسلة = rediscache.savedatatoredis (rediskey ، obj) ؛ if (code.equals ("ok")) {logger.info ("************** تم حفظ البيانات بنجاح إلى Redis Cache !!! **************") ؛ logger.info ("redis مفتاح القيمة:"+rediskey) ؛ logger.info ("قيمة redis قيمة:"+obj.toString ()) ؛ } إرجاع OBJ ؛ }}ثم اتصل بـ rediscache لتنفيذ ذاكرة التخزين المؤقت
/ ** * احصل على معلومات القائمة من خلال معرف القائمة * param معرف * regurn */ transactional rediscache القائمة العامة findmenubyid ( @RERESCACHEKEY int) {return menurepository.findmenubymenuid (id) ؛ }الطرق التي تسجل الدخول إلى النظام ثم إضافة شرح @RERESCACHER سوف تنفذ معالجة ذاكرة التخزين المؤقت
يمكنك أن ترى أن redis يتم حفظه في ذاكرة التخزين المؤقت
رمز المشروع: https://github.com/U014427391/jeepatform
ما سبق هو كل محتوى هذه المقالة. آمل أن يكون ذلك مفيدًا لتعلم الجميع وآمل أن يدعم الجميع wulin.com أكثر.