1 Introdução ao Ehcache
O Ehcache é uma estrutura de cache em processo de java pura, com recursos rápidos e enxutos, e é o cacheProvider padrão no hibernado.
O Ehcache é um cache distribuído Java de código aberto amplamente usado. Destinado principalmente a cache universal, Java EE e contêineres leves. Possui os recursos do armazenamento de memória e disco, carregador de cache, extensão de cache, manipulador de exceção de cache, filtro de servlet de cache GZIP e suporta APIs de descanso e sabão.
Ehcache foi originalmente desenvolvido por Greg Luck em 2003. Em 2009, o projeto foi comprado pela Terracotta. O software ainda é de código aberto, mas alguns novos recursos importantes (por exemplo, consistência entre reinicialização rápida) só podem ser usados em produtos comerciais, como ErpRise Ehcache e BigMemory. A Wikimedia FoundationAnnouned atualmente usa a tecnologia Ehcache.
Em suma, o Ehcache ainda é uma boa tecnologia de cache. Vamos dar uma olhada em como a primavera é implementada com o ehcache.
2 mola com ehcache
Os resultados do sistema são os seguintes:
3 Introdução específica de configuração
Existem combinações dessas partes:
SRC: código Java, incluindo interceptores, interface de chamada, classe de teste
src/cache-bean.xml: configure o feijão correspondente a ehcache, interceptador e aulas de teste, etc.
src/ehcache.xml: informações de configuração de cache ehcache
Webroot/Lib: Biblioteca
4 Introdução detalhada de conteúdo
4.1 Src
4.1.1 Interceptor
Dois interceptores são configurados pela primeira vez no código:
O primeiro interceptador é:
com.test.ehcache.cachemethodintercept
O conteúdo é o seguinte:
pacote com.test.ehcache; importar java.io.Serializable; importar net.sf.ehcache.cache; importação net.sf.ehcache.Element; importação org.aopalliance.intercept.methOninterceptor; importfrortFringFortFring; org.springframework.util.assert; public classe Cachemethodintercept implementa MethodInterceptor, InicializandoBean {private cache cache; public void setCache (cache cache) {this.cache = cache; } public CachemethodIntercept () {super (); } /*** Intercepte o método ServiceManager e descubra se o resultado existe. Se existir, retorne o valor no cache. * Caso contrário, retorne o resultado da consulta do banco de dados e coloque o resultado da consulta no cache */public objeto Invoke (MethodInvocation Invocation) lança lançável {// Obtenha a classe String TargetName a ser interceptada = Invocation.getThis (). GetClass (). GetName (); // Obtenha o método da classe a ser interceptada string métodname = invocação.getMethod (). GetName (); // Obtenha os parâmetros do método da classe a ser interceptada objeto [] argumentos = invocação.getarguments (); Resultado do objeto; // Crie uma string para fazer a chave no cache string cachekey = getCacheKey (TargetName, MethodName, Argumments); // Obter dados do elemento de cache = cache.get (cachekey); if (element == null) {// Se não houver dados no cache, procure por não cache, como o banco de dados, e coloque os encontrados no resultado do cache = Invocation.proeced (); // Gere a chave e o valor que serão armazenados no elemento do cache = novo elemento (CacheKey, (serializável) resultado); System.out.println ("---- Digite a pesquisa não cache, como pesquisar diretamente o banco de dados, colocando-o no cache após a pesquisa"); // armazenar a chave e o valor no cache cache.put (elemento); } else {// Se houver dados no cache, procure por cache System.out.println ("--- Digite a pesquisa de cache, não procure o banco de dados, aliviando a pressão no banco de dados"); } return element.getValue (); } /*** Método para obter a tecla de cache. A chave do cache é o identificador exclusivo de um elemento no cache. * Incluindo o nome do pacote + Nome da classe + nome do método, como: com.test.service.testserviceImpl.getObject */ private String getCacheKey (string TargetName, String MethodName, Object [] Argumentos) {StringBuffer sb = new StringBuffer (); SB.Append (TargetName) .Append ("."). Append (MethodName); if ((argumentos! = null) && (argumentos.Length! = 0)) {for (int i = 0; i <argumentos.Length; i ++) {sb.append ("."). Append (argumentos [i]); }} return sb.toString (); } / ** * Implemente inicializeBean, verifique se o cache está vazio 70 * / public void depoispropertiesset () lança exceção {Assert.NotNull (cache, "Precisa de um cache. Use setCache (cache) crie -o."); }}Cachemethodinterceptor é usado para interceptar métodos começando com "get". Observe que esse interceptador intercepta primeiro e depois executa a interface de chamada original.
Há também um interceptador:
com.test.ehcache.cacheafterReturningAdvice
Conteúdo específico:
pacote com.test.ehcache; importar java.lang.reflect.method; importar java.util.list; importar net.sf.ehcache.cache; importar org.springframework.aop.afterReturningAdvice; importação.springFramework.BeanS.Factory.InInInging.InIngingAdvice; import.springFramwork.BeanS.Factory.InInInmialing.InIngingAdvice; CacheafterReturningAdvice implementa após o renúncia, inicializando oBean {cache privado de cache; public void setCache (cache cache) {this.cache = cache; } public CacheafterReturningAdvice () {super (); } public void após renunciar (objeto arg0, método arg1, objeto [] arg2, objeto arg3) lança jogável {string className = arg3.getClass (). getName (); Lista da lista = cache.getKeys (); for (int i = 0; i <list.size (); i ++) {string cacheKey = string.valueof (list.get (i)); if (cachekey.startswith (className)) {cache.remove (cachekey); System.out.println ("----- cache limpo"); }}} public void depoispropertiesset () lança Exceção {Assert.NotNull (cache, "Precisa de um cache. Por favor, use o setCache (cache) crie -o."); }}CacheafterReturningAdvice é usado para interceptar métodos começando com "Atualização". Observe que esse interceptador primeiro executa a interface de chamada original e depois é interceptada.
4.1.2 chamando a interface
O nome da interface é:
com.test.service.Servicemanager
O conteúdo específico é o seguinte:
pacote com.test.service; importar java.util.list; interface pública serviceManager {public list getObject (); public void updateObject (objeto objeto); }O nome da classe de implementação é:
com.test.service.ServicemanagerImpl
O conteúdo específico é o seguinte:
pacote com.test.service; importar java.util.ArrayList; importar java.util.list; public class ServiceManagerImpl implementa serviceManager {@Override list Public GetObject () {System.out.println ("--Upicemanager: esse elemento não existe no cache, consulte o cache. retornar nulo; } @Override public void updateObject (objeto objeto) {System.out.println ("---- ServiceManager: O objeto é atualizado e todos os caches gerados por esta classe serão removidos!"); }}4.1.3 Classe de teste
O nome da classe de teste é:
com.test.service.testmain
O conteúdo específico é:
pacote com.test.service; importar org.springframework.context.applicationContext; importar org.springframework.context.support.classPathXMLApplicationContext; public class "/public static void main (string [] args) {string cachestring ="/cache "/cache/cache/cache/cache"/cache/cache "/cache/cache"/cache/cache "/cache/cache"/cache/cache "/cache"/cache "/cache"/cache/cache "/sticts étic e a string (string [] args) {string; ApplicationContext Context = novo ClassPathXMLApplicationContext (Cachestring); // obtém o feijão gerado pelo proxyfactory de fábrica proxy para gerar um efeito de interceptação serviceManager testService = (serviceManager) context.getBean ("proxyfactory"); // a primeira vez que pesquisará System.out.println ("===== Primeira Pesquisa"); testService.getObject (); // a segunda vez pesquisando System.out.println ("===== Segunda pesquisa"); testService.getObject (); // a segunda vez pesquisando System.out.println ("====== a terceira vez pesquisando"); testService.UpdateObject (null); // a terceira vez de pesquisa de pesquisa.out.println ("====== A terceira pesquisa de pesquisa"); testService.getObject (); }}Observe aqui que a obtenção de feijões é produzida pelo proxyfactory de fábrica de proxy, para que haja um efeito de interceptação.
Pode -se observar que quatro chamadas estão definidas na classe de teste e a ordem de execução é:
Primeira pesquisa Segunda pesquisa Primeira atualização da terceira pesquisa
4.2 src/cache-bean.xml
cache-bean.xml é usado para configurar feijões correspondentes a classes de ehcache, interceptor e teste. O conteúdo é o seguinte:
<? xml versão = "1.0" coding = "utf-8"?> <! > <property name="configLocation"> <value>ehcache.xml</value> </property> </bean> <!-- Define the factory of ehCache and set the name of the cache used, that is, "com.tt" --> <bean id="ehCache"> <property name="cacheManager"> <ref local="defaultCacheManager" /> </property> <!-- The name of the Cache-> <propriedade name = "Cachename"> <Value> com.tt </value> </propriedade> </bean> <!-o interceptador para criar cache e consulta cache-> <bean id = "cachemethodintercept"> <nome da propriedade = "cache"> <ref local = "ehcache"/> </> </> cache-> <bean id = "cacheafterRenterningAdvice"> <propriedade name = "cache"> <ref local = "ehcache" /> < /propriedade> < /bean> <!-chame a interface, o interceptador interceptor-> <bean id = "servicemanager" /> <!-inserção de que o intercept. Interceptor aqui com.test.ehcache.cachemethodinterceptor-> <bean id = "CachePointCut"> <!-Adicione uma seção, a seção é a seção que é adicionada após executar o método de impressão-> <Nome da propriedade = "Conselhos"> <Ref Local = "Cachemethodintercetor" /> < /propriedade> <nome = "Patternns"> <Ref Local = "Cachemethodintercetor" /> < /propriedade> <nome = " caractere ### + significa conformar-se com o caractere anterior uma ou várias vezes ###* significa conformar-se com o caractere anterior zero ou várias vezes ###/escapar de qualquer símbolo usado na expressão regular-> <!-.* significa o prefixo anterior (incluindo o nome do pacote, que significa o método getObject-> <valor>.* O nome do método e as características do nome do método de interceptação do interceptor, etc., chame o interceptor com.test.ehcache.cacheafterReturningAdvice-> <bean id = "cachePointCutadVice"> <Nome da propriedade "> <warsws> <ref local =" CacheafterGurningAdVice "> < /> < /> < /name =" o nome do pacote), que significa Método UpdateObject-> <Value>.*Update. <list> <Value> CachePointCut </value> <Value> CachePointCutadvice </value> </list> </Property> </beans>
O conteúdo de cada feijão foi comentado e observou que não se esquecem de agente feijão de fábrica.
4.3 src/ehcache.xml
O ehcache.xml armazena informações detalhadas sobre a configuração do cache do ehcache, como segue:
<? xml versão = "1.0" coding = "utf-8"?> <ehcache xmlns: xsi = "http://www.w3.org/2001/xmlschema-innstance" xsi: nonamesChemalocation = "htttp:/ehehcate" <DiskStore Path = "D: // temp // cache"/> <DefaultCache maxElementsInmemory = "1000" eternal = "false" timeToidleSeconds = "120" timeToliveSeconds = "120" Overflowtodisk = "True"/!-File de cache de cache de informações-onde "com:" com 120 "", onde "/! maxElementsInMemory = "10000" eternal = "false" timeToidleSeconds = "300000" timetoliveSeconds = "600000" OverflowTodisk = "true" /> </hcache>
Você pode ver que o local de armazenamento do armazenamento em cache está definido como "d:/temp/cache" e o nome do cache é definido como "com.tt", como mostrado na figura:
4.4 Webroot/lib
Para a biblioteca Java necessária, consulte a imagem da estrutura do sistema no início, omitida aqui.
5 teste
Execute a classe de teste e os resultados dos testes são os seguintes:
Através dos resultados da execução, podemos ver:
Após a primeira pesquisa ser interceptada, verifica -se que é a primeira interceptação e o cache não foi armazenado em cache. Portanto, primeiro execute a classe de interface original para que os dados sejam consultados. Pode ser obtido através da consulta do banco de dados e, em seguida, gerar o cache e colocar os dados consultados no cache.
Depois que a segunda pesquisa foi interceptada, verificou -se que o cache já existe; portanto, a classe de interface original não é mais executada, ou seja, o banco de dados não está mais consulta e os dados da consulta são diretamente obtidos através do cache. Claro, é apenas uma impressão simples aqui.
Depois, há a primeira atualização . A operação realizada após ser interceptada é armazenar todos os dados no cache no banco de dados e excluir o cache.
Finalmente, há a terceira consulta . Depois de ser interceptada, verifica -se que o sistema não possui um cache; portanto, o banco de dados de consulta de classe de interface original, cria um cache e coloque os dados obtidos da nova consulta no cache. O mesmo método que a primeira consulta.
Até agora, implementamos o que precisa ser feito na primavera com o ehcache.
6 Código fonte de anexo
O código -fonte do anexo pode ser obtido no site do meu github.
O exposto acima é todo o conteúdo deste artigo. Espero que seja útil para o aprendizado de todos e espero que todos apoiem mais o wulin.com.