- 浏览: 5029153 次
- 性别:
- 来自: 南京
文章分类
- 全部博客 (2844)
- java (1094)
- hadoop (37)
- jvm (39)
- hbase (11)
- sql (25)
- 异常 (83)
- div css (6)
- 数据库 (95)
- 有趣的code (15)
- struts2 (6)
- spring (124)
- js (44)
- 算法 (65)
- linux (36)
- hibernate (7)
- 中间件 (78)
- 设计模式 (2)
- 架构 (275)
- 操作系统 (91)
- maven (35)
- tapestry (1)
- mybatis (9)
- MQ (101)
- zookeeper (18)
- 搜索引擎,爬虫 (208)
- 分布式计算 (45)
- c# (7)
- 抓包 (28)
- 开源框架 (45)
- 虚拟化 (12)
- mongodb (15)
- 计算机网络 (2)
- 缓存 (97)
- memcached (6)
- 分布式存储 (13)
- scala (5)
- 分词器 (24)
- spark (104)
- 工具 (23)
- netty (5)
- Mahout (6)
- neo4j (6)
- dubbo (36)
- canal (3)
- Hive (10)
- Vert.x (3)
- docker (115)
- 分布式追踪 (2)
- spring boot (5)
- 微服务 (56)
- 淘客 (5)
- mesos (67)
- php (3)
- etcd (2)
- jenkins (4)
- nginx (7)
- 区块链 (1)
- Kubernetes (92)
- 驾照 (1)
- 深度学习 (15)
- JGroups (1)
- 安全 (5)
- 测试 (16)
- 股票 (1)
- Android (2)
- 房产 (1)
- 运维 (6)
- 网关 (3)
最新评论
-
明兜3号:
部署落地+业务迁移 玩转k8s进阶与企业级实践技能(又名:Ku ...
Kubernetes系统常见运维技巧 -
q328965539:
牛掰啊 资料收集的很全面
HDFS小文件处理解决方案总结+facebook(HayStack) + 淘宝(TFS) -
guichou:
fluent挂载了/var/lib/kubelet/pods目 ...
kubernetes上部署Fluentd+Elasticsearch+kibana日志收集系统 -
xu982604405:
System.setProperty("java.r ...
jmx rmi 穿越防火墙问题及jmxmp的替代方案 -
大漠小帆:
麻烦问下,“获取每个Item相似性最高的前N个Item”,这个 ...
协同过滤推荐算法在MapReduce与Spark上实现对比
因为公司人手原因,最近在为项目搭建架构,在异常,缓存,日志,方面都打算用Aop来做,在原来的项目中对在对异常,日志方面可能都是Log log=Logfactory.getLog();这样既麻烦,又紧耦合在一起。所以打算用Aop试试。下面是对一些缓存对象的Aop处理。主要是根据方法签名来做key值。
定义一个注解
import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.METHOD,ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface MethodCache { int second() default 0; }
定义一个业务处理类
public class Sev { @MethodCache(second=3) public Map getSort(int type,int parentid){ System.out.println("no cache----"); Map m =new HashMap(); return m; } @MethodCache(second=3) public void getSort(){ System.out.println("no cache----"); } }
定义一个Aop
import java.io.Serializable; import java.lang.reflect.Method; import java.util.Date; import net.sf.ehcache.Cache; import net.sf.ehcache.Element; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; @Aspect public class MethodCacheAspectJ { private Cache cache; /** * 设置缓存名 */ public void setCache(Cache cache) { this.cache = cache; } @Pointcut("@annotation(com.zhang.shine.cache.MethodCache)") public void methodCachePointcut(){ } @Around("methodCachePointcut()") public Object methodCacheHold(ProceedingJoinPoint joinPoint) throws Throwable{ System.out.println("aop start "); String targetName = joinPoint.getTarget().getClass().getName(); String methodName = joinPoint.getSignature().getName(); Object[] arguments = joinPoint.getArgs(); Object result = null; String cacheKey = getCacheKey(targetName, methodName, arguments); System.out.println("key--"+cacheKey); Element element = cache.get(cacheKey); if (element == null) { try{ result = joinPoint.proceed(); }catch(Exception e){ } if(result!=null){ try{ element = new Element(cacheKey, (Serializable) result); Class targetClass = Class.forName(targetName); Method[] method = targetClass.getMethods(); int second = 0; for(Method m:method){ if (m.getName().equals(methodName)) { Class[] tmpCs = m.getParameterTypes(); if(tmpCs.length==arguments.length){ MethodCache methodCache = m.getAnnotation(MethodCache.class); second = methodCache.second(); break; } } } if(second>0){ // annotation没有设second值则使用ehcache.xml中自定义值 element.setTimeToIdle(second); element.setTimeToLive(second); } cache.put(element); }catch(Exception e){ } } } System.out.println("aop end "); return element.getValue(); } private String getCacheKey(String targetName, String methodName, Object[] arguments) { StringBuffer sb = new StringBuffer(); sb.append(targetName).append(".").append(methodName); if ((arguments != null) && (arguments.length != 0)) { for (int i = 0; i < arguments.length; i++) { if (arguments[i] instanceof Date) { sb.append(".").append( DateUtil.datetoString((Date) arguments[i])); } else { sb.append(".").append(arguments[i]); } } } return sb.toString(); } }
Spring配置文件
<bean id = "methodCacheAspectJ" class="com.zhang.shine.cache.MethodCacheAspectJ" > <property name="cache"> <!-- <ref local="methodCache" /> --> <ref bean="methodCache"/> </property> </bean> <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"> <property name="configLocation"> <value>classpath:ehcache.xml</value> </property> </bean> <!-- 定义ehCache的工厂,并设置所使用的Cache name --> <bean id="methodCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean"> <property name="cacheManager"> <ref local="cacheManager" /> </property> <property name="cacheName"> <value>DEFAULT_CACHE</value> </property> </bean> <bean id="sev" class="com.zhang.shine.cache.Sev"></bean>
ehcache.xml
<?xml version="1.0" encoding="UTF-8"?> <ehcache> <diskStore path="/home/workspace/gzshine/trunk/ehcache"/> <defaultCache maxElementsInMemory="50000" eternal="false" overflowToDisk="false" timeToIdleSeconds="7200" timeToLiveSeconds="7200" diskPersistent="false" diskExpiryThreadIntervalSeconds="120"/> <cache name="DEFAULT_CACHE" maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="3600" overflowToDisk="true" /> </ehcache>
测试类
package test; import net.sf.cglib.core.DebuggingClassWriter; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.zhang.shine.cache.CallImpl; import com.zhang.shine.cache.MyImpl; import com.zhang.shine.cache.Sev; import sun.misc.*; /** * 1.产生代理类$Proxy0类 执行了Proxy.newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h) 将产生$Proxy0类,它继承Proxy对象,并根据第二个参数,实现了被代理类的所有接口,自然就可以生成接口要实现的所有方法了(这时候会重写hashcode,toString和equals三个方法),但是还没有具体的实现体; 2. 将代理类$Proxy0类加载到JVM中 这时候是根据Proxy.newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)它的第一个参数----就是被代理类的类加载器,把当前的代理类加载到JVM中 3. 创建代理类$Proxy0类的对象 调用的$Proxy0类的$Proxy0(InvocationHandler)构造函数,生成$Proxy0类的对象 参数就是Proxy.newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)它的第三个参数 这个参数就是我们自己实现的InvocationHandler对象,我们知道InvocationHandler对象中组合加入了代理类代理的接口类的实现类;所以,$Proxy0对象调用所有要实现的接口的方法,都会调用InvocationHandler对象的invoke()方法实现; 4. 生成代理类的class byte 动态代理生成的都是二进制class字节码 * @author zhang_zengmin * */ public class TestAOP { public static void main(String[] args) throws Exception{ //cglib 代理对象class文件输出目录 如果是jdk动态代理就不输出 /** * cglib头部信息 public class Sev$$EnhancerByCGLIB$$bb4c2585 extends Sev implements SpringProxy, Advised, Factory */ System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "c://class" ); ApplicationContext ap =new ClassPathXmlApplicationContext("ApplicationContent.xml"); Sev s = (Sev)ap.getBean("sev"); //Sev s = new Sev(); s.getSort(1, 2); //Thread.sleep(3010); s.getSort(1, 3); // s.getSort(); System.out.println(s.getClass()); MyImpl my=(MyImpl)ap.getBean("my"); my.pao(); //动态代理获取字节码 头部信息 //public final class $Proxy0 extends Proxy implements Manager { /*byte[] proxyClassFile = ProxyGenerator.generateProxyClass( proxyName, interfaces);*/ /** * 接口默认Jdk代理 */ // ICall call = (ICall)ap.getBean("call"); // call.cll(); // Thread.sleep(60000); /* Enhancer enhancer = new Enhancer();//通过类Enhancer创建代理对象 enhancer.setSuperclass(Sev.class);//传入创建代理对象的类 ClassReader cr = new ClassReader(enhancer.getClass().getName()); byte[] a = cr.b; File f =new File("c://Sev.class"); FileOutputStream fout = new FileOutputStream(f); fout.write(a); fout.flush(); fout.close();*/ } }
发表评论
-
spring session序列化问题排查
2017-12-01 19:07 6264严重: Servlet.service() for ser ... -
spring mvc统一异常处理(@ControllerAdvice + @ExceptionHandler)
2017-12-01 17:09 2998spring 封装了非常强大的异常处理机制。本文选取@Co ... -
springboot注解
2017-12-01 09:44 1016@RestController和@RequestMappin ... -
Spring 4 xml 注解配置谅解
2017-12-01 09:39 1110《Spring in Action》4th E ... -
利用junit对springMVC的Controller进行测试
2017-11-30 16:26 1441平时对junit测试service/D ... -
spring cloud config实现datasource的热部署
2017-11-21 16:44 1615关于spring cloud config的基本使用,前面的 ... -
Spring+MyBatis实现数据库读写分离方案
2017-11-20 17:15 1075百度关键词:spring mybatis 多数据源 读写分离 ... -
spring session 退出登录 清理session
2017-11-10 09:26 6469/** * Allows creating an ... -
spring http session 监听 创建 失效session
2017-11-15 09:35 4870一.流程概述 主要是通过扩展ServletRequest ... -
spring session spring:session:sessions:expires 源码跟踪
2017-11-14 09:37 1500/** * Saves any attribut ... -
spring session 考虑问题解答
2017-11-09 09:50 647相关问题 2.Redis容量考虑,由于spring see ... -
spring 获取bean 测试
2017-11-09 09:51 665package com.jayway.springsess ... -
spring父子容器与读取properties文件
2017-11-09 09:51 821读取properties文件中的内容,可以使用@Value ... -
Spring在代码中获取bean的几种方式
2017-11-08 09:46 1219方法一:在初始化时保存ApplicationContext对 ... -
Spring中DispacherServlet、WebApplicationContext、ServletContext的关系
2017-11-08 09:41 815解释一: 要想很好理解这三个上下文的关系,需 ... -
Spring以及SPringmvc相关问题: ServletContext -父子容器
2017-11-08 09:41 615总结如下: 明确了Servlet规范中Servl ... -
DelegatingFilterProxy
2017-11-08 09:48 1207摘要: 配置过滤器代理类,通过spring配置的bean来 ... -
DelegatingFilterProxy-api
2017-11-09 09:51 551为什么用DelegatingFilterProxy ... -
spring的启动过程——spring和springMVC父子容器的原理
2017-11-15 09:29 715要想很好理解这三个上下文的关系,需要先熟悉spri ... -
spring中bean被多次实例化问题
2017-11-13 09:33 52121. 描述 spring中提供了两种主要方式实例化bea ...
相关推荐
3. **创建缓存注解**:在Spring AOP中,我们可以创建一个自定义注解来标记需要缓存的方法。例如,创建一个名为`@Cacheable`的注解: ```java @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) ...
在本篇【Spring AOP+ehCache简单缓存系统解决方案】中,我们将探讨如何利用Spring AOP(面向切面编程)和ehCache框架来构建一个高效、简单的缓存系统,以提升应用程序的性能。ehCache是一款流行的开源Java缓存库,它...
Spring AOP实现Redis缓存数据库查询 Spring AOP(Aspect-Oriented Programming,面向方面编程)是一种编程技术,可以将散落在各个对象之间的逻辑提取出来,封装成一个个独立的模块,并将这些模块组合起来,形成一...
本代码通过使用spring aop+ehcache的技术,实现了方法级别的查询缓存,主要原理是 方法的完整路径+方法参数值,作为key,放入cache中,下次访问时先判断cache中是否有该key.
Spring源码中最难的问题之一是循环依赖问题,当Spring AOP遇上循环依赖时,该如何解决? Spring通过三级缓存机制解决循环依赖的问题。 在Spring中,bean的实例化过程中,会先尝试从三级缓存中获取bean,这也是...
Spring框架作为Java开发领域的领头羊之一,提供了强大的AOP支持。本文旨在深入探讨Spring AOP的核心概念及其原理。 #### 二、AOP基本概念 AOP是一种编程范式,其目的是提高模块化程度,特别是将那些对很多类都具有...
在Spring AOP(面向切面编程)中,自定义缓存是一种常见的优化技术,它可以显著提高应用程序的性能,减少对数据库或远程服务的重复访问。本实例将介绍如何利用Spring AOP来实现自定义缓存功能。 首先,理解Spring ...
Spring AOP可以结合缓存注解(如`@Cacheable`、`@CacheEvict`等)来实现高效的缓存操作,提升系统性能。 2. **第三章_proxy-demo.zip**:这个例子可能展示了如何创建和使用动态代理。你可能会看到如何通过Spring ...
5. **缓存管理**:在方法调用前检查是否有缓存结果,避免重复计算。 6. **错误处理**:统一处理异常,提供友好的错误信息。 通过学习和实践Spring AOP,开发者可以更高效地组织代码,将关注点分离,提升代码的...
- **缓存管理**:在方法调用前检查缓存,避免不必要的数据库查询。 ### 5. 示例项目`SpringAopPrj`分析 这个项目很可能是包含了一个Spring AOP的实战例子,可能包含了以下内容: - `LoggingAspect`类:定义切面,...
8. **AOP应用场景**:Spring AOP广泛应用于日志记录、事务管理、权限控制、缓存管理等场景。通过切面可以将这些通用功能与业务逻辑解耦,提高代码的可维护性和可重用性。 总之,Spring AOP的默认代理方式是动态代理...
标题 "使用Spring AOP对Web应用数据进行Memcached缓存" 涉及到的关键技术是Spring AOP(面向切面编程)和Memcached,这是一种常见的高性能、分布式内存对象缓存系统。在Web应用程序中,使用缓存可以显著提高数据访问...
9. **享元模式(Flyweight)**:享元模式在Spring AOP中不太直接体现,但在Spring框架的其他部分,如缓存管理,可能会用到此模式来减少内存消耗,通过共享大量细粒度对象的内部状态来降低内存占用。 10. **代理模式...
此外,Spring AOP还支持其他类型的通知,如`@After`(方法执行后)、`@AfterReturning`(正常返回后)、`@AfterThrowing`(抛出异常后)和`@Around`(环绕通知,完全控制方法的调用过程)。每种通知类型都有其特定的...
在实际项目中,可能还需要考虑其他因素,如缓存策略、性能优化以及与其他安全框架(如Spring Security)的协同工作等。总的来说,Spring AOP与Oracle的数据权限控制相结合,为大型企业应用提供了强大的安全保障。
Spring AOP 和 EhCache 结合使用提供了一个简单而有效的缓存解决方案,主要目的是优化系统性能,减少对数据库的频繁访问。下面将详细解释这个解决方案的关键组成部分。 首先,EhCache 是一个广泛使用的开源 Java ...
无论是对于初学者还是资深开发者来说,掌握Spring AOP都是非常有价值的技能之一。通过对Spring AOP的基本概念、配置方式以及源码层面的理解,我们可以更好地利用这一强大的工具来优化我们的应用程序。
8. **AOP应用场景**:Spring AOP广泛应用于事务管理、安全控制、缓存管理、日志记录等多个领域。例如,`@Transactional`注解可以方便地声明一个方法需要在数据库事务中执行。 9. **与其他Spring模块的集成**:...