Package com.alibaba.citrus.springext.util

Source Code of com.alibaba.citrus.springext.util.SpringExtUtil$AbstractProxy

/*
* Copyright (c) 2002-2012 Alibaba Group Holding Limited.
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.alibaba.citrus.springext.util;

import static com.alibaba.citrus.springext.util.DomUtil.*;
import static com.alibaba.citrus.util.ArrayUtil.*;
import static com.alibaba.citrus.util.Assert.*;
import static com.alibaba.citrus.util.BasicConstant.*;
import static com.alibaba.citrus.util.CollectionUtil.*;
import static com.alibaba.citrus.util.ObjectUtil.*;
import static com.alibaba.citrus.util.StringUtil.*;
import static org.springframework.util.ReflectionUtils.*;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.alibaba.citrus.springext.ConfigurationPoint;
import com.alibaba.citrus.springext.Contribution;
import com.alibaba.citrus.util.Assert;
import net.sf.cglib.core.DefaultNamingPolicy;
import net.sf.cglib.core.Predicate;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.CallbackFilter;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.BeanReference;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.DependencyDescriptor;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.ManagedList;
import org.springframework.beans.factory.support.ManagedMap;
import org.springframework.beans.factory.support.ManagedSet;
import org.springframework.beans.factory.xml.BeanDefinitionParserDelegate;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.context.ApplicationContext;
import org.springframework.core.MethodParameter;
import org.springframework.util.ObjectUtils;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;

public class SpringExtUtil {
    private static final Logger log = LoggerFactory.getLogger(SpringExtUtil.class);

    public static <T> T getBeanOfType(BeanFactory beanFactory, Class<T> type) {
        if (beanFactory == null || !(beanFactory instanceof ListableBeanFactory)) {
            return null;
        }

        ListableBeanFactory listable = (ListableBeanFactory) beanFactory;

        @SuppressWarnings("unchecked")
        Map<String, T> beans = listable.getBeansOfType(type);

        if (beans == null || beans.isEmpty()) {
            return null;
        }

        return beans.values().iterator().next();
    }

    public static <T> T autowireAndInitialize(T existingBean, ApplicationContext context, int autowireMode,
                                              String beanName) {
        context.getAutowireCapableBeanFactory().autowireBeanProperties(existingBean, autowireMode, false);
        context.getAutowireCapableBeanFactory().initializeBean(existingBean, beanName);

        return existingBean;
    }

    public static ConfigurationPoint getSiblingConfigurationPoint(String configurationPointName, Contribution contrib) {
        assertNotNull(contrib, "contribution");
        return getSiblingConfigurationPoint(configurationPointName, contrib.getConfigurationPoint());
    }

    public static ConfigurationPoint getSiblingConfigurationPoint(String configurationPointName, ConfigurationPoint cp) {
        assertNotNull(configurationPointName, "configurationPointName");
        assertNotNull(cp, "configurationPoint");

        ConfigurationPoint siblingCp = cp.getConfigurationPoints().getConfigurationPointByName(configurationPointName);

        assertNotNull(siblingCp, "could not find configuration point of name: %s", configurationPointName);

        return siblingCp;
    }

    /** 创建<code>ManagedList</code>,避免type safety警告。 */
    @SuppressWarnings("unchecked")
    public static List<Object> createManagedList(Element element, ParserContext parserContext) {
        ManagedList list = new ManagedList();

        list.setSource(parserContext.getReaderContext().extractSource(element));

        return list;
    }

    /** 创建<code>ManagedMap</code>,避免type safety警告。 */
    @SuppressWarnings("unchecked")
    public static Map<Object, Object> createManagedMap(Element element, ParserContext parserContext) {
        ManagedMap map = new ManagedMap();

        map.setSource(parserContext.getReaderContext().extractSource(element));

        return map;
    }

    /** 创建<code>ManagedSet</code>,避免type safety警告。 */
    @SuppressWarnings("unchecked")
    public static Set<Object> createManagedSet(Element element, ParserContext parserContext) {
        ManagedSet set = new ManagedSet();

        set.setSource(parserContext.getReaderContext().extractSource(element));

        return set;
    }

    /** 将子element的值设入properties。 */
    public static void subElementsToProperties(Element element, BeanDefinitionBuilder builder) {
        subElementsToProperties(element, null, builder, null);
    }

    /** 将子element的值设入properties。 */
    public static void subElementsToProperties(Element element, BeanDefinitionBuilder builder, ElementSelector selector) {
        subElementsToProperties(element, null, builder, selector);
    }

    /** 将子element的值设入properties。 */
    public static void subElementsToProperties(Element element, String propertyPrefix, BeanDefinitionBuilder builder,
                                               ElementSelector selector) {
        for (Element subElement : subElements(element, selector)) {
            elementToProperty(subElement, propertyPrefix, builder);
        }
    }

    /** 将一个element的值设入property。 */
    public static void elementToProperty(Element element, BeanDefinitionBuilder builder) {
        elementToProperty(element, null, builder);
    }

    /** 将一个element的值设入property。 */
    public static void elementToProperty(Element element, String propertyPrefix, BeanDefinitionBuilder builder) {
        String propName = element.getLocalName();

        if (!isEmpty(propertyPrefix)) {
            propName = propertyPrefix + propName;
        }

        builder.addPropertyValue(propName, trimToNull(element.getTextContent()));
    }

    /** 将attribute的值设入properties。 */
    public static void attributesToProperties(Element element, BeanDefinitionBuilder builder, String... attrNames) {
        attributesToProperties(element, null, builder, attrNames);
    }

    /** 将attribute的值设入properties。 */
    public static void attributesToProperties(Element element, String propertyPrefix, BeanDefinitionBuilder builder,
                                              String... attrNames) {
        NamedNodeMap attrs = element.getAttributes();
        Set<String> attrNameSet;

        if (isEmptyArray(attrNames)) {
            attrNameSet = null;
        } else {
            attrNameSet = createHashSet(attrNames);
        }

        for (int i = 0; i < attrs.getLength(); i++) {
            Attr attr = (Attr) attrs.item(i);

            if (attrNameSet == null || attrNameSet.contains(attr.getNodeName())) {
                attributeToProperty(attr, propertyPrefix, builder);
            }
        }
    }

    /** 将一个attribute的值设入properties。 */
    public static void attributeToProperty(Attr attr, String propertyPrefix, BeanDefinitionBuilder builder) {
        String propName = attr.getNodeName();

        if (!isEmpty(propertyPrefix)) {
            propName = propertyPrefix + propName;
        }

        builder.addPropertyValue(propName, trimToNull(attr.getNodeValue()));
    }

    /** 解析beans:bean的attributes。 */
    public static void parseBeanDefinitionAttributes(Element element, ParserContext parserContext,
                                                     BeanDefinitionBuilder builder) {
        parserContext.getDelegate().parseBeanDefinitionAttributes(element, null, null, builder.getRawBeanDefinition());
    }

    /**
     * 从element创建指定configuration point的bean。如果element不属于该configuration
     * point的名字空间,则返回<code>null</code>
     */
    public static BeanDefinitionHolder parseConfigurationPointBean(Element element, ConfigurationPoint cp,
                                                                   ParserContext parserContext,
                                                                   BeanDefinitionBuilder containingBeanBuilder) {
        assertNotNull(cp, "configurationPoint");

        BeanDefinitionParserDelegate delegate = parserContext.getDelegate();
        boolean isInnerBean = containingBeanBuilder != null;
        BeanDefinition containingBean = isInnerBean ? containingBeanBuilder.getRawBeanDefinition() : null;
        ElementSelector customSelector = ns(cp.getNamespaceUri());

        // 解析custom element。
        if (customSelector.accept(element)) {
            AbstractBeanDefinition bean = (AbstractBeanDefinition) delegate.parseCustomElement(element, containingBean);
            String beanName = trimToNull(element.getAttribute("id"));

            if (beanName == null) {
                beanName = BeanDefinitionReaderUtils.generateBeanName(bean, parserContext.getRegistry(), isInnerBean);
            }

            return new BeanDefinitionHolder(bean, beanName);
        }

        return null;
    }

    /** 解析bean element。 */
    public static Object parseBean(Element element, ParserContext parserContext,
                                   BeanDefinitionBuilder containingBeanBuilder) {
        return parseBean(element, parserContext,
                         containingBeanBuilder == null ? null : containingBeanBuilder.getRawBeanDefinition());
    }

    /** 解析bean element。 */
    public static Object parseBean(Element element, ParserContext parserContext, BeanDefinition containingBean) {
        BeanDefinitionParserDelegate delegate = parserContext.getDelegate();
        String refName = trimToNull(element.getAttribute("ref"));

        // 如果是ref
        if (refName != null) {
            NamedBeanReference ref = new NamedBeanReference(refName, element.getAttribute("id"));
            ref.setSource(parserContext.extractSource(element));

            return ref;
        }

        // 如果是bean
        else {
            BeanDefinitionHolder beanHolder = delegate.parseBeanDefinitionElement(element, containingBean);

            if (beanHolder != null) {
                beanHolder = delegate.decorateBeanDefinitionIfRequired(element, beanHolder, containingBean);
            }

            return beanHolder;
        }
    }

    /** 取得对象的beanName。如不支持,则返回<code>null</code>。 */
    public static String getBeanName(Object bean) {
        if (bean instanceof BeanDefinitionHolder) {
            return ((BeanDefinitionHolder) bean).getBeanName();
        } else if (bean instanceof NamedBeanReference) {
            return ((NamedBeanReference) bean).getId();
        } else if (bean instanceof BeanReference) {
            return ((BeanReference) bean).getBeanName();
        } else {
            return null;
        }
    }

    /**
     * 根据baseName创建不重复的beanName。
     * <p>
     * 有别于 {@link BeanDefinitionReaderUtils.generateBeanName()}
     * 方法,这里使用指定的baseName,而不是使用类名作为baseName。
     * </p>
     */
    public static String generateBeanName(String baseName, BeanDefinitionRegistry registry) {
        return generateBeanName(baseName, registry, null, false);
    }

    /**
     * 根据baseName创建不重复的beanName。
     * <p>
     * 有别于 {@link BeanDefinitionReaderUtils.generateBeanName()}
     * 方法,这里使用指定的baseName,而不是使用类名作为baseName。
     * </p>
     * <p>
     * 如果是innerBean,则需要提供bean definition来生成id。
     * </p>
     */
    public static String generateBeanName(String baseName, BeanDefinitionRegistry registry, BeanDefinition definition,
                                          boolean isInnerBean) {
        baseName = assertNotNull(trimToNull(baseName), "baseName");
        String name;

        if (isInnerBean) {
            name = baseName + BeanDefinitionReaderUtils.GENERATED_BEAN_NAME_SEPARATOR
                   + ObjectUtils.getIdentityHexString(definition);
        } else {
            name = baseName;

            for (int i = 0; registry.containsBeanDefinition(name); i++) {
                name = baseName + BeanDefinitionReaderUtils.GENERATED_BEAN_NAME_SEPARATOR + i;
            }
        }

        return name;
    }

    /** 添加一个constructor参数。 */
    public static void addConstructorArg(BeanDefinitionBuilder builder, boolean required, Class<?> argType) {
        builder.addConstructorArgValue(createConstructorArg(builder.getRawBeanDefinition().getBeanClass(), required,
                                                            argType));
    }

    /**
     * 添加一个constructor参数。
     * <p>
     * 假如未指定argTypes,则只能有一个constructor。
     * </p>
     */
    public static void addConstructorArg(BeanDefinitionBuilder builder, boolean required, int argIndex,
                                         Class<?>... argTypes) {
        builder.addConstructorArgValue(createConstructorArg(builder.getRawBeanDefinition().getBeanClass(), required,
                                                            argIndex, argTypes));
    }

    /**
     * 本方法提供一个bean definition,可被<code>BeanDefinitionParser</code>
     * 调用,用来注入可选的constructor arg,并支持resolvableDependency对象以及optional选项。
     */
    public static BeanDefinition createConstructorArg(Class<?> beanType, boolean required, Class<?> argType) {
        return createConstructorArg(beanType, required, 0, argType);
    }

    /**
     * Spring有三种注入方法:
     * <ul>
     * <li>通过明确的bean definition声明来注入对象,缺点是无法注入
     * <code>ConfigurableListableBeanFactory.registerResolvableDependency()</code>
     * 中注册的对象,如<code>HttpServletRequest</code></li>
     * <li>通过autowire
     * byConstructor来注入对象,可以注入包括resolvableDependency在内的对象,缺点是无法将注入对象设成“optional”
     * ,即:对象不存在,则报错。</li>
     * <li>通过autowire
     * byName/byType来注入对象,相当于optional注入,缺点是不能注入包括resolvableDependency在内的对象
     * ,且会自动对所有property进行注入,无法精确控制,可能造成不确定情况。</li>
     * <li>通过<code>@Autowired</code>
     * annotation来注入对象,可以注入包括resolvableDependency在内的对象
     * ,也可以设置optional选项。缺点是有侵入性,必须修改bean class的代码。Springext试图将注入的多样性限定在
     * <code>BeanDefinitionParser</code>的范围中,因此使用annotation不是最好的方法。</li>
     * </ul>
     * <p>
     * 本方法提供一个bean definition,可被<code>BeanDefinitionParser</code>
     * 调用,用来注入到的constructor arg,并支持resolvableDependency对象以及optional选项。
     * </p>
     */
    public static BeanDefinition createConstructorArg(Class<?> beanType, boolean required, int argIndex,
                                                      Class<?>... argTypes) {
        assertNotNull(beanType, "beanType");
        argTypes = defaultIfNull(argTypes, EMPTY_CLASS_ARRAY);

        // 尝试取得constructor
        Constructor<?> constructor;

        if (isEmptyArray(argTypes)) {
            Constructor<?>[] constructors = beanType.getConstructors();

            assertTrue(constructors.length == 1, "%d constructors found, please specify argTypes", constructors.length);
            constructor = constructors[0];
            argTypes = constructor.getParameterTypes();
        } else {
            try {
                constructor = beanType.getConstructor(argTypes);
            } catch (NoSuchMethodException e) {
                throw new IllegalArgumentException("Could not find constructor", e);
            }
        }

        assertTrue(argIndex >= 0 && argIndex < argTypes.length, "argIndex is out of bound: %d", argIndex);

        BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(ConstructorArg.class);

        builder.addConstructorArgValue(constructor);
        builder.addConstructorArgValue(argTypes[argIndex]);
        builder.addConstructorArgValue(argIndex);
        builder.addConstructorArgValue(required);

        return builder.getBeanDefinition();
    }

    /** 添加一个bean引用,支持optional选项。 */
    public static void addPropertyRef(BeanDefinitionBuilder builder, String propertyName, String beanName,
                                      Class<?> beanType, boolean required) {
        if (required) {
            builder.addPropertyReference(propertyName, beanName);
        } else {
            builder.addPropertyValue(propertyName, createOptionalPropertyRef(beanName, beanType));
        }
    }

    /**
     * 本方法提供一个bean definition,可被<code>BeanDefinitionParser</code>
     * 调用,用来注入到的property arg,不支持resolvableDependency对象,但支持optional注入。
     */
    public static BeanDefinition createOptionalPropertyRef(String beanName, Class<?> beanType) {
        beanName = assertNotNull(trimToNull(beanName), "beanName");
        assertNotNull(beanType, "beanType");

        BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(OptionalPropertyRef.class);

        builder.addConstructorArgValue(beanName);
        builder.addConstructorArgValue(beanType);

        return builder.getBeanDefinition();
    }

    private final static DefaultInterceptor defaultInterceptor = new DefaultInterceptor();
    private final static ProxiedFilter      proxiedFilter      = new ProxiedFilter();

    /**
     * 创建指定interface的proxy,当proxy的方法被调用时,proxy将会从factory中取得实际对象,
     * 然后将调用delegate给实际对象来执行。
     */
    public static <T> T createProxy(final Class<T> intfs, final ProxyTargetFactory factory) {
        return createProxy(intfs, null, factory);
    }

    /**
     * 创建指定interface的proxy,当proxy的方法被调用时,proxy将会从factory中取得实际对象,
     * 然后将调用delegate给实际对象来执行。
     */
    public static <T> T createProxy(Class<T> intfs, ClassLoader classLoader, final ProxyTargetFactory factory) {
        assertNotNull(intfs, "no interface");
        assertNotNull(factory, "no ProxyTargetFactory");

        try {
            intfs.getMethod("getObject");
            throw new IllegalArgumentException("Method name conflict: interface " + intfs.getName() + ".getObject()");
        } catch (NoSuchMethodException e) {
        }

        Enhancer generator = new Enhancer();

        generator.setClassLoader(classLoader);
        generator.setSuperclass(AbstractProxy.class);
        generator.setInterfaces(new Class<?>[] { intfs });

        generator.setCallbacks(new Callback[] { defaultInterceptor, new ProxiedInterceptor(factory) });
        generator.setCallbackFilter(proxiedFilter);
        generator.setNamingPolicy(new ProxiedNamingPolicy(intfs));

        return intfs.cast(generator.create(new Class<?>[] { Class.class, ProxyTargetFactory.class }, new Object[] {
                intfs, factory }));
    }

    /**
     * 确保所得到的对象为代理对象。
     * <p>
     * <strong>注意</strong>,此方法可以接受<code>null</code>值。如果想确保非空,请结合
     * {@link Assert.assertNotNull}方法使用。
     * </p>
     */
    public static <T> T assertProxy(T object) {
        if (object != null) {
            assertTrue(object instanceof ProxyTargetFactory,
                       "expects a proxy delegating to a real object, but got an object of type %s", object.getClass()
                                                                                                          .getName());
        }

        return object;
    }

    /** 取得proxy所指向的真实对象。 */
    @SuppressWarnings("unchecked")
    public static <T> T getProxyTarget(T object) {
        if (object instanceof ProxyTargetFactory) {
            try {
                return (T) ((ProxyTargetFactory) object).getObject();
            } catch (Exception e) {
                log.warn("Could not get proxied object from ProxyTargetFactory: {} {}", e.getClass().getSimpleName(),
                         e.getMessage());
                return null;
            }
        } else {
            return object;
        }
    }

    public static class ConstructorArg implements FactoryBean, BeanFactoryAware {
        private final Constructor<?>                  constructor;
        private final Class<?>                        argType;
        private final int                             argIndex;
        private final boolean                         required;
        private       ConfigurableListableBeanFactory context;

        public ConstructorArg(Constructor<?> constructor, Class<?> argType, int argIndex, boolean required) {
            this.constructor = constructor;
            this.argType = argType;
            this.argIndex = argIndex;
            this.required = required;
        }

        public void setBeanFactory(BeanFactory context) throws BeansException {
            BeanFactory factory = null;

            if (context instanceof ApplicationContext) {
                factory = ((ApplicationContext) context).getAutowireCapableBeanFactory();
            } else {
                factory = context;
            }

            if (factory instanceof ConfigurableListableBeanFactory) {
                this.context = (ConfigurableListableBeanFactory) factory;
            }
        }

        public Class<?> getObjectType() {
            return argType;
        }

        public boolean isSingleton() {
            return false;
        }

        public Object getObject() {
            if (required && context == null) {
                throw new IllegalArgumentException("could not get object of " + argType.getName()
                                                   + ": no Application Context");
            }

            Object object = null;

            if (context != null) {
                DependencyDescriptor dd = new DependencyDescriptor(new MethodParameter(constructor, argIndex), required);
                object = context.resolveDependency(dd, null);
            }

            return object;
        }
    }

    public static class OptionalPropertyRef implements FactoryBean, BeanFactoryAware {
        private final String      beanName;
        private final Class<?>    beanType;
        private       BeanFactory context;

        public OptionalPropertyRef(String beanName, Class<?> beanType) {
            this.beanName = beanName;
            this.beanType = beanType;
        }

        public void setBeanFactory(BeanFactory context) throws BeansException {
            this.context = context;
        }

        public Class<?> getObjectType() {
            return beanType;
        }

        public boolean isSingleton() {
            return false;
        }

        public Object getObject() {
            Object object = null;

            if (context != null) {
                try {
                    object = context.getBean(beanName);
                } catch (NoSuchBeanDefinitionException e) {
                    // ignore
                }
            }

            return object;
        }
    }

    /** 携带id的bean ref。 */
    private static class NamedBeanReference extends RuntimeBeanReference {
        private final String id;

        public NamedBeanReference(String beanName, String id) {
            this(beanName, id, false);
        }

        public NamedBeanReference(String beanName, String id, boolean toParent) {
            super(beanName, toParent);
            this.id = trimToNull(id);
        }

        public String getId() {
            return id == null ? getBeanName() : id;
        }

        @Override
        public String toString() {
            return '<' + (id == null ? "" : id + "=") + getBeanName() + '>';
        }
    }

    /** 服务于createProxy()方法,Proxy的基类。 */
    public static class AbstractProxy implements ProxyTargetFactory {
        private final Class<?>           intfs;
        private final ProxyTargetFactory factory;

        public AbstractProxy(Class<?> intfs, ProxyTargetFactory factory) {
            this.intfs = assertNotNull(intfs);
            this.factory = assertNotNull(factory, "ProxyTargetFactory");
        }

        public Object getObject() {
            return factory.getObject();
        }

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;

            result = prime * result + (factory == null ? 0 : factory.hashCode());

            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }

            if (obj == null) {
                return false;
            }

            if (getClass() != obj.getClass()) {
                return false;
            }

            AbstractProxy other = (AbstractProxy) obj;

            if (factory == null) {
                if (other.factory != null) {
                    return false;
                }
            } else if (!factory.equals(other.factory)) {
                return false;
            }

            return true;
        }

        @Override
        public String toString() {
            try {
                return factory.getObject().toString();
            } catch (Exception e) {
                return String.format("%s[%s: %s]", intfs.getSimpleName(), e.getClass().getSimpleName(), e.getMessage());
            }
        }
    }

    /** 服务于createProxy()方法,将调用转发给proxy对象本身。 */
    private static final class DefaultInterceptor implements MethodInterceptor {
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
            return proxy.invokeSuper(obj, args);
        }
    }

    /** 服务于createProxy()方法,将调用委托给ProxyTargetFactory所返回的对象。 */
    private static final class ProxiedInterceptor implements MethodInterceptor {
        private final ProxyTargetFactory factory;

        private ProxiedInterceptor(ProxyTargetFactory factory) {
            this.factory = factory;
        }

        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
            return proxy.invoke(factory.getObject(), args);
        }
    }

    /**
     * 服务于createProxy()方法,对于equals、hashCode、toString和ProxyTargetFactory.
     * getObject方法, 执行defaultInterceptor,否则执行proxiedInterceptor。
     */
    private static final class ProxiedFilter implements CallbackFilter {
        public int accept(Method method) {
            if (isEqualsMethod(method) || isHashCodeMethod(method) || isToStringMethod(method)
                || isProxyTargetFactoryMethod(method)) {
                return 0; // invoke super
            } else {
                return 1; // invoke proxied object
            }
        }

        private boolean isProxyTargetFactoryMethod(Method method) {
            return method != null && method.getName().equals("getObject") && method.getParameterTypes().length == 0;
        }
    }

    /** 服务于createProxy()方法,返回以interface name作为前缀的proxy class name。 */
    private static final class ProxiedNamingPolicy extends DefaultNamingPolicy {
        private final Class<?> intfs;

        private ProxiedNamingPolicy(Class<?> intfs) {
            this.intfs = intfs;
        }

        @Override
        public String getClassName(String prefix, String source, Object key, Predicate names) {
            if (AbstractProxy.class.getName().equals(prefix)) {
                prefix = intfs.getName();
            }

            return super.getClassName(prefix, source, key, names);
        }
    }
}
TOP

Related Classes of com.alibaba.citrus.springext.util.SpringExtUtil$AbstractProxy

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.