Multiple spring task executors with annotation-driven spring tasks - java

I have a class MessageProcessor being called by another method in another class (i.e. Caller).
public class Caller {
#Scheduled(filxedDelay=10)
public void poll(){
//do stuff
messageProcessor.process(msg);
}
}
public class MessageProcessor{
#Async(value="abcExecutor")
public void process(String msg){
//do stuff here.
}
}
Spring file looks like:
<task:executor id="abcExecutor" pool-size="9" rejection-policy-"CALLER_RUNS"/>
I want to add another #Async executor:
#Async(value="defExecutor")
public void remove(String msg){
//do stuff here.
}
#Scheduled(filxedDelay=10)
public void kill(){
//do stuff
messageProcessor.remove(msg);
}
By adding another executor in spring file:
<task:executor id="defExecutor" pool-size="9" rejection-policy="CALLER_RUNS"/>
But how to add multiple executors in <task:annotation-driven executor="abcExecutor" scheduler="scheduler" mode="proxy" proxy-target-class="true"/>
How can I make these multiple executors run with annotation?
PS: Obviously, I don't want to have the same pool being used for both the
#Async methods

The #Async("defExecutor") is sufficient to designate the method to be handled by the 2nd executor. The xml declaration specifies only the default executor, which will be used whenever no value is specified in #Async.
See the explanation of Chris Beams in this issue:

So, is it a right XML ?
<task:executor id="abcExecutor" pool-size="9" rejection-policy-"CALLER_RUNS"/>
<task:executor id="defExecutor" pool-size="9" rejection-policy="CALLER_RUNS"/>
<task:annotation-driven executor="abcExecutor" scheduler="scheduler" mode="proxy" proxy-target-class="true"/>

Related

#Async with JavaMelody #MonitoredWithSpring not working

I have problem with asynchronus execution of my code.
Method startConversion() should be called asynchronusly. call goes trought AOP proxy.
Everything separated works fine. Problem occurs when I put together #Async and #MonitoredWithSpring annotations
javamelody is defined in webxml in first xml - OK
Spring async support is defiend in xml - OK
Code works well without #MonitoredWithSpring. But i need this bean to be monitored.
Sample code:
#MonitoredWithSpring //L1 - if this line removed #async will work
public interface IOfficeConversionService {
void startConversion ();
}
Implementing class
#Service
public class COfficeConversionSevice implements IOfficeConversionService {
#Override
#Transactional
#Async ("officeFileConversionExecutor")
public void startConversion () {
//ASYNC work
}
}
With L1 present, code will call method startConversion() synchronusly.
Without L1 everything works fine, and method startConversion() is called asynchronusly in new thread
In stacktrace don't even create async pointcut.
#Async annotation is never processed by its postProcessor. #Transactional works, and transaction is created. No error in initialization
Spring configuration
<context:annotation-config />
<aop:aspectj-autoproxy />
<task:executor id="mailexecutor" pool-size="25-100" queue-capacity="1000" rejection-policy="ABORT" />
<task:executor id="pnpexecutor" pool-size="5" />
<task:executor id="officeFileConversionExecutor" pool-size="5" />
<task:scheduler id="systemScheduler" pool-size="5" />
<task:annotation-driven executor="mailexecutor" scheduler="systemScheduler"/>
Can you help me? Some suggestion ?
I am out of ideas.

Spring XML equivalent of #EnableAsync

Is there a way to turn on Spring's Async configuration from XML? All the examples I saw are using programmatic context declaration and use #EnableAsync
Is there an XML equivalent for this. In some places I saw <context:annotation-config /> being used, but this doesn't mention anything about async .
I am using Spring 4.
Did you try using this
<task:annotation-driven />
Yes, you can use something like this
<beans>
<task:annotation-driven executor="myExecutor" exception-handler="exceptionHandler"/>
<task:executor id="myExecutor" pool-size="7-42" queue-capacity="11"/>
<bean id="asyncBean" class="com.foo.MyAsyncBean"/>
<bean id="exceptionHandler" class="com.foo.MyAsyncUncaughtExceptionHandler"/>
</beans>
According to the Spring documentation, this is equivalent to using #EnableAsync
In the annotation based approach you have to have #EnableAsync on the Configuration class. Something like as shown below:
#Configuration
#EnableAsync
#ComponentScan(basePackages ="com.spring.sample.demoAsync")
public class SpringAsyncConfig {
}
Then you create a component class to have a function that is called Asynchronously. Something like as shown below:
#Component
public class AsyncClass {
#Async
public Future<String> asyncMethod() {
System.out.println("Executing Thread Async:" +Thread.currentThread().getName());
return new AsyncResult<String>(Thread.currentThread().getName());
}
}
To have the xml equivalent of this approach, you can create a bean in the applicationContext.xml file as shown below:
<bean id="AsyncClass" class="com.spring.sample.demoAsync.AsyncClass"/>
To call the function asyncMethod() in your flow, you can refer AsyncClass bean from any other bean or service. Below is something that I tried to stitch the flow:
<bean id="callingBean" class="comspring.sample.demoAsync.CallingBeanClass">
<property name="AsyncClassBean" ref="AsyncClass"/>
</bean>
It's not necessary to follow this step but is an alternative approach.
In my applicationContext.xml file, I also imported the task schema by using:
xmlns:task="http://www.springframework.org/schema/task
xsi:schemaLocation="http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd"
and then mentioning the executor as a task in the same file:
<task:executor id="myexecutor" pool-size="5" />
Now my AsyncClass looks like this without #component annotation.
public class AsyncClass {
#Async("myexecutor")
public Future<String> asyncMethod() {
System.out.println("Executing Thread Async:" +Thread.currentThread().getName());
return new AsyncResult<String>(Thread.currentThread().getName());
}
}
and then finally invoking the asyncMethod() asynchronously from the CallingBeanClass.

