Browse Source
git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@1291 50f2f4bb-b051-0410-bef5-90022cba6387pull/1/head
1 changed files with 144 additions and 0 deletions
@ -0,0 +1,144 @@
@@ -0,0 +1,144 @@
|
||||
/* |
||||
* Copyright 2002-2009 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.springframework.scheduling.annotation; |
||||
|
||||
import java.lang.annotation.Annotation; |
||||
|
||||
import org.springframework.aop.framework.Advised; |
||||
import org.springframework.aop.framework.AopInfrastructureBean; |
||||
import org.springframework.aop.framework.ProxyConfig; |
||||
import org.springframework.aop.framework.ProxyFactory; |
||||
import org.springframework.aop.support.AopUtils; |
||||
import org.springframework.beans.BeansException; |
||||
import org.springframework.beans.factory.BeanClassLoaderAware; |
||||
import org.springframework.beans.factory.BeanFactory; |
||||
import org.springframework.beans.factory.BeanFactoryAware; |
||||
import org.springframework.beans.factory.config.BeanPostProcessor; |
||||
import org.springframework.core.Ordered; |
||||
import org.springframework.core.task.TaskExecutor; |
||||
import org.springframework.util.Assert; |
||||
import org.springframework.util.ClassUtils; |
||||
|
||||
import java.util.concurrent.Executor; |
||||
|
||||
/** |
||||
* Bean post-processor that automatically applies asynchronous invocation |
||||
* behavior to any bean that carries the {@link Async} annotation at class or |
||||
* method-level by adding a corresponding {@link AsyncAnnotationAdvisor} to the |
||||
* exposed proxy (either an existing AOP proxy or a newly generated proxy that |
||||
* implements all of the target's interfaces). |
||||
* |
||||
* <p>The {@link TaskExecutor} responsible for the asynchronous execution may |
||||
* be provided as well as the annotation type that indicates a method should be |
||||
* invoked asynchronously. If no annotation type is specified, this post- |
||||
* processor will detect both Spring's {@link Async @Async} annotation as well |
||||
* as the EJB 3.1 <code>javax.ejb.Asynchronous</code> annotation. |
||||
* |
||||
* @author Mark Fisher |
||||
* @author Juergen Hoeller |
||||
* @since 3.0 |
||||
* @see Async |
||||
* @see AsyncAnnotationAdvisor |
||||
*/ |
||||
public class AsyncAnnotationBeanPostProcessor extends ProxyConfig |
||||
implements BeanPostProcessor, BeanClassLoaderAware, BeanFactoryAware, Ordered { |
||||
|
||||
private Class<? extends Annotation> asyncAnnotationType; |
||||
|
||||
private Executor executor; |
||||
|
||||
private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader(); |
||||
|
||||
private AsyncAnnotationAdvisor asyncAnnotationAdvisor; |
||||
|
||||
|
||||
/** |
||||
* Set the 'async' annotation type to be detected at either class or method |
||||
* level. By default, both the {@link Async} annotation and the EJB 3.1 |
||||
* <code>javax.ejb.Asynchronous</code> annotation will be detected. |
||||
* <p>This setter property exists so that developers can provide their own |
||||
* (non-Spring-specific) annotation type to indicate that a method (or all |
||||
* methods of a given class) should be invoked asynchronously. |
||||
* @param asyncAnnotationType the desired annotation type |
||||
*/ |
||||
public void setAsyncAnnotationType(Class<? extends Annotation> asyncAnnotationType) { |
||||
Assert.notNull(asyncAnnotationType, "'asyncAnnotationType' must not be null"); |
||||
this.asyncAnnotationType = asyncAnnotationType; |
||||
} |
||||
|
||||
/** |
||||
* Set the {@link Executor} to use when invoking methods asynchronously. |
||||
*/ |
||||
public void setExecutor(Executor executor) { |
||||
this.executor = executor; |
||||
} |
||||
|
||||
public void setBeanClassLoader(ClassLoader classLoader) { |
||||
this.beanClassLoader = classLoader; |
||||
} |
||||
|
||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException { |
||||
this.asyncAnnotationAdvisor = (this.executor != null) ? |
||||
new AsyncAnnotationAdvisor(this.executor) : new AsyncAnnotationAdvisor(); |
||||
if (this.asyncAnnotationType != null) { |
||||
this.asyncAnnotationAdvisor.setAsyncAnnotationType(asyncAnnotationType); |
||||
} |
||||
} |
||||
|
||||
public int getOrder() { |
||||
// This should run after all other post-processors, so that it can just add
|
||||
// an advisor to existing proxies rather than double-proxy.
|
||||
return LOWEST_PRECEDENCE; |
||||
} |
||||
|
||||
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { |
||||
return bean; |
||||
} |
||||
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { |
||||
if (bean instanceof AopInfrastructureBean) { |
||||
// Ignore AOP infrastructure such as scoped proxies.
|
||||
return bean; |
||||
} |
||||
|
||||
Class<?> targetClass = AopUtils.getTargetClass(bean); |
||||
if (targetClass == null) { |
||||
// Can't do much here.
|
||||
return bean; |
||||
} |
||||
|
||||
if (AopUtils.canApply(this.asyncAnnotationAdvisor, targetClass)) { |
||||
if (bean instanceof Advised) { |
||||
((Advised) bean).addAdvisor(this.asyncAnnotationAdvisor); |
||||
return bean; |
||||
} |
||||
else { |
||||
ProxyFactory proxyFactory = new ProxyFactory(bean); |
||||
// Copy our properties (proxyTargetClass etc) inherited from ProxyConfig.
|
||||
proxyFactory.copyFrom(this); |
||||
proxyFactory.addAdvisor(this.asyncAnnotationAdvisor); |
||||
return proxyFactory.getProxy(this.beanClassLoader); |
||||
} |
||||
} |
||||
else { |
||||
// No async proxy needed.
|
||||
return bean; |
||||
} |
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue