Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to inject session scope bean in interceptor using java config with Spring

I'm developping a full Spring 3.1 and servlet 3.0 application. But my interceptor has a private properties scoped as proxy:

public class MyInterceptor extends HandlerInterceptorAdapter {

    @Ressource
    private UserSession userSession;
}

The user session is defined as:

@Component 
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS) 
public class UserSession implements Serializable {
   ....
}

When using this user session in the interceptor, java throws a NullPointerException for userSession.

I think the problem comes from my javaconfig oriented spring configuration:

@EnableWebMvc
@ComponentScan(basePackages = {"com.whatever"})
@Configuration
public class WebAppConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor());
    }

    ...
}

The problem is that interceptor is manually instantied, so without instrumentation for the session proxy mechanism. Thus, the question is: "how can I let Spring detect and instance the scope session proxy bean in the java config of my application ?

like image 407
Kartoch Avatar asked Jan 28 '14 11:01

Kartoch


2 Answers

What you posted works, but you aren't taking advantage of Spring's autowiring capabilities. What if you had many services or other beans to inject into your MyInterceptor bean.

Instead just make a @Bean method for your MyInterceptor

@EnableWebMvc
@ComponentScan(basePackages = {"com.whatever"})
@Configuration
public class WebAppConfig extends WebMvcConfigurerAdapter {

    @Bean
    @Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
    public UserSession userSession() {
        return new UserSession();
    }

    @Bean
    public MyInterceptor myInterceptor() {
        return new MyInterceptor(); // let Spring go nuts injecting stuff
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(myInterceptor()); // will always refer to the same object returned once by myInterceptor()
    }

    ...
}
like image 157
Sotirios Delimanolis Avatar answered Nov 02 '22 03:11

Sotirios Delimanolis


The solution is to use annotation in the java config class:

@EnableWebMvc
@ComponentScan(basePackages = {"com.whatever"})
@Configuration
public class WebAppConfig extends WebMvcConfigurerAdapter {

    @Bean
    @Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
    public UserSession userSession() {
        return new UserSession();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        MyInterceptor interceptor = new MyInterceptor();
        interceptor.setUserSession(userSession());
        registry.addInterceptor(interceptor);
    }

    ...
}

And you need to remove @Scope and @Bean annotation from UserSession class.

like image 2
Kartoch Avatar answered Nov 02 '22 03:11

Kartoch