Refactored PublisherAnnotationBeanPostProcessor to implement BeanClassLoaderAware and to use AopUtils.canApply() since the advisor is a pointcut-advisor.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* 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.
|
||||
@@ -13,96 +13,101 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.aop;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.springframework.aop.framework.Advised;
|
||||
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.InitializingBean;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.integration.core.MessageChannel;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Will post process beans that contain @{@link Publisher} annotation.
|
||||
* Post-processes beans that contain the method-level @{@link Publisher} annotation.
|
||||
*
|
||||
* @author Oleg Zhurakousky
|
||||
* @author Mark Fisher
|
||||
* @since 2.0
|
||||
*
|
||||
*/
|
||||
public class PublisherAnnotationBeanPostProcessor implements BeanPostProcessor, BeanFactoryAware, InitializingBean {
|
||||
public class PublisherAnnotationBeanPostProcessor extends ProxyConfig
|
||||
implements BeanPostProcessor, BeanClassLoaderAware, BeanFactoryAware, InitializingBean, Ordered {
|
||||
|
||||
private volatile MessageChannel defaultChannel;
|
||||
|
||||
private volatile PublisherAnnotationAdvisor advisor;
|
||||
|
||||
private volatile int order = Ordered.LOWEST_PRECEDENCE;
|
||||
|
||||
private volatile BeanFactory beanFactory;
|
||||
|
||||
private volatile ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
|
||||
|
||||
|
||||
private BeanFactory beanFactory;
|
||||
private MessageChannel defaultChannel;
|
||||
private PublisherAnnotationAdvisor advisor;
|
||||
/**
|
||||
*
|
||||
* Set the default channel where Messages should be sent if the annotation
|
||||
* itself does not provide a channel.
|
||||
*/
|
||||
public PublisherAnnotationBeanPostProcessor(){}
|
||||
/**
|
||||
*
|
||||
* @param defaultChannel
|
||||
*/
|
||||
public PublisherAnnotationBeanPostProcessor(MessageChannel defaultChannel){
|
||||
public void setDefaultChannel(MessageChannel defaultChannel){
|
||||
this.defaultChannel = defaultChannel;
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName)
|
||||
throws BeansException {
|
||||
if (this.containsPublisherAnnotations(bean)){
|
||||
ProxyFactory pf = new ProxyFactory(bean);
|
||||
pf.addAdvisor(advisor);
|
||||
bean = pf.getProxy();
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName)
|
||||
throws BeansException {
|
||||
return bean;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public BeanFactory getBeanFactory() {
|
||||
return beanFactory;
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
public void setBeanFactory(BeanFactory beanFactory) {
|
||||
this.beanFactory = beanFactory;
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
public void setBeanClassLoader(ClassLoader classLoader) {
|
||||
this.beanClassLoader = classLoader;
|
||||
}
|
||||
|
||||
public void setOrder(int order) {
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
public int getOrder() {
|
||||
return this.order;
|
||||
}
|
||||
|
||||
public void afterPropertiesSet(){
|
||||
advisor = new PublisherAnnotationAdvisor();
|
||||
advisor.setBeanFactory(beanFactory);
|
||||
advisor.setDefaultChannel(defaultChannel);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param bean
|
||||
* @return
|
||||
*/
|
||||
private boolean containsPublisherAnnotations(Object bean){
|
||||
Method[] methods = bean.getClass().getMethods();
|
||||
for (Method method : methods) {
|
||||
Annotation publisher = AnnotationUtils.findAnnotation(method, Publisher.class);
|
||||
if (publisher != null){
|
||||
return true;
|
||||
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||
return bean;
|
||||
}
|
||||
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||
Class<?> targetClass = AopUtils.getTargetClass(bean);
|
||||
if (targetClass == null) {
|
||||
return bean;
|
||||
}
|
||||
|
||||
if (AopUtils.canApply(this.advisor, targetClass)) {
|
||||
if (bean instanceof Advised) {
|
||||
((Advised) bean).addAdvisor(this.advisor);
|
||||
return bean;
|
||||
}
|
||||
else {
|
||||
ProxyFactory proxyFactory = new ProxyFactory(bean);
|
||||
// Copy our properties (proxyTargetClass etc) inherited from ProxyConfig.
|
||||
proxyFactory.copyFrom(this);
|
||||
proxyFactory.addAdvisor(this.advisor);
|
||||
return proxyFactory.getProxy(this.beanClassLoader);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
else {
|
||||
// cannot apply advisor
|
||||
return bean;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd"
|
||||
xmlns:si="http://www.springframework.org/schema/integration">
|
||||
|
||||
|
||||
<bean id="testBean"
|
||||
class="org.springframework.integration.aop.MessagePublishingAnnotationUsageTest$TestBean" />
|
||||
class="org.springframework.integration.aop.MessagePublishingAnnotationUsageTests$TestBean" />
|
||||
|
||||
<si:channel id="testChannel">
|
||||
<si:queue />
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* 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.
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.aop;
|
||||
|
||||
import junit.framework.Assert;
|
||||
@@ -31,26 +32,31 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class MessagePublishingAnnotationUsageTest {
|
||||
public class MessagePublishingAnnotationUsageTests {
|
||||
|
||||
@Autowired
|
||||
private TestBean testBean;
|
||||
|
||||
@Autowired
|
||||
private QueueChannel channel;
|
||||
|
||||
@Test
|
||||
public void demoMessagePublishingInterceptor(){
|
||||
public void demoMessagePublishingInterceptor() {
|
||||
String name = testBean.setName("John", "Doe");
|
||||
Assert.assertNotNull(name);
|
||||
Message<?> message = channel.receive();
|
||||
Message<?> message = channel.receive(1000);
|
||||
Assert.assertNotNull(message);
|
||||
Assert.assertEquals("John Doe", message.getPayload());
|
||||
Assert.assertEquals("123", message.getHeaders().get("bar"));
|
||||
}
|
||||
|
||||
|
||||
public static class TestBean{
|
||||
public static class TestBean {
|
||||
|
||||
@Publisher(value="#return", channel="testChannel", headers="bar='123'")
|
||||
public String setName(String fname, String lname){
|
||||
return fname + " " + lname;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
xmlns:si="http://www.springframework.org/schema/integration">
|
||||
|
||||
<bean id="testBean"
|
||||
class="org.springframework.integration.aop.MessagePublishingInterceptorUsageTest$TestBean" />
|
||||
class="org.springframework.integration.aop.MessagePublishingInterceptorUsageTests$TestBean" />
|
||||
|
||||
<si:channel id="testChannel">
|
||||
<si:queue />
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* 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.
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.aop;
|
||||
|
||||
import junit.framework.Assert;
|
||||
@@ -28,29 +29,33 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
/**
|
||||
* @author Oleg Zhurakousky
|
||||
* @since 2.0
|
||||
*
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class MessagePublishingInterceptorUsageTest {
|
||||
public class MessagePublishingInterceptorUsageTests {
|
||||
|
||||
@Autowired
|
||||
private TestBean testBean;
|
||||
|
||||
@Autowired
|
||||
private QueueChannel channel;
|
||||
|
||||
@Test
|
||||
public void demoMessagePublishingInterceptor(){
|
||||
String name = testBean.setName("John", "Doe");
|
||||
Assert.assertNotNull(name);
|
||||
Message<?> message = channel.receive();
|
||||
Message<?> message = channel.receive(1000);
|
||||
Assert.assertNotNull(message);
|
||||
Assert.assertEquals("John Doe", message.getPayload());
|
||||
Assert.assertEquals("bar", message.getHeaders().get("foo"));
|
||||
}
|
||||
|
||||
|
||||
public static class TestBean{
|
||||
|
||||
public static class TestBean {
|
||||
|
||||
public String setName(String fname, String lname){
|
||||
return fname + " " + lname;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user