注释嵌套注释_DIY注释
注釋嵌套注釋
從Java 5開始,Java中出現(xiàn)了注釋。 我想做一個(gè)自己的注釋,只是為了看看需要什么。 但是,我發(fā)現(xiàn)它們只是接口。
有擦
接口后面沒有牙。 必須執(zhí)行一些代碼。 我認(rèn)為這是橡膠行之有效的方法,我真的找到了解決方法。
首先,我需要一個(gè)目標(biāo)
我選擇了一個(gè)最近的熱門話題:緩存。 我不想實(shí)現(xiàn)JSR 109(JCache),但也不想做典型的“ Hello World”。 我選擇實(shí)現(xiàn)兩個(gè)注釋,一個(gè)注釋不帶任何參數(shù),另一個(gè)注釋不帶參數(shù)。 我還需要一個(gè)緩存提供程序。 如果我要這樣做的話,還可以將真正的緩存庫(kù)加入其中。 它還遵循我的設(shè)計(jì)理念,即使用產(chǎn)品/庫(kù)來(lái)達(dá)成目標(biāo),而不是將所有內(nèi)容都進(jìn)行家庭紡。 經(jīng)過仔細(xì)考慮,我選擇了hazelcast作為我的緩存引擎。 它是市場(chǎng)上最快的,而且是免費(fèi)的。
更多決定
在選擇了目標(biāo)之后,我仍然需要找出如何在它們后面扎牙的方法。 經(jīng)過一番挖掘,我發(fā)現(xiàn)了兩種方法:
反射
幾乎每次使用反射時(shí),我都會(huì)為編寫這么笨拙的代碼感到遺憾。 另外,要按照我想要的方式進(jìn)行操作,我必須創(chuàng)建自己的框架。 聽起來(lái)兩個(gè)注解的工作量很大。
面向方面的編程(AOP)
這非常適合我想做的事。 AOP致力于將樣板代碼減少到一個(gè)地方。 這將很方便并且與緩存緊密結(jié)合,因?yàn)榫彺婵煞譃橐韵虏襟E:
也許這過于簡(jiǎn)單,但總的來(lái)說是正確的。 就像所有事物一樣,細(xì)節(jié)決定成敗。
同時(shí),回到AOP牧場(chǎng)
雖然我知道AOP是適合我的地方,但我對(duì)此并不了解。 我發(fā)現(xiàn)Spring有一個(gè)AOP庫(kù),而眾所周知的庫(kù)是AspectJ。 AspectJ對(duì)我不熟悉,需要運(yùn)行時(shí)引擎才能工作。 我對(duì)Spring更加熟悉,所以選擇了它。 在研究Spring的AOP時(shí),我發(fā)現(xiàn)我必須深入研究AspectJ的注釋,因此無(wú)論如何我還是以某種形式或方式被AspectJ所困。
新概念,新詞匯
編寫方面不像編寫對(duì)象。 它們是對(duì)象,但并非如此,因此當(dāng)然需要一組新的術(shù)語(yǔ)。 我使用的是Spring AOP文檔中的內(nèi)容
我確實(shí)需要閱讀幾次該頁(yè)面才能理解所講的內(nèi)容。 強(qiáng)烈建議您執(zhí)行相同的操作,否則其余帖子聽起來(lái)像胡言亂語(yǔ)。
切入點(diǎn)的構(gòu)成和建議
切入點(diǎn)設(shè)計(jì)很容易,因?yàn)槲抑粚?duì)帶有注釋的方法感興趣。 它需要的建議是周圍的建議,因?yàn)槿绻呀?jīng)進(jìn)行了匹配的調(diào)用,我就需要能夠避免調(diào)用該方法。
最后的代碼
Maven Pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.darylmathison</groupId><artifactId>annotation-implementation</artifactId><version>1.0-SNAPSHOT</version><properties><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target><spring.version>4.2.4.RELEASE</spring.version></properties><description>This project is an example of how to implement an annotation via Spring AOP.</description><scm><url>https://github.com/darylmathison/annotation-implementation-example.git</url><connection>scm:git:https://github.com/darylmathison/annotation-implementation-example.git</connection><developerConnection>scm:git:git@github.com:darylmathison/annotation-implementation-example.git</developerConnection></scm><issueManagement><system>GitHub</system><url>https://github.com/darylmathison/annotation-implementation-example/issues</url></issueManagement><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>${spring.version}</version><scope>test</scope></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.8.8</version></dependency><dependency><groupId>com.hazelcast</groupId><artifactId>hazelcast</artifactId><version>3.6</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency></dependencies><reporting><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-project-info-reports-plugin</artifactId><version>2.7</version><reportSets><reportSet><reports><report>dependencies</report><report>index</report><report>project-team</report><report>issue-tracking</report><report>scm</report></reports></reportSet></reportSets></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-report-plugin</artifactId><version>2.18.1</version></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-javadoc-plugin</artifactId><version>2.10.3</version><reportSets><reportSet><reports><report>javadoc</report><report>test-javadoc</report></reports></reportSet></reportSets></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jxr-plugin</artifactId><version>2.5</version><configuration><linkJavadoc>true</linkJavadoc></configuration><reportSets><reportSet><reports><report>jxr</report><report>test-jxr</report></reports></reportSet></reportSets></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-changelog-plugin</artifactId><version>2.3</version><configuration><type>range</type><range>90</range></configuration></plugin></plugins></reporting> </project>注釋
快取
緩存注釋的可愛名稱,對(duì)嗎?
package com.darylmathison.ai.annotation;import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;/*** Created by Daryl on 2/19/2016.*/ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface CacheMe { }CacheMeNow
package com.darylmathison.ai.annotation;import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;/*** Created by Daryl on 2/19/2016.*/ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface CacheMeNow {String key(); }彈簧配置
我決定使用基于Java的配置,而不是像通常為了改變速度而使用的XML。 EnableAspectJAutoProxy批注是使Spring AOP開始工作的關(guān)鍵。 我一直在我旁邊,直到我讀到有關(guān)這顆小寶石的這篇文章。 有時(shí),這是一天中最容易燃燒的事情。
AppConfig
package com.darylmathison.ai.config;import com.darylmathison.ai.cache.CacheAspect; import com.darylmathison.ai.service.FibonacciService; import com.darylmathison.ai.service.FibonacciServiceImpl; import com.hazelcast.config.Config; import com.hazelcast.config.EvictionPolicy; import com.hazelcast.config.MapConfig; import com.hazelcast.core.Hazelcast; import com.hazelcast.core.HazelcastInstance; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.EnableAspectJAutoProxy;import java.util.HashMap; import java.util.Map;/*** Created by Daryl on 2/20/2016.*/ @Configuration @ComponentScan(basePackages = "com.darylmathison.ai") @EnableAspectJAutoProxy public class AppConfig {@Beanpublic Map<String, Object> cache() {Config config = new Config();MapConfig mapConfig = new MapConfig();mapConfig.setEvictionPercentage(50);mapConfig.setEvictionPolicy(EvictionPolicy.LFU);mapConfig.setTimeToLiveSeconds(300);Map<String, MapConfig> mapConfigMap = new HashMap<>();mapConfigMap.put("cache", mapConfig);config.setMapConfigs(mapConfigMap);HazelcastInstance instance = Hazelcast.newHazelcastInstance(config);return instance.getMap("cache");}@Beanpublic FibonacciService fibonacci() {return new FibonacciServiceImpl();}@Beanpublic CacheAspect cacheAspect() {return new CacheAspect();} }服務(wù)編號(hào)
基于經(jīng)典Spring的設(shè)計(jì)需要服務(wù)嗎? 由于Spring使用代理來(lái)實(shí)現(xiàn)其AOP,因此強(qiáng)烈建議為帶注釋的類定義一個(gè)接口以實(shí)現(xiàn)。
斐波那契服務(wù)
package com.darylmathison.ai.service;/*** Created by Daryl on 2/20/2016.*/ public interface FibonacciService {long calculate(int rounds);long calculateWithKey(int rounds); }FibonacciServiceImpl
package com.darylmathison.ai.service;import com.darylmathison.ai.annotation.CacheMe; import com.darylmathison.ai.annotation.CacheMeNow;/*** Created by Daryl on 2/20/2016.*/ public class FibonacciServiceImpl implements FibonacciService {@Override@CacheMepublic long calculate(int rounds) {return sharedCalculate(rounds);}@Override@CacheMeNow(key = "now")public long calculateWithKey(int rounds) {return sharedCalculate(rounds);}private static long sharedCalculate(int rounds) {long[] lastTwo = new long[] {1, 1};for(int i = 0; i < rounds; i++) {long last = lastTwo[1];lastTwo[1] = lastTwo[0] + lastTwo[1];lastTwo[0] = last;}return lastTwo[1];} }AOP的東西
這是注釋實(shí)現(xiàn)的核心。 其他所有內(nèi)容都可以用來(lái)支持后續(xù)的工作。
系統(tǒng)存檔
根據(jù)Spring文檔,集中化切入點(diǎn)定義是一個(gè)好主意。
package com.darylmathison.ai.cache;import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut;/*** Created by Daryl on 2/20/2016.*/ @Aspect public class SystemArch {@Pointcut("@annotation(com.darylmathison.ai.annotation.CacheMe)")public void cacheMeCut() {}@Pointcut("@annotation(com.darylmathison.ai.annotation.CacheMeNow)")public void cacheMeNowCut() {} }緩存方面
周圍注釋使用切入點(diǎn)類的完整方法名稱來(lái)定義建議的內(nèi)容。 CacheMeNow批注的建議包括一個(gè)額外條件,因此可以定義批注,以便可以讀取關(guān)鍵參數(shù)。 測(cè)試代碼中揭示了CacheMeNow中的一個(gè)設(shè)計(jì)錯(cuò)誤。
package com.darylmathison.ai.cache;import com.darylmathison.ai.annotation.CacheMeNow; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.beans.factory.annotation.Autowired;import java.util.Map;/*** Created by Daryl on 2/20/2016.*/ @Aspect public class CacheAspect {@Autowiredprivate Map<String, Object> cache;@Around("com.darylmathison.ai.cache.SystemArch.cacheMeCut()")public Object simpleCache(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {StringBuffer keyBuffer = new StringBuffer();for(Object o: proceedingJoinPoint.getArgs()) {keyBuffer.append(o.hashCode());}String key = keyBuffer.toString();Object ret = cache.get(key);if(ret == null) {ret = proceedingJoinPoint.proceed();cache.put(key, ret);}return ret;}@Around("com.darylmathison.ai.cache.SystemArch.cacheMeNowCut() && @annotation(cacheMeNow)")public Object simpleCacheWithParam(ProceedingJoinPoint proceedingJoinPoint, CacheMeNow cacheMeNow) throws Throwable {Object ret = cache.get(cacheMeNow.key());if(ret == null) {ret = proceedingJoinPoint.proceed();cache.put(cacheMeNow.key(), ret);}return ret;} }測(cè)試代碼
顯示注釋確實(shí)引起緩存的驅(qū)動(dòng)程序代碼。
斐波那契檢驗(yàn)
package com.darylmathison.ai.service;import com.darylmathison.ai.config.AppConfig; import org.junit.Assert; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;/*** Created by Daryl on 2/20/2016.*/ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = {AppConfig.class}) public class FibonacciTest {private static final int ROUNDS = 12;private static final long ANSWER = 377;@Autowiredprivate FibonacciService fibonacci;@org.junit.Testpublic void testCalculate() throws Exception {long start = System.currentTimeMillis();Assert.assertEquals(ANSWER, fibonacci.calculate(ROUNDS));long middle = System.currentTimeMillis();Assert.assertEquals(ANSWER, fibonacci.calculate(ROUNDS));long end = System.currentTimeMillis();Assert.assertTrue((end - middle) < (middle - start));}@org.junit.Testpublic void testCalculateWithKey() throws Exception {Assert.assertEquals(ANSWER, fibonacci.calculateWithKey(ROUNDS));// This test should not passAssert.assertEquals(ANSWER, fibonacci.calculateWithKey(13));} }結(jié)論
注釋不必很難實(shí)現(xiàn)。 使用AOP編程,我可以用很少的代碼來(lái)實(shí)現(xiàn)兩個(gè)注釋。
翻譯自: https://www.javacodegeeks.com/2016/03/diy-annotations-3.html
注釋嵌套注釋
總結(jié)
以上是生活随笔為你收集整理的注释嵌套注释_DIY注释的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 中文字体临摹(中文字体linux)
- 下一篇: linux文件备份命令(linux 文件