Last active
December 16, 2015 03:59
-
-
Save garyrussell/5374267 to your computer and use it in GitHub Desktop.
BeanPostProcessor To Apply a Handler Advice
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<beans xmlns="http://www.springframework.org/schema/beans" | |
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xmlns:int="http://www.springframework.org/schema/integration" | |
xmlns:aop="http://www.springframework.org/schema/aop" | |
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd | |
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd | |
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> | |
<int:channel id="input"> | |
<int:queue/> | |
</int:channel> | |
<int:channel id="output"> | |
<int:queue/> | |
</int:channel> | |
<int:service-activator id="myService" input-channel="input" output-channel="output"> | |
<bean class="org.springframework.integration.aop.AdvisePolledFlow$Service" /> | |
<int:poller fixed-rate="500" /> | |
</int:service-activator> | |
<bean class="org.springframework.integration.aop.AdvisePolledFlow$ApplyAdviceToHandler"> | |
<constructor-arg value="myService.handler" /> | |
</bean> | |
</beans> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2002-2013 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.integration.aop; | |
import static org.junit.Assert.assertEquals; | |
import static org.junit.Assert.assertNotNull; | |
import org.aopalliance.intercept.MethodInterceptor; | |
import org.aopalliance.intercept.MethodInvocation; | |
import org.junit.Test; | |
import org.junit.runner.RunWith; | |
import org.springframework.aop.framework.Advised; | |
import org.springframework.aop.framework.ProxyFactory; | |
import org.springframework.aop.support.AopUtils; | |
import org.springframework.aop.support.NameMatchMethodPointcutAdvisor; | |
import org.springframework.beans.BeansException; | |
import org.springframework.beans.factory.BeanClassLoaderAware; | |
import org.springframework.beans.factory.FactoryBean; | |
import org.springframework.beans.factory.annotation.Autowired; | |
import org.springframework.beans.factory.config.BeanFactoryPostProcessor; | |
import org.springframework.beans.factory.config.BeanPostProcessor; | |
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; | |
import org.springframework.integration.Message; | |
import org.springframework.integration.MessageChannel; | |
import org.springframework.integration.core.MessageHandler; | |
import org.springframework.integration.core.PollableChannel; | |
import org.springframework.integration.message.GenericMessage; | |
import org.springframework.test.context.ContextConfiguration; | |
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; | |
import org.springframework.util.Assert; | |
/** | |
* @author Gary Russell | |
* | |
*/ | |
@ContextConfiguration | |
@RunWith(SpringJUnit4ClassRunner.class) | |
public class AdvisePolledFlow { | |
private static Object received; | |
@Autowired | |
private MessageChannel input; | |
@Autowired | |
private PollableChannel output; | |
@Test | |
public void test() { | |
input.send(new GenericMessage<String>("foo")); | |
assertNotNull(output.receive(1000)); | |
assertNotNull(received); | |
assertEquals("foo", ((Message<?>) received).getPayload()); | |
} | |
///////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
/** | |
* B(F)PP that applies an advice to the handler embedded in an endpoint. | |
* | |
* @author Gary Russell | |
* | |
*/ | |
public static class ApplyAdviceToHandler implements BeanFactoryPostProcessor, BeanPostProcessor, BeanClassLoaderAware { | |
private String beanName; | |
private ClassLoader beanClassLoader; | |
public ApplyAdviceToHandler(String beanName) { | |
Assert.notNull(beanName); | |
this.beanName = beanName; | |
} | |
/** | |
* Convert the 'endpoint.handler' alias to the actual bean name | |
*/ | |
@Override | |
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { | |
String[] aliases = beanFactory.getAliases(this.beanName); | |
if (aliases.length > 0) { | |
this.beanName = aliases[0]; | |
} | |
} | |
@Override | |
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { | |
return bean; | |
} | |
@Override | |
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { | |
if (!(bean instanceof FactoryBean) && beanName.equals(this.beanName)) { | |
if (AopUtils.isAopProxy(bean) && bean instanceof Advised) { | |
Class<?> targetClass = AopUtils.getTargetClass(bean); | |
MyAdvice advice = new MyAdvice(); | |
NameMatchMethodPointcutAdvisor handlerAdvice = new NameMatchMethodPointcutAdvisor(advice); | |
handlerAdvice.addMethodName("handleMessage"); | |
if (AopUtils.canApply(handlerAdvice.getPointcut(), targetClass)) { | |
((Advised) bean).addAdvice(advice); | |
} | |
} | |
else { | |
Assert.isInstanceOf(MessageHandler.class, bean, "Can only advise message handlers"); | |
ProxyFactory proxyFactory = new ProxyFactory(bean); | |
proxyFactory.addAdvice(new MyAdvice()); | |
return proxyFactory.getProxy(this.beanClassLoader); | |
} | |
} | |
return bean; | |
} | |
@Override | |
public void setBeanClassLoader(ClassLoader classLoader) { | |
this.beanClassLoader = classLoader; | |
} | |
} | |
/** | |
* Test advice | |
* @author Gary Russell | |
* | |
*/ | |
public static class MyAdvice implements MethodInterceptor { | |
@Override | |
public Object invoke(MethodInvocation invocation) throws Throwable { | |
received = invocation.getArguments()[0]; | |
return invocation.proceed(); | |
} | |
} | |
/** | |
* Test Service. | |
* @author Gary Russell | |
* | |
*/ | |
public static class Service { | |
public String handleMessage(String msg) { | |
return msg; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment