第1章の要件分析
チームのオープンソースプロジェクトにキャッシュ処理を実装するためにRedisを追加する予定です。ビジネス機能は部分的に実装されているため、Redisツールのクラスを作成し、それらを参照することにより、変更の量は大きく、分離を達成できないため、SpringフレームワークのAOP(セクション指向プログラミング)について考えました。
オープンソースプロジェクト:https://github.com/u014427391/jeepatform
第2章スプリングブートの紹介
Javaeeフレームワークの分野における重要なオープンソースフレームワークとして、Spring Frameworkはエンタープライズアプリケーション開発において重要な役割を果たしています。同時に、Spring Frameworkとそのサブフレームは非常に多いため、知識の量は非常に広いです。
Springboot:Microframeworkとも呼ばれるSpring Frameworkのサブフレームは、2014年に開始されたフレームワークであり、Spring Frameworkの開発を容易にします。スプリングフレームワークのすべての知識を学んだ後、スプリングフレームワークは必然的に多くのXMLを必要とします。スプリングブートフレームワークを使用する場合、注釈開発を使用して、スプリングフレームワークに基づいて開発を大幅に簡素化できます。 Springbootは、Javaconfigの構成モードを最大限に活用し、「コンベンションの概念は構成よりも優れています」。これにより、SpringMVCに基づくWebアプリケーションとRESTサービスの開発を大幅に簡素化できます。
第3章レディスの紹介
3.1 Redisのインストールと展開(Linux)
Redisのインストールと展開については、私のブログを参照してください(RedisはCに基づいて書かれているため、インストール前にGCCコンパイラをインストールしてください)://www.vevb.com/article/79096.htm
3.2 Redisの紹介
Redisは現在、Web開発コミュニティで最も人気のあるインメモリデータベースの1つになりました。 Web2.0の急速な発展と半構造化データの割合の増加により、Webサイトには効率的なパフォーマンスに対する需要がますます増えています。
さらに、大規模なWebサイトには一般に、数百以上のRedisサーバーがあります。強力なシステムとして、Redisには、ストレージ、キュー、またはキャッシュシステムであろうと、独自の使用があります。
Springboot Frameworkを開始するには、前の記事を参照してください:http://www.vevb.com/article/111197.htm
第4章Redisキャッシュの実装
4.1次の構造図
プロジェクト構造図:
4.2 SpringbootのYMLファイル構成
MySQL、Druid、およびRedisが主に構成されている場合、リソースの下にapplication.yml構成を追加します
spring: datasource: # main data source shop: url: jdbc:mysql://127.0.0.1:3306/jeepatform?autoReconnect=true&useUnicode=true&characterEncoding=utf8&characterSetResults=utf8&useSSL=false username: root password: root driver-class-name: com.mysql.jdbc.Driver type: com.alibaba.druid.pool.druiddatasource#接続プール設定Druid:Inivery-size:5 min-idle:5 max-active:20#接続待機時間を取得する時間を設定する最大wait:60000 #プールで生き残るための最小時間を構成します。ミリ秒単位で任命可能なアイドル時刻と時間ミリ:300000#oracleを使用してください。デュアル検証queryから1を選択してください。接続サイズごとにMax-Pool-Prepared-Statement-forting-#configure Filters for Monitoring Statistics Intercepting。監視インターフェイスを削除した後、SQLをカウントできません。「ウォール」はファイアウォールフィルターに使用されます。 SQL Records Connection-Properties:druid.stat.mergesql = true; druid.stat.slowsqlmillis = 5000#マルジュマージ監視データの複数のdruiddatasource use-global-data-source-stat:true jpa:database:mysql himbernate:show_sql:true format_sql物理的戦略:org.hibernate.boot.model.model.model.physicalnamingstrategystandardimpl mvc:view:web-inf/jsp/suffix:.jsp #jedis構成ジェディス:プール:ホスト:ホスト:ホスト:ホスト:127.0.0.1ポート:6379パスワード:0 100000
構成クラスを作成して構成を開始しますjedisconfig.java:
Package org.muses.jeepatform.config; Import org.springframework.beans.factory.annotation.autowired; Import org.springframework.beans.actory.annotation.qualifier; Import org.springframework.beans.factory.annotation.value; Import; org.springframework.boot.autoconfigure.condition.conditionalonmissingbean; Import org.springframework.boot.context.properties.configurationproperties; Import org.springframework.context.annotation.bean; import.springframework Redis.clients.jedis.jedispool; import redis.clients.jedis.jedispoolconfig; @confurationProperties(prefix = jedisconfig.jedis_prefix)public class jedisconfig {// public static final string jedis_prefix = "jedis"; @bean(name = "jedispool")@autowired public jedispool jedispool( @qualifier( "jedispoolconfig")jedispoolconfig config、@value( "$ {spring.jedis.pool.host}") @value( "$ {spring.jedis.pool.timeout}")int timeout、@value( "$ {spring.jedis.pool.password}")string password){return new jedispool(config、host、ポート、タイムアウト、パスワード); } @bean(name = "jedispoolconfig")public jedispoolconfig jedispoolconfig( @value( "$ {spring.jedis.config.maxtotal}")int maxtotal、 @value( "$ {spring.jedis.pool.config.maxidle}") @value( "$ {spring.jedis.pool.config.maxwaitmillis}")int maxwaitmillis){jedispoolconfig config = new jedispoolconfig(); config.setmaxtotal(maxtotal); config.setmaxidle(maxidle); config.setmaxwaitmillis(maxwaitmillis); configを返します。 }}4.3メタ解剖学クラスライティング
Meta AnnotationクラスRediscache.javaを作成します。変更された注釈によって定義されたすべてのクラスは、AOPキャッシュ処理で自動的に実装されます。
Package org.muses.jeepatform.annotation; Import org.muses.jeepatform.common.rediscachenamespace; Import Java.lang.Annotation。 {// rediscachenamespace namespace();}保持に加えて、JDK 5が提供する他の3つの注釈、すなわちターゲット、継承、文書化されています。これに基づいて、カスタムメタアノテーションを実装できます
メソッドメソッドレベルに基づいて、再発行性を参照に設定します。
1. RetentionPolicy.Sourceこのタイプの注釈は、ソースコードレベルでのみ予約されており、コンパイル中に無視されます。
2。RetentionPolicy.classこのタイプの注釈は、コンピレーション中に保持され、クラスファイルに存在しますが、JVMはそれを無視します。
3. retentionPolicy.Runtimeこのタイプの注釈はJVMによって予約されるため、実行時に反射メカニズムを使用するJVMまたは他のコードで読み、使用できます。
4.4 Jedispoolに電話してRedisキャッシュ処理を実装します
package org.muses.jeepatform.cache;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import org.springframework.stereotype.Service;import redis.clients.jedis.Jedis;import redis.clients.jedis.JedisPool;import javax.annotation.resource; @component( "rediscache")public class rediscache {@autowired private jedispool jedispool; Private Jedispool getjedispool(){return jedispool; } public void setjedispool(jedispool jedispool){this.jedispool = jedispool; } / ** * Redis Cacheからデータを取得 * @param Rediskey * @return * / public Object getDataFromredis(String Rediskey){jedis jedis = jedispool.getResource(); byte [] bytearray = jedis.get(rediskey.getBytes()); if(bytearray!= null){return serializeutil.unserialize(bytearray); } nullを返します。 } / ** * redisにデータを保存 * @param rediskey * / public string savedatatoredis(string rediskey、object obj){byte [] bytes = serializeutil.serialize(obj); jedis jedis = jedispool.getResource();文字列code = jedis.set(rediskey.getBytes()、bytes);返品コード。 }}オブジェクトシリアル化ツールクラス:
Package org.muses.jeepatform.cache; import java.io。*; public class serializeutil { / *** serialized object* @return* / public static byte [] serialize(object obj){objectoutputstream oos = null; bytearrayoutputStream baos = null; try {baos = new bytearrayoutputStream(); oos = new objectOutputStream(baos); oos.writeobject(obj); byte [] bytearray = baos.tobytearray(); bytearrayを返します。 } catch(ioexception e){e.printstacktrace(); } nullを返します。 } / ** * deserialize object * @param bytearray * @return * / public static object unserialize(byte [] bytearray){bytearrayinputStream bais = null; try {// deserialize to object bais = new bytearrayinputStream(bytearray); ObjectInputStream ois = new ObjectInputStream(BAIS); ois.readObject()を返します。 } catch(Exception e){e.printstacktrace(); } nullを返します。 }}ここでは、VOクラスがシリアル化可能な実装を行う必要があることを覚えています
たとえば、メニュー情報voクラス、これはJPAマッピングエンティティクラスです
Package org.muses.jeepatform.core.entity.admin; import javax.persistence。*; import java.io.serializable; import java.util.list;/*** @description mentmentmentmentment entity* @author nicky* @date 3月17日*/ @ @table(name namepublic ") { / **メニューID ** / private int menuid; / **優れたID **/ private int parentid; / **メニュー名**/プライベートストリングメンナーム。 / **メニューアイコン**/プライベート文字列メニューイコン。 / **メニューurl **/ private string menuurl; / **メニュータイプ**/プライベート文字列Menutype; / **メニューソート**/プライベート文字列メニューオーダー。 / **メニューステータス**/プライベートストリングMenustatus;プライベートリスト<メニュー> submenu;プライベートストリングターゲット。プライベートブールhassubmenu = false; public Menu(){super(); } @id @generatedValue(Strategy = GenerationType.Identity)public int getMenuid(){return this.menuid; } public void setMenuid(int menuid){this.menuid = menuid; } @column(length = 100)public int getParentId(){return derparentId; } public void setParentID(int carentid){this.parentid = carperid; } @column(length = 100)public string getMenuname(){return this.menuname; } public void setMenuname(string menuname){this.menuname = menuname; } @column(length = 30)public string getmenuicon(){return this.menuicon; } public void setMenuicon(string menuicon){this.menuicon = menuicon; } @column(length = 100)public string getmenuurl(){return this.menuurl; } public void setMenuurl(string menuurl){this.menuurl = menuurl; } @column(length = 100)public string getMenutype(){return this.menutype; } public void setMenutype(string menutype){this.menutype = menutype; } @column(length = 10)public string getMenuorder(){return menueder; } public void setMenuorder(string menu -order){this.menuorder = menuorder; } @column(length = 10)public string getMenustatus(){return menustatus; } public void setmenustatus(string menustatus){this.menustatus = menustatus; } @transient public List <menu> getsubmenu(){return submenu; } public void setsubmenu(list <menu> submenu){this.submenu = submenu; } public void settarget(string target){this.target =ターゲット; } @transient public string getTarget(){return target; } public void sethassubmenu(boolean hassubmenu){this.hassubmenu = hassubmenu; } @transient public boolean gethassubmenu(){return hassubmenu; }}4.5スプリングAOPは、@rediscacheによって注釈されたすべてを監視するメソッドキャッシュを実装します
最初にRedisからキャッシュを取得します。照会できない場合は、MySQLデータベースをクエリしてから、Redisキャッシュに保存します。次回クエリをするときは、Redisキャッシュを直接呼び出します。
Package org.muses.jeepatform.cache; import org.aspectj.lang.proceedjoinpoint; import org.aspectj.lang.annotation.around; import org.aspectj.lang.annotation.aspect; import org.aspectj.lang.annotation.point; import org.slf4j.logger; org.slf4j.loggerfactory; Import org.springframework.beans.factory.annotation.autowired; import org.springframework.beans.factory.annotation.qualifier; Import org.springframework.stereototy.component;静的最終ロガーロガー= loggerFactory.getLogger(redisaspect.class); @autowired @qualifier( "rediscache")private rediscache rediscache; /***すべてのメタアノテーションを傍受する方法アノテーションを再発見します* /@pointcut( " @annotation(org.muses.jeepatform.annotation.rediscache)")public void pointcutmethod(){} /***サラウンド処理の場合、最初にRedisからキャッシュを取得します。クエリができない場合は、mysqlデータベースを照会し、 * @param joinpoint * @return */@around( "pointcutmethod()")パブリックオブジェクトの周り(// receedingjoinpoint joinpoint)にクエリを保存します。文字列applid = null; object [] args = joinpoint.getargs(); if(args!= null && args.length> 0){applid = string.valueof(args [0]); } //ターゲットメソッドが文字列ターゲット= joinpoint.getTarget()に配置されているクラスを取得します。 //ターゲットメソッドのメソッド名を取得ましたstring methodname = joinpoint.getSignature()。getName(); // redisキー形式:applid:メソッド名文字列rediskey = applid + ":" + classname + "。"。 + methodname;オブジェクト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キャッシュAOP処理時間:"+(endtime-starttime)); logger.info( "*************** Redisからデータが見つかりません****************"); try {obj = joinpoint.proceed(); } catch(throwable e){e.printstacktrace(); } logger.info( "*************** mysqlのデータのクエリを開始*************"); //ポストセット:データベースで見つかったデータをredis string code = rediscache.savedatatoredis(rediskey、obj)に保存します。 if(code.equals( "ok")){logger.info( "************データは、redisキャッシュに正常に保存されました!!! ************"); logger.info( "redisキー値:"+rediskey); logger.info( "redis値値:"+obj.toString()); } objを返します。 }}次に、@rediscacheに電話してキャッシュを実装します
/ ** *メニューIDを介してメニュー情報を取得 * @param ID * @return */ @Transactional @Rediscache Public Menu findMenubyid(@rediscachekekey int id){return menurepository.findmenubymenuid(id); }システムにログインして@rediscacheアノテーションを追加するメソッドは、Redisキャッシュ処理を実装します
Redisがキャッシュに保存されていることがわかります
プロジェクトコード:https://github.com/u014427391/jeepatform
上記はこの記事のすべての内容です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。