Spring hibernate , how to call some method after transaction commit or transaction rollback

I need to call some method after transaction succes or rollback. I am using as
<bean name="openSessionInViewInterceptor" class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor">
<property name="sessionFactory">
<ref local="mysessionFactory"/>
</property>
</bean>
<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="mysessionFactory"/>
</property>
</bean>
<tx:annotation-driven transaction-manager="txManager" proxy-target-class="true"/>
The application use some external web services which needs to be "cleaned" when the internal transaction gets rollbacked.
Is there way how to accomplish this without using declarative transaction management.
From Hibernate, you could extends EmptyInterceptor and override
afterTransactionCompletion() method and register it in
SessionFactoryBean or HibernateTransactionManager.
From Spring you could extends TransactionSynchronizationAdapter and
override afterCompletion() and register when appropriate with
TransactionSynchronizationManager#registerSynchronization().
Edit
An Example of using Spring Aop to add a synchronization to all methods annotated with #Transactional
#Aspect
class TransactionAspect extends TransactionSynchronizationAdapter {
#Before("#annotation(org.springframework.transaction.annotation.Transactional)")
public void registerTransactionSyncrhonization() {
TransactionSynchronizationManager.registerSynchronization(this);
}
#Override
public void afterCompletion(int status) {
// code
}
}
Spring has various classes which might be of interest here:
http://docs.spring.io/spring/docs/3.2.x/javadoc-api/org/springframework/transaction/support/TransactionSynchronization.html
http://docs.spring.io/spring/docs/3.2.x/javadoc-api/org/springframework/transaction/support/TransactionSynchronizationAdapter.html
http://docs.spring.io/spring/docs/3.2.x/javadoc-api/org/springframework/transaction/support/TransactionSynchronizationManager.html
There's some example code here:
http://azagorneanu.blogspot.co.uk/2013/06/transaction-synchronization-callbacks.html
Update 2016
The event handling infrastructure introduced in Spring 4.2 makes this much simpler.
See:
https://spring.io/blog/2015/02/11/better-application-events-in-spring-framework-4-2#transaction-bound-events
Another popular improvement is the ability to bind the listener of an
event to a phase of the transaction. The typical example is to handle
the event when the transaction has completed successfully
#Component
public class MyComponent {
#TransactionalEventListener(condition = "#creationEvent.awesome")
public void handleOrderCreatedEvent(CreationEvent<Order> creationEvent) {
...
}
}
#TransactionalEventListener is a regular #EventListener and also
exposes a TransactionPhase, the default being AFTER_COMMIT. You can
also hook other phases of the transaction (BEFORE_COMMIT,
AFTER_ROLLBACK and AFTER_COMPLETION that is just an alias for
AFTER_COMMIT and AFTER_ROLLBACK).
Using Spring 4+: The easiest/cleanest way without using global aspects and configurations is based on my answer here: https://stackoverflow.com/a/43322052/986160
If you need a callback on a #Transactional method after it successfully commits just add that in the beginning of the method:
#Service
public class OneService {
#Autowired
OneDao dao;
#Transactional
public void a transactionalMethod() {
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter(){
public void afterCommit(){
//do stuff right after commit
System.out.println("commit!!!");
}
});
//do db stuff
dao.save();
}
}

Implementing Web Services timer for Tweet Service

My problem is that I have a function implemented on my website which searches for Particular Tweet when I press the button. I want it to make it automatic such that, that function is called again and again after every two minutes, regardless some one uses the website or not.. How to do this in java?? Spring Solution is better
You could use Spring scheduling (see documentation here)
From the doc:
XML config
<context:component-scan base-package="some.package" />
<task:annotation-driven executor="myExecutor" scheduler="myScheduler"/>
<task:executor id="myExecutor" pool-size="5"/>
<task:scheduler id="myScheduler" pool-size="10"/>
Java bean
#Component
public class SomeBean {
#Scheduled(fixedRate=5000)
public void doSomething() {
// something that should execute periodically
}
}

Spring Bean running in its own thread

Within my web application, I am trying to create a directory polling bean using Java SDK7 WatchService. What I would like to achieve is to run this bean in its own thread so that it does not block the application. Something like:
<bean id="directoryPoller" class="org...MyDirectoryPoller" scope="thread"/>
I am afraid you will have to create this thread manually with Spring:
<bean id="pollThread" class="java.lang.Thread" init-method="start" destroy-method="interrupt">
<constructor-arg ref="watchServiceRunnableWrapper"/>
</bean>
<bean id="watchServiceRunnableWrapper" class="WatchServiceRunnableWrapper">
<constructor-arg ref="watchService"/>
</bean>
<bean id="WatchService" class="java.nio.file.WatchService" destroy-method="close"/>
The WatchServiceRunnableWrapper is simple:
public class WatchServiceRunnableWrapper implements Runnable {
private WatchService WatchService;
public WatchServiceRunnableWrapper(WatchService watchService) {
this.watchService = watchService;
}
public void run() {
watchService.poll();
//
}
}
I haven't tested it, but it more-or-less should work and shutdown gracefully.
I'm not familiar with Java 7's WatchService, but you could use Springs' scheduling support for this. Here's yet another tutorial and googling for something like Spring Scheduled probably finds loads more.

Categories

Resources