We help IT Professionals succeed at work.

Spring AOP for objects instantiated outside of the application context

apollonius_tyana
on
1,461 Views
Last Modified: 2013-11-11
Hi,

I have a simple app. I've got a TaskExecutorService class which instantiated several Runnable's and gives them to the TaskExecutor.

I've managed to wire things with Spring. however what I need is to weave a logger advise before and after the run() method of my Runnable class.

The problem is the task class which implements Runnable is NOT instantiated by Spring, instead it is instantiated by the TaskExecutorService outside the Spring container.

Can somebody tell me how can I weave an advise for objects instantiated OUTSIDE the Spring context? I could not how to make use of ProxyFactory.

Thanks in advance


package springexec;
 
public class HelloWorldCountDownTask implements Runnable {
 
    private String name;
    private int count = 4;
 
    public HelloWorldCountDownTask(String name) {
        this.name = name;
    }        
    
    public void run() {
        while( count > 0 ){
            count--;
            if (count == 0){
                System.out.println(name + " says 'Hello World!'");
            } else {
                System.out.println(name + " : " + count);
                Thread.yield();
            }
        }
    }
}
 
package springexec;
 
import org.springframework.core.task.TaskExecutor;
 
public class TaskExecutorExample {
 
    private TaskExecutor taskExecutor;
 
    public TaskExecutorExample(TaskExecutor taskExecutor) {
        this.taskExecutor = taskExecutor;
    }
    
    public void executeTasks(){
        this.taskExecutor.execute(new HelloWorldCountDownTask("Anna"));
        this.taskExecutor.execute(new HelloWorldCountDownTask("Beth"));
        this.taskExecutor.execute(new HelloWorldCountDownTask("Charlie"));
        this.taskExecutor.execute(new HelloWorldCountDownTask("Daniel"));
 
    }
}
 
package springexec;
 
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.task.TaskExecutor;
 
public class SyncTaskExecutorExample {
 
    public static void main(String args[]){
        ApplicationContext ctx = new ClassPathXmlApplicationContext("springexec/exec.xml");
        
        TaskExecutor taskExecutor = (TaskExecutor) ctx.getBean("syncTaskExecutor",TaskExecutor.class);
        TaskExecutorExample example = new TaskExecutorExample(taskExecutor);
        example.executeTasks();
    }
}
 
<?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:aop="http://www.springframework.org/schema/aop"
       xmlns:jee="http://www.springframework.org/schema/jee"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
       http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
       http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd">
    
    <bean id="threadPoolExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
          <property name="corePoolSize" value="5"/>
          <property name="maxPoolSize" value="10"/>
          <property name="queueCapacity" value="25"/>
    </bean>
          
    <bean id="syncTaskExecutor" class="org.springframework.core.task.SyncTaskExecutor"/>
    
    <bean id="timerTaskExecutor" class="org.springframework.scheduling.timer.TimerTaskExecutor">
        <property name="delay" value="3000"/>
        <property name="timer" ref="timer"/>
    </bean>
    
    <bean id="timer" class="java.util.Timer"/>
    
    <bean id="logger" class="springexec.Logger"/>
 
</beans>

Open in new window

Comment
Watch Question

If you mean Spring AOP, you cannot use it to work outside the Spring framework/container.  In this case, you could consider using AspectJ.

Author

Commented:
By outside I mean objects that have to be instantiated within new() rather than getBean(). If you look at the example you'll see there's a Runnable class which is instantiated by the Executor. What I need is a logging aspect around the Runnable object. How would I do it in Spring configuration?

Author

Commented:
Do not close the question. No people in EE site able to anwer the question does not mean the question is abondened.
Kevin CrossChief Technology Officer
CERTIFIED EXPERT
Most Valuable Expert 2011

Commented:
Do you have to use spring logger?

I would do something like this if I am understanding your requirements correctly:

public void run() {
        // log start of run here
        // http://java.sun.com/j2se/1.4.2/docs/api/java/util/logging/Logger.html

        while( count > 0 ){
            count--;
            if (count == 0){
                System.out.println(name + " says 'Hello World!'");
            } else {
                System.out.println(name + " : " + count);
                Thread.yield();
            }
        }

        // log end of run here    
    }
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION
Unlock the solution to this question.
Join our community and discover your potential

Experts Exchange is the only place where you can interact directly with leading experts in the technology field. Become a member today and access the collective knowledge of thousands of technology experts.

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.