How can I run a method Asynchronously with spring?

10,238

Solution 1

@Async only works when you annotate Spring-managed beans, not arbitrary classes. You need to define Process as a Spring bean, and then inject it into your controller class, e.g.

<bean id="test" class="com.spring.test.Test">
   <property name="process">
      <bean class="com.spring.test.Process"/>
   </property>
</bean>

public class Test {
   private Process process;

   public void setProcess(Process process) {
      this.process = process;
   }

   ...

   public String triggerNew() {  
      process.blah();
   }
}

Solution 2

Alternatively you can execute your task manually with TaskExecutor. Just define executor in the context:

<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"/>

Than you can execute yor task:

taskExecutor.execute(new Process ());

But in this case your Process class must implement Runnable interface

Share:
10,238
Grammin
Author by

Grammin

Updated on June 09, 2022

Comments

  • Grammin
    Grammin almost 2 years

    The following code is suppose to work Asynchronously but instead it waits for the Async part to finish and then goes. How can I make the blah() method run Asynchronously?

    spring.xml

    <?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:task="http://www.springframework.org/schema/task"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
            http://www.springframework.org/schema/task
            http://www.springframework.org/schema/task/spring-task-3.0.xsd
            http://www.springframework.org/schema/context 
            http://www.springframework.org/schema/context/spring-context-3.0.xsd
        ">
    
        <!-- Activates @Scheduled and @Async annotations for scheduling -->  
        <task:annotation-driven />
    
        <bean id="test"
            class="com.spring.test.Test">
    </beans>
    

    Test.java

    @Path("/test")
    public class Test
    {
      @GET
      @Path("/test")
      @Produces("text/plain")
      public String tester()
      {
        return "Running...";
      }
    
      @GET
      @Path("/triggerNew")
      @Produces("text/plain")
      public String triggerNew()
      {
        System.out.println("BEFORE " + new Date() + " BEFORE");
    
        new Process().blah();
    
        System.out.println("AFTER " + new Date() + " AFTER");
        return "TRIGGERED";
      }
    }
    

    Process.java

      @Component
        public class Process
        {
          @Async
          public void blah()
          {
            try
            {
              Thread.currentThread().sleep(5000);
            }
            catch (InterruptedException e)
            {
              e.printStackTrace(); 
            }
            System.out.println("NEW THREAD " + new Date() + " NEW THREAD");
          }
        }
    
  • Grammin
    Grammin about 12 years
    I've updated the code to include @Component, but I don't exactly know how to inject Process.java into my controller?
  • Grammin
    Grammin about 12 years
    I'm getting a Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify proxy interfaces. in my spring.xml, any ideas?
  • skaffman
    skaffman about 12 years
    @Grammin: Either add CGLIB to the classpath, or create an interface with the triggerNew method in it, and make Process implement that interface.