0

I'm working on REST service which is developed using Apache-CXF. I'm using Spring 3.1 annotations for wiring the bean. I have written an interceptor which intercepts my REST method for monitoring purposes. To do this, i have to autowire my Monitor class which is added as library in my project. @Autowired doesn't seems to be working in this case and results into NPE. Am i doing anything wrong here ?

@Aspect
@Component
public class ApplicationMonitoring {

Logger logger = LoggerFactory.getLogger(ApplicationMonitoring.class);

@Autowired
private Monitor monitor;

@Around("execution(* com.abc.xyz.rest.CustomerResource.getCustomerByAccountNumber(..))")
public Object invoke(ProceedingJoinPoint joinPoint) throws Throwable {
    String methodName = joinPoint.getSignature().getName();

    long start = System.currentTimeMillis();
    try {
        // proceed to original method call
        Object result = joinPoint.proceed();
        monitor.elapsedTime(methodName, System.currentTimeMillis() - start);
            return result;
    } catch (Exception e) {
        throw e;
    }
}

ApplicationContext:

.................
......
<context:spring-configured />

<context:component-scan base-package="com.abc">
    <context:exclude-filter expression="org.springframework.stereotype.Controller"
        type="annotation" />
</context:component-scan>

<context:annotation-config/>  

.............
Pankaj
  • 3,512
  • 16
  • 49
  • 83
  • Can you show your context where you have a component scan on this `@Aspect`? – Sotirios Delimanolis Oct 28 '13 at 18:12
  • @SotiriosDelimanolis i've updated the original post with applicationContext – Pankaj Oct 28 '13 at 18:22
  • This problem usually happens when a spring bean has annotations that should end up generating 2 proxies (e.g. Transactional and Aspects). Spring is able to generate one of the proxies, but then it "looses" the metadata to create the 2nd proxy. One one to avoid this is to use the aspectj compile time weaver, as some aspects will be added at compilation time. – Augusto Oct 28 '13 at 19:44

2 Answers2

0

I'm not a master of Spring but as far as I know a bit of it I'll try to put into words as best as I can.

I think you noticed, but @Aspect is not spring-based, so in order it to be scanned you need to add <aop:aspectj-autoproxy/>, furthermore I think the issue is that two instances of the same class are being created, one for each container(spring and AspectJ), to avoid that I'd use a factory method to retrieve the exact same instance to the spring container (I'm not sure at a 100% if I explained it properly), - remember that the one for the aspect is created first-, in such a way:

<bean id="id_of_your_bean" class="ApplicationMonitoring" factory-method="aspectOf">
     //other stuff
</bean>
Diego Jimeno
  • 312
  • 4
  • 15
0

Found the solution in this blog

The aspect is a singleton object and is created outside the Spring container. A solution with XML configuration is to use Spring's factory method to retrieve the aspect.

<bean id="monitoringAspect" class="com.myaapp.ApplicationMonitoring" 
   factory-method="aspectOf" />

With this configuration the aspect will be treated as any other Spring bean and the autowiring will work as normal.

Pankaj
  • 3,512
  • 16
  • 49
  • 83