zoukankan      html  css  js  c++  java
  • spring aop 的一个demo(未完,待完善)

    假设我们有这样的一个场景 : 对于一个类的众多方法,有些方法需要从缓存读取数据,有些则需要直接从数据库读取数据。怎样实现呢?

    实现方案有多种。下面我说下常见的几种实现方案 :

    1、直接采用spring xml、或者  annotation AOP完成。但个人认为这种方案似乎有点不是很完美。

    原因 :  ①、如果只有针对这个类做切面拦截,这种方案是没有问题的,只需对需要走DB(or 缓存,两者择一)的方法配置切面。

        ②、那如果是多个类呢?统一做一个切面,对指定方法拦截,如selectXXX。但,还要考虑个特殊场景,每个人的代码风格不一致,你不能限制

        别人的风格,查询他就偏偏用queryXXX来命令。你能拦截到么?

    2、采用 ProxyFactory 拦截处理, 并且用java自定义的annotation来作为是否需要走缓存的方法唯一标识。(实现得不是很好,后期会持续优化,见谅

    看下代码

    1)自定义注解,标识是否需要走缓存

    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface CacheAnnotition {
    
    }

    2)接口定义

    public interface UserReadService {
        
        @CacheAnnotition
        public UserInfo getUserInfoById(Long id);
        
        public UserInfo getUserInfoByName(String name);
    }
    @Component("userReadService")
    public class UserReadServiceImpl implements UserReadService {
    
        @Override
        public UserInfo getUserInfoById(Long id) {
            System.out.println("获取用户信息");
            return null;
        }
        
        @Override
        public UserInfo getUserInfoByName(String name) {
            // TODO Auto-generated method stub
            return null;
        }
    
    }
    View Code
    public interface PeopleReadService {
        
        @CacheAnnotition
        public UserInfo getPeopleInfoById(Long id);
        
        public UserInfo getPeopleInfoByName(String name);
    }
    @Component("peopleReadService")
    public class PeopleReadServiceImpl implements PeopleReadService {
    
        @Override
        public UserInfo getPeopleInfoById(Long id) {
            System.out.println("getPeopleInfoById : 获取用户信息");
            return null;
        }
    
        @Override
        public UserInfo getPeopleInfoByName(String name) {
            // TODO Auto-generated method stub
            return null;
        }
    
    }
    View Code

    3)拦截处理核心逻辑

    public class ProxyFactoryDemo {
    
        public static Map<String, Class<?>> beanMap = new HashMap<String, Class<?>>();
        public static Map<String, Class<?>> instanceMap = new HashMap<String, Class<?>>();
    
        public static List<Object> proxyObjs = new ArrayList<Object>();
    
        static {
            beanMap.put("userReadService", UserReadService.class);
            beanMap.put("peopleReadService", PeopleReadService.class);
    
            instanceMap.put("userReadService", UserReadServiceImpl.class);
            instanceMap.put("peopleReadService", PeopleReadServiceImpl.class);
        }
    
        public static void main(String[] args) throws Exception {
            initProxyObjs();
            
            for(Object proxy : proxyObjs) {
                if (proxy instanceof UserReadService) {
                    UserReadService u = (UserReadService)proxy;
                    u.getUserInfoById(null);
                    u.getUserInfoByName(null);
                } else if(proxy instanceof PeopleReadService) {
                    PeopleReadService p = (PeopleReadService)proxy;
                    p.getPeopleInfoById(null);
                    p.getPeopleInfoByName(null);
                }
            }
        }
    
        public static void initProxyObjs() throws InstantiationException, IllegalAccessException {
            Iterator<String> it = beanMap.keySet().iterator();
            while (it.hasNext()) {
                String beanName = it.next();
                Class<?> beanClass = instanceMap.get(beanName);
                Object proxy = getProxy(beanClass.newInstance(), beanMap.get(beanName), beanName);
                proxyObjs.add(proxy);
            }
        }
    
        public static Object getProxy(final Object target, Class<?> aClass, final String beanName) {
    
            ProxyFactory factory = new ProxyFactory();
    
            factory.addInterface(aClass);
            factory.setTarget(target);
            factory.setOpaque(true);
            factory.addAdvice(new MethodInterceptor() {
    
                @Override
                public Object invoke(MethodInvocation invocation) throws Throwable {
                    System.out.println("start");
                    if (invocation.getMethod().isAnnotationPresent(CacheAnnotition.class)) {
                        System.out.println(invocation.getMethod().getName() + "需要走缓存");
                    } else {
                        System.out.println(invocation.getMethod().getName() + "不需要走缓存");
                    }
                    Object obj = invocation.proceed();
                    System.out.println("end");
                    return obj;
                }
            });
    
            return factory.getProxy(factory.getClass().getClassLoader());
        }
    }
  • 相关阅读:
    401. Binary Watch
    46. Permutations
    61. Rotate List
    142. Linked List Cycle II
    86. Partition List
    234. Palindrome Linked List
    19. Remove Nth Node From End of List
    141. Linked List Cycle
    524. Longest Word in Dictionary through Deleting
    android ListView详解
  • 原文地址:https://www.cnblogs.com/chenmo-xpw/p/5540592.html
Copyright © 2011-2022 走看看