org.jdal.aop.SerializableProxyUtils.java Source code

Java tutorial

Introduction

Here is the source code for org.jdal.aop.SerializableProxyUtils.java

Source

/*
 * Copyright 2009-2014 Jose Luis Martin.
 *
 * 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 org.jdal.aop;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdal.aop.config.SerializableProxyFactoryBean;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.framework.autoproxy.AutoProxyUtils;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.DependencyDescriptor;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;

/**
 * Utility class for creating proxy bean definitions.
 * <p>
 * Note: This class includes code from {@link org.springframework.aop.scope.ScopedProxyUtils}
 * </p>
 * @author Jose Luis Martin
 * @since 2.0
 */
public class SerializableProxyUtils {

    public static Log log = LogFactory.getLog(SerializableProxyUtils.class);
    public static final String TARGET_NAME_PREFIX = "jdalSerializableProxy.";

    public static BeanDefinitionHolder createSerializableProxy(BeanDefinitionHolder definition,
            BeanDefinitionRegistry registry, boolean proxyTargetClass) {

        String originalBeanName = definition.getBeanName();
        BeanDefinition targetDefinition = definition.getBeanDefinition();

        // Create a scoped proxy definition for the original bean name,
        // "hiding" the target bean in an internal target definition.
        RootBeanDefinition proxyDefinition = new RootBeanDefinition(SerializableProxyFactoryBean.class);
        proxyDefinition.setOriginatingBeanDefinition(definition.getBeanDefinition());
        proxyDefinition.setSource(definition.getSource());
        proxyDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);

        String targetBeanName = getTargetBeanName(originalBeanName);
        proxyDefinition.getPropertyValues().add("targetBeanName", targetBeanName);

        if (proxyTargetClass) {
            targetDefinition.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
        } else {
            proxyDefinition.getPropertyValues().add("proxyTargetClass", Boolean.FALSE);
        }

        // Copy autowire settings from original bean definition.
        proxyDefinition.setAutowireCandidate(targetDefinition.isAutowireCandidate());
        proxyDefinition.setPrimary(targetDefinition.isPrimary());
        if (targetDefinition instanceof AbstractBeanDefinition) {
            proxyDefinition.copyQualifiersFrom((AbstractBeanDefinition) targetDefinition);
        }

        // Set singleton property of FactoryBean
        proxyDefinition.getPropertyValues().add("singleton", !targetDefinition.isPrototype());

        // The target bean should be ignored in favor of the scoped proxy.
        targetDefinition.setAutowireCandidate(false);
        targetDefinition.setPrimary(false);

        // Register the target bean as separate bean in the factory.
        registry.registerBeanDefinition(targetBeanName, targetDefinition);

        // Return the scoped proxy definition as primary bean definition
        // (potentially an inner bean).
        return new BeanDefinitionHolder(proxyDefinition, originalBeanName, definition.getAliases());
    }

    public static String getTargetBeanName(String originalBeanName) {
        return TARGET_NAME_PREFIX + originalBeanName;
    }

    /**
     * Create a new Serializable proxy for the given target
     * @param target target to proxy
     * @param proxyTargetClass true to force CGLIB proxies
     * @param useMemoryCache if true keep a reference to target object in memory
     * @param beanFactory beanFactory to use.
     * @param descriptor Dependency descriptor
     * @param beanName name of bean holding the dependency
     * @return a new serializable proxy
     */
    public static Object createSerializableProxy(Object target, boolean proxyTargetClass, boolean useMemoryCache,
            ConfigurableListableBeanFactory beanFactory, DependencyDescriptor descriptor, String beanName) {
        if (target instanceof SerializableAopProxy)
            return target;

        if (log.isDebugEnabled())
            log.debug("Creating serializable proxy for [" + descriptor.getDependencyName() + "]" + " in bean ["
                    + beanName + "]");

        SerializableReference reference = new SerializableReference(target, proxyTargetClass, useMemoryCache,
                beanFactory, descriptor, beanName);

        return createSerializableProxy(target, reference);
    }

    /**
     * Create a new Serializable proxy for the given target
     * @param target target to proxy
     * @param proxyTargetClass true to force CGLIB proxies
     * @param useMemoryCache if true keep a reference to target object in memory
     * @param beanFactory beanFactory to use.
     * @param targetBeanName name of target bean
     * @return a new serializable proxy
     * 
     */
    public static Object createSerializableProxy(Object target, boolean proxyTargetClass, boolean useMemoryCache,
            ConfigurableListableBeanFactory beanFactory, String targetBeanName) {

        if (target instanceof SerializableAopProxy)
            return target;

        if (log.isDebugEnabled())
            log.debug("Creating serializable proxy for target bean [" + targetBeanName + "]");

        SerializableReference reference = new SerializableReference(target, proxyTargetClass, useMemoryCache,
                beanFactory, targetBeanName);

        return createSerializableProxy(target, reference);

    }

    /**
     * Creates a new serializable proxy for given target holding it in memory 
     * until deserialization.
     * 
     * @param target object to proxy
     * @return a serialziable proxy for target.
     */
    public static Object createCachedSerializableProxy(Object target) {
        return createSerializableProxy(target, true, true, null, null);
    }

    /**
     * Create a new Serializable proxy for the given target
     * @param target target to proxy
     * @param beanFactory beanFactory to use.
     * @param targetBeanName name of the target bean.
     * @return a new serializable proxy
     */
    public static Object createSerializableProxy(Object target, ConfigurableListableBeanFactory beanFactory,
            String targetBeanName) {

        return createSerializableProxy(target, false, false, beanFactory, targetBeanName);
    }

    /**
     * Create a new Serializable proxy for the given target.
     * @param target target to proxy
     * @param reference serializable reference 
     * @return a new serializable proxy
     */
    private static Object createSerializableProxy(Object target, SerializableReference reference) {
        ProxyFactory pf = new ProxyFactory(target);
        pf.setExposeProxy(true);
        pf.setProxyTargetClass(reference.isProxyTargetClass());
        pf.addInterface(SerializableObject.class);
        pf.addAdvice(new SerializableIntroductionInterceptor(reference));

        return pf.getProxy(reference.getBeanFactory().getBeanClassLoader());
    }
}