1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  package org.springframework.cache.interceptor;
17  
18  import org.aopalliance.aop.Advice;
19  import org.springframework.aop.Pointcut;
20  import org.springframework.aop.framework.ProxyFactory;
21  import org.springframework.aop.support.AbstractPointcutAdvisor;
22  import org.springframework.aop.support.AopUtils;
23  import org.springframework.cache.CacheManager;
24  import org.springframework.cache.annotation.AnnotationCacheOperationSource;
25  
26  
27  
28  
29  public final class CacheProxy {
30      
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41      private CacheProxy() {
42          throw new IllegalArgumentException("do not call");
43      }
44  
45      
46  
47  
48  
49  
50  
51  
52  
53      public static <T> T createCacheProxy(T o, CacheManager cacheManager) {
54          if (o == null) {
55              throw new IllegalArgumentException("o is null");
56          }
57  
58          if (cacheManager == null) {
59              throw new IllegalArgumentException("cacheManager is null");
60          }
61  
62          
63  
64          final AnnotationCacheOperationSource source = new AnnotationCacheOperationSource();
65  
66          final CacheInterceptor interceptor = new CacheInterceptor();
67          interceptor.setCacheManager(cacheManager);
68          interceptor.setCacheOperationSources(source);
69          
70          interceptor.afterPropertiesSet();
71  
72          final ProxyPointcut pointcut = new ProxyPointcut(source);
73          final ProxyPointCutAdvisor advisor = new ProxyPointCutAdvisor(pointcut, interceptor);
74  
75          if (AopUtils.canApply(advisor, o.getClass())) {
76              final ProxyFactory proxyFactory = new ProxyFactory(o);
77              proxyFactory.addAdvisor(advisor);
78              return (T) proxyFactory.getProxy();
79          }
80          return o;
81      }
82  
83      private static class ProxyPointcut extends CacheOperationSourcePointcut {
84          private static final long serialVersionUID = 6050508570006106939L;
85  
86          private final AnnotationCacheOperationSource source;
87  
88          private ProxyPointcut(AnnotationCacheOperationSource source) {
89              this.source = source;
90          }
91  
92          @Override
93          protected CacheOperationSource getCacheOperationSource() {
94              return source;
95          }
96      }
97  
98      private static class ProxyPointCutAdvisor extends AbstractPointcutAdvisor {
99  
100         private static final long serialVersionUID = 6050508570006106939L;
101 
102         private final CacheOperationSourcePointcut pointcut;
103         private final CacheInterceptor interceptor;
104 
105         private ProxyPointCutAdvisor(CacheOperationSourcePointcut pointcut, CacheInterceptor interceptor) {
106             this.pointcut = pointcut;
107             this.interceptor = interceptor;
108         }
109 
110         @Override
111         public Pointcut getPointcut() {
112             return pointcut;
113         }
114 
115         @Override
116         public Advice getAdvice() {
117             return interceptor;
118         }
119     }
120 }