آشنایی با Spring Caching و نحوه اتصال آن به سرور Redis

برای یک وب‌سرویس با ترافیک بالا، واجب است که از نوعی مکانیزم caching بهره ببرد. Caching راهی برای ذخیره داده‌های محاسبه شده در رم است، تا در آینده درخواست‌ها بتوانند به سرعت حاضر شوند. دو عدد از معروف‌ترین مخازن موجود، بر پایه رم Redis و Memcached هستند.ردیس یکی از رایجترین دیتابیس های Nosql است که اطلاعات در آن بصورت Key و Value، بر روی معماری داخلی سیستم ذخیره سازی میشود . نحوه استفاده از cache در پروژه ما :1- نحوه ی ایجاد cache :برای ساخت کش از انوتیشن @cacheable استفاده میشود.نحوه ی کار @cacheable به این صورت است که ابتدا ترکیب (value+key) را در استوریج خودش (لوکال یا سرور ردیس) جستجو میکند ، در صورتی که وجود داشته باشد وارد متد نمیشود و در صورتی که وجود نداشته باشد وارد متد میشود و خروجی متد را با توجه به ترکیب (value+key) کش میکند.پارامترهای ورودی انوتیشن @cacheable :cacheNames: Name of the caches in which method result are stored. value: Alias for cacheNames. condition: Spring SpEL expression to make conditional caching. key: SpEL to compute key dynamically. keyGenerator: Bean name for custom KeyGenerator. unless: SpEL to veto method caching.نکته 1 : پارامترهای متد به طور پیشفرض بعنوان key در نظر گرفته میشود.نکته 2: در @cacheable وجود value الزامی است ولی وجود key الزامی نیست.نکته 3: با توجه به توضیح نکته قبل، ما در پروژه برای کش کردن همیشه مقادیر value و key را قرار میدهیم.2- نحوه تعریف key و value در پروژه به این شکل است:· در کلاس CommonRedisKeyValue باید تعریف شود.· فیلدهای key و value از نوع string هستند و به صورت استاتیک و غیرقابل تغییر final (حروف بزرگ) تعریف میشوند.· نام فیلد Valueبه این صورت تعریف میشود :{در صورت داشتن پارامترورودی ، نام پارامتر ورودی } + نام متد+ نام انتیتی+_ VALUECITY_TREE_BY_COUNTRY_ID_VALUE· مقدار فیلد Valueبه این صورت تعریف میشود:RunConfiguration.MBDBMAIN + "_" + "_VALUE بدون Valueنام استفاده شده برای ";مثال کامل برای تعریف value کش :CITY_TREE_BY_COUNTRY_ID_VALUE = RunConfiguration.MBDBMAIN + "_" + "CITY_TREE_BY_COUNTRY_ID";· نام فیلد Key به این صورت تعریف میشود :{در صورت داشتن پارامترورودی ، نام پارامتر ورودی } + نام متد+ نام انتیتی+_KEYCITY_TREE_BY_COUNTRY_ID_KEY· مقدار فیلد Key با توجه به سه حالت زیر تعریف میشود:+ در صورتی که متدی که قرار است کش شود ، پارامتر ورودی نداشته باشد key را به این صورت تعریف میکنیم:مثال کامل برای تعریف Key کش :ORGANIZATION_UNIT_TREE_KEY = "";نکته : درصورتی متد پارامتر ورودی نداشته باشد و کلید کش تعریف نشود ، ردیس بجای keyمقدار SimpleKeyرا بصورت پیشفرض قرار میدهد.+ در صورتی که متدی که قرار است کش شود ، پارامتر ورودی از نوع primitiveType داشته باشد میتوان آن پارامترها را به عنوان کلید کش در نظر بگیریم و به این صورت تعریف میکنیم:"{'countryId='.concat(#countryId)}"مثال کامل برای تعریف Key کش :CITY_TREE_BY_COUNTRY_ID_KEY = "{'countryId='.concat(#countryId)}";+ در صورتی که متدی که قرار است کش شود ، پارامتر ورودی از نوع کلاس داشته باشد میتوان هر کدام از فیلدهای کلاس را که لازم داریم درkey کش قرار دهیم"{'name ='.concat(#bar.name).concat('-id=') .concat(#bar.id)}"مثال کامل برای تعریف Key کش :FOO_BY_NAME_ID_KEY ="{'name ='.concat(#bar.name).concat('-id=') .concat(#bar.id)}"مثالی از : StackOverFlowhttps://stackoverflow.com/questions/13381731/caching-with-multiple-keys@Cacheable(key=&quot#bar.name.concat('-').concat(#bar.id)&quot)public int foo(Bar bar) {....}3- آپدیت کش:برای آپدیت کش ایجاد شده از انوتیشن @CachePut استفاده میشود.برای آپدیت کش باید value و key موردنظر را در @CachePut قرار دهیم.برخلاف @Cacheable ، متد انوتیشن شده با @CachePut در هر بار فراخوانی اجرا میشود و خروجی متد را در کش قرار میدهد.پارامترهای ورودی @cacheable در اینجا هم کاربرد دارد.4- پاک کردن کش :برای پاک کردن کش ایجاد شده از انوتیشن @cacheEvict استفاده میشود.برای پاک کردن کش باید value و key موردنظر را در @cacheEvict قرار دهیم.در صورتی که بخواهیم چندتا کش رو بصورت همزمان پاک کنیم از @Caching استفاده میکنیم.@cacheEvict دو تا ویژگی رو ساپورت میکند: 1 – allEntries 2- beforeInvocation· allEntrie : بطور کامل همه محتویات یک کش که در پارامتر اجباری value در @cacheEvict مشخص شده است را clear میکند.· beforInvocation : هر دو حالت @cacheEvict و @cacheable را میتوان بر روی یک متد اعمال کرد.این ویژگی مشخص میکند که چه چیزی از کش ، قبل یا یعد از فراخوانی متد clear شود.نکته 1 : اسپرینگ کش پدیده ی self-Invocation رو ساپورت نمیکند.https://stackoverflow.com/questions/16899604/spring-cache-cacheable-not-working-while-calling-from-another-method-of-the-s/48867068https://code.google.com/archive/p/ehcache-spring-annotations/wikis/UsingCacheable.wikiبرای حل این مشکل دو روش وجود دارد:1- از @Resource استفاده کنیم : یک کلاس را درون خودش inject میکند:@Resourceprivate SphereClientFactory self;2- یک کلاس جدید ایجاد کنیم و متدهای مربوط به کش را در آنجا قرار دهیم.نکته2 : مدل خروجی متد کش باید حتما serializable باشد.