Package org.springmodules.resource.interceptor

Source Code of org.springmodules.resource.interceptor.ResourceProxyFactoryBean

/*
* Copyright 2002-2005 the original author or authors.
*
* 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.springmodules.resource.interceptor;

import org.springframework.aop.Advisor;
import org.springframework.aop.Pointcut;
import org.springframework.aop.TargetSource;
import org.springframework.aop.framework.ProxyConfig;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.framework.adapter.AdvisorAdapterRegistry;
import org.springframework.aop.framework.adapter.GlobalAdvisorAdapterRegistry;
import org.springframework.aop.support.AopUtils;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.target.SingletonTargetSource;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springmodules.resource.ResourceManager;

/**
* Proxy factory bean for simplified declarative transaction handling.
* Alternative to the standard AOP ProxyFactoryBean with a TransactionInterceptor.
*
* <p>This class is intended to cover the <i>typical</i> case of declarative
* transaction demarcation: namely, wrapping a singleton target object with a
* transactional proxy, proxying all the interfaces that the target implements.
*
* <p>There are three main properties to be specified:
*
* <ul>
* <li>"transactionManager": the PlatformTransactionManager implementation to use
* (for example, a JtaTransactionManager instance)
* <li>"target": the target object that a transactional proxy shouls be created for
* <li>"transactionAttributes": the transaction attributes (for example, propagation
* behavior and "readOnly" flag) per target method name (or method name pattern)
* </ul>
*
* <p>If the "transactionManager" property is not set explicitly and this FactoryBean
* is running in a ListableBeanFactory, a single matching bean of type
* PlatformTransactionManager will be fetched from the BeanFactory.
*
* <p>In contrast to TransactionInterceptor, the transaction attributes are
* specified as properties, with method names as keys and transaction attribute
* descriptors as values. Method names are always applied to the target class.
*
* <p>Internally, a TransactionInterceptor instance is used, but the user of this
* class does not have to care. Optionally, a MethodPointcut can be specified
* to cause conditional invocation of the underlying TransactionInterceptor.
*
* <p>The "preInterceptors" and "postInterceptors" properties can be set to add
* additional interceptors to the mix, like PerformanceMonitorInterceptor or
* HibernateInterceptor/JdoInterceptor.
*
* @author Juergen Hoeller
* @author Dmitriy Kopylenko
* @author Rod Johnson
* @since 21.08.2003
* @see #setTransactionManager
* @see #setTarget
* @see #setTransactionAttributes
* @see TransactionInterceptor
* @see org.springframework.aop.framework.ProxyFactoryBean
*/
public class ResourceProxyFactoryBean extends ProxyConfig
    implements FactoryBean, BeanFactoryAware, InitializingBean {

  private final ResourceInterceptor resourceInterceptor = new ResourceInterceptor();

  private Object target;

  private Class[] proxyInterfaces;

  private Pointcut pointcut;

  private Object[] preInterceptors;

  private Object[] postInterceptors;

  /** Default is global AdvisorAdapterRegistry */
  private AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();

  private Object proxy;


  /**
   * Set the resource manager. This will perform actual
   * resource management: This class is just a way of invoking it.
   * @see ResourceInterceptor#setresourceManager
   */
  public void setResourceManager(ResourceManager resourceManager) {
    this.resourceInterceptor.setResourceManager(resourceManager);
  }

  /**
   * Set the target object, i.e. the bean to be wrapped with a resource proxy.
   * <p>The target may be any object, in which case a SingletonTargetSource will
   * be created. If it is a TargetSource, no wrapper TargetSource is created:
   * This enables the use of a pooling or prototype TargetSource etc.
   * @see org.springframework.aop.TargetSource
   * @see org.springframework.aop.target.SingletonTargetSource
   * @see org.springframework.aop.target.LazyInitTargetSource
   * @see org.springframework.aop.target.PrototypeTargetSource
   * @see org.springframework.aop.target.CommonsPoolTargetSource
   */
  public void setTarget(Object target) {
    this.target = target;
  }

  /**
   * Specify the set of interfaces being proxied.
   * <p>If left null (the default), the AOP infrastructure works
   * out which interfaces need proxying by analyzing the target,
   * proxying all the interfaces that the target object implements.
   */
  public void setProxyInterfaces(String[] interfaceNames) throws ClassNotFoundException {
    this.proxyInterfaces = AopUtils.toInterfaceArray(interfaceNames);
  }

  /**
   * Set a pointcut, i.e a bean that can cause conditional invocation
   * of the TransactionInterceptor depending on method and attributes passed.
   * Note: Additional interceptors are always invoked.
   * @see #setPreInterceptors
   * @see #setPostInterceptors
   */
  public void setPointcut(Pointcut pointcut) {
    this.pointcut = pointcut;
  }

  /**
   * Set additional interceptors (or advisors) to be applied before the
   * implicit transaction interceptor, e.g. PerformanceMonitorInterceptor.
   * @see org.springframework.aop.interceptor.PerformanceMonitorInterceptor
   */
  public void setPreInterceptors(Object[] preInterceptors) {
    this.preInterceptors = preInterceptors;
  }

  /**
   * Set additional interceptors (or advisors) to be applied after the
   * implicit transaction interceptor, e.g. HibernateInterceptors for
   * eagerly binding Sessions to the current thread when using JTA.
   * <p>Note that this is just necessary if you rely on those interceptors in general:
   * HibernateTemplate and JdoTemplate work nicely with JtaTransactionManager through
   * implicit on-demand thread binding.
   * @see org.springframework.orm.hibernate.HibernateInterceptor
   * @see org.springframework.orm.jdo.JdoInterceptor
   */
  public void setPostInterceptors(Object[] postInterceptors) {
    this.postInterceptors = postInterceptors;
  }

  /**
   * Specify the AdvisorAdapterRegistry to use.
   * Default is the global AdvisorAdapterRegistry.
   * @see org.springframework.aop.framework.adapter.GlobalAdvisorAdapterRegistry
   */
  public void setAdvisorAdapterRegistry(AdvisorAdapterRegistry advisorAdapterRegistry) {
    this.advisorAdapterRegistry = advisorAdapterRegistry;
  }

  /**
   * This callback is optional: If running in a BeanFactory and no transaction
   * manager has been set explicitly, a single matching bean of type
   * PlatformTransactionManager will be fetched from the BeanFactory.
   * @see org.springframework.beans.factory.BeanFactoryUtils#beanOfTypeIncludingAncestors
   * @see org.springframework.transaction.PlatformTransactionManager
   */
  public void setBeanFactory(BeanFactory beanFactory) {
    if (this.resourceInterceptor.getResourceManager() == null &&
        beanFactory instanceof ListableBeanFactory) {
      ListableBeanFactory lbf = (ListableBeanFactory) beanFactory;
      ResourceManager rm = (ResourceManager)
          BeanFactoryUtils.beanOfTypeIncludingAncestors(lbf, ResourceManager.class);
      this.resourceInterceptor.setResourceManager(rm);
    }
  }


  public void afterPropertiesSet() {
    this.resourceInterceptor.afterPropertiesSet();

    if (this.target == null) {
      throw new IllegalArgumentException("'target' is required");
    }
   
    ProxyFactory proxyFactory = new ProxyFactory();

    if (this.preInterceptors != null) {
      for (int i = 0; i < this.preInterceptors.length; i++) {
        proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(this.preInterceptors[i]));
      }
    }

    if (this.pointcut != null) {
      Advisor advice = new DefaultPointcutAdvisor(this.pointcut, this.resourceInterceptor);
      proxyFactory.addAdvisor(advice);
    }
    else {
      // rely on default pointcut
      proxyFactory.addAdvisor(new ResourceAdvisor(this.resourceInterceptor));
      // Could just do the following, but it's usually less efficient because of AOP advice chain caching.
      // proxyFactory.addInterceptor(transactionInterceptor);
    }

    if (this.postInterceptors != null) {
      for (int i = 0; i < this.postInterceptors.length; i++) {
        proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(this.postInterceptors[i]));
      }
    }

    proxyFactory.copyFrom(this);

    TargetSource targetSource = createTargetSource(this.target);
    proxyFactory.setTargetSource(targetSource);

    if (this.proxyInterfaces != null) {
      proxyFactory.setInterfaces(this.proxyInterfaces);
    }
    else if (!isProxyTargetClass()) {
      // Rely on AOP infrastructure to tell us what interfaces to proxy.
      proxyFactory.setInterfaces(AopUtils.getAllInterfacesForClass(targetSource.getTargetClass()));
    }
   
    this.proxy = proxyFactory.getProxy();
  }

  /**
   * Set the target or TargetSource.
   * @param target target. If this is an implementation of TargetSource it is
   * used as our TargetSource; otherwise it is wrapped in a SingletonTargetSource.
   * @return a TargetSource for this object
   */
  protected TargetSource createTargetSource(Object target) {
    if (target instanceof TargetSource) {
      return (TargetSource) target;
    }
    else {
      return new SingletonTargetSource(target);
    }
  }

  public Object getObject() {
    return this.proxy;
  }

  public Class getObjectType() {
    if (this.proxy != null) {
      return this.proxy.getClass();
    }
    else if (this.proxyInterfaces != null && this.proxyInterfaces.length == 1) {
      return this.proxyInterfaces[0];
    }
    else if (this.target instanceof TargetSource) {
      return ((TargetSource) this.target).getTargetClass();
    }
    else if (this.target != null) {
      return this.target.getClass();
    }
    else {
      return null;
    }
  }

  public boolean isSingleton() {
    return true;
  }

}
TOP

Related Classes of org.springmodules.resource.interceptor.ResourceProxyFactoryBean

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.