com.ivanzhangwb.interpose.core.InterposeBootStrap.java Source code

Java tutorial

Introduction

Here is the source code for com.ivanzhangwb.interpose.core.InterposeBootStrap.java

Source

/*
 * Copyright 2013 Alibaba.com All right reserved. This software is the confidential and proprietary information of
 * Alibaba.com ("Confidential Information"). You shall not disclose such Confidential Information and shall use it only
 * in accordance with the terms of the license agreement you entered into with Alibaba.com.
 */
package com.ivanzhangwb.interpose.core;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import org.springframework.aop.framework.ProxyFactoryBean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.util.ClassUtils;

import com.ivanzhangwb.interpose.cache.InterposeAnnotationCache;
import com.ivanzhangwb.interpose.constants.InterposeConstants;
import com.ivanzhangwb.interpose.model.MethodInfo;

/**
 * AnnotationHandler.java???
 * 
 * @author zhangwenbo Jan 9, 2013 1:08:32 AM
 */
public class InterposeBootStrap implements DestructionAwareBeanPostProcessor, ApplicationContextAware {

    private ApplicationContext applicationContext = null;

    private volatile InterposeClassPathApplicationContext interposeClassPathApplicationContext;

    @Override
    public Object postProcessBeforeInitialization(final Object bean, final String beanName) throws BeansException {
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException {
        if (interposeClassPathApplicationContext == null) {
            interposeClassPathApplicationContext = new InterposeClassPathApplicationContext(
                    this.applicationContext);
        }
        boolean needInterpose = false;
        Class beanClass = bean.getClass();
        do {
            Method[] methods = beanClass.getDeclaredMethods();
            for (int i = 0; i < methods.length; i++) {
                if (Interpose.class != null && methods[i].isAnnotationPresent(Interpose.class)
                        && methods[i].equals(ClassUtils.getMostSpecificMethod(methods[i], bean.getClass()))) {
                    needInterpose = true;
                    handleMethodAnnotation(methods[i]);
                }
            }
            beanClass = beanClass.getSuperclass();
        } while (beanClass != null);

        if (needInterpose) {
            ConfigurableApplicationContext atx = (ConfigurableApplicationContext) interposeClassPathApplicationContext;
            DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) atx.getBeanFactory();
            ProxyFactoryBean factoryBean = new ProxyFactoryBean();
            factoryBean.setTarget(bean);
            factoryBean.setInterceptorNames(new String[] { InterposeConstants.INTERPOSE_CORE_INTERCEPTOR });
            factoryBean.setBeanFactory(beanFactory);
            return factoryBean.getObject();
        } else {
            return bean;
        }
    }

    /**
     * ?
     * 
     * @param methods
     * @param i
     */
    private void handleMethodAnnotation(Method method) {
        InterposeAnnotationCache.put(new MethodInfo(method.getName(), method.getParameterTypes()).toString(),
                method.getAnnotation(Interpose.class));
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @Override
    public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
        // do nothing.
    }
}