0

I have service controller which functionality I would like to reuse in another controller. Here is my service controller

@Controller
@Service
@Scope("session")
public class Controller1{
...
}

Here is my second controller

 @Controller
 public class Controller2 {
     @Autowired
     private Controller1 adminController;
     ...
 }

But I'm getting exception which says:

Error creating bean with name 'adminController': Scope 'session' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton;

I think that this is because Controler1 is session-scoped bean and Controller2 is application. How can I reuse then Controller1 functionality inside Controller2? Thanks.

Dropout
  • 13,653
  • 10
  • 56
  • 109
Arsen Alexanyan
  • 3,061
  • 5
  • 25
  • 45
  • 2
    Why is your class both a @Service and a @Controller? This would at least have some alarm-bells ringing with me... Next to that you need to tell it to create a scoped-proxy next to specifying only the scope. – M. Deinum Oct 30 '13 at 11:24
  • Thanks for your comments, I don't know why this is defined in this way :) I would like just to reuse it. I will try the @ScopedProxy methodology – Arsen Alexanyan Oct 30 '13 at 11:37

3 Answers3

1

you can use aop:scoped-proxy in your xml config file for controller1

 <bean id="controller1" class="...Controller1" scope="session">
    <aop:scoped-proxy />
 </bean>

look at spring scoped proxy bean

Community
  • 1
  • 1
karci10
  • 375
  • 3
  • 15
  • Well here I'm using for controlles I haven't here bean definition. – Arsen Alexanyan Oct 30 '13 at 11:56
  • i cannot add comment to Debojit Saikia answer, the error is because you have two beans of class Controller1, and both have same requestmapping. do you really need controller with session scope? – karci10 Oct 30 '13 at 13:36
  • But their @RequestMapping annotations are different on methods. Yes one should be session scope another application scope. – Arsen Alexanyan Oct 30 '13 at 13:40
  • RequestMapping on methods are different, but you have two beans of same class, and these controllers have same RequesMappings, look at http://stackoverflow.com/questions/11869057/cannot-scope-spring-controller-as-request-when-a-component-is-scoped-as-session – karci10 Oct 30 '13 at 13:58
  • Where is here two beans of the same class? One is Controller1 class another Controller2 class – Arsen Alexanyan Oct 30 '13 at 14:00
  • if bean have session scope, spring creates two instances of this bean. – karci10 Oct 30 '13 at 14:02
  • I've never heard about that if bean is session scoped Spring creates two instances of them and this is confusing. Why then defining session scoped controller just works fine without this? – Arsen Alexanyan Oct 30 '13 at 14:07
  • sorry, two instances created just if the session scope bean is injected in singleton bean. – karci10 Oct 30 '13 at 14:16
1

Both of these annotations @Controller and @Service serve as a specialization of @Component, which allows the implementation classes to be autodetected through classpath scanning. And @Controller is typically used in combination with annotated handler methods to handle http requests. So you don't have to use @Controller and @Service on the same class. You can safely remove @Service.

Now if you want to inject an HTTP session scoped bean into another bean, you must inject an AOP proxy in place of the scoped bean.

That is, you need to inject a proxy object that exposes the same public interface as the scoped object but that can also retrieve the real, target object from the relevant scope (in this scenario, an HTTP session) and delegate method calls onto the real object. So, in order to make it work, change the @Scope annotation of Controller1 to this:

@Controller
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class Controller1{
...
}
Debojit Saikia
  • 10,532
  • 3
  • 35
  • 46
  • Thanks for your post. I have used this and get another exception : Cannot map handler 'adminController' to URL path [//timezone/{minutes}]: There is already handler 'scopedTarget.adminController' mapped. What can it be? – Arsen Alexanyan Oct 30 '13 at 12:12
  • can you share your application cotext xml file? – Debojit Saikia Oct 30 '13 at 12:19
  • Here is just tons of configuration xmls I don't know what to share( – Arsen Alexanyan Oct 30 '13 at 12:48
  • do you have any bean definition for `adminController` in your config file along with `context:component-scan` entry. if you have these two entries, then that could be the reason for the error. try removing the bean definition for `adminController`() if you have any. – Debojit Saikia Oct 30 '13 at 12:52
  • No here just configuration. I found 2 of it mapped to the same package I have removed the one but still it brings the same exception – Arsen Alexanyan Oct 30 '13 at 12:54
  • when this error is reported? while sending request to the URL or during startup? – Debojit Saikia Oct 30 '13 at 12:55
  • It brings during startup of Tomcat – Arsen Alexanyan Oct 30 '13 at 12:57
  • can you try by changing the URL path `[//timezone/{minutes}]` to something else? – Debojit Saikia Oct 30 '13 at 13:29
  • I've changed and it gives now Cannot map handler 'adminController' to URL path [/timezonesss/{minutessss}]: There is already handler 'scopedTarget.adminController' mapped. – Arsen Alexanyan Oct 30 '13 at 13:33
  • confusing! do you have urls mapped with methods of `adminController` or you are using it just as another spring `component`? if you are using it as as a simple `component`, annotate it with `@component` or `@service`. `@controller` annotations should be used for components if they really serve the purpose of controllers by serving web requests. – Debojit Saikia Oct 30 '13 at 13:38
  • They are annotated as You commented. I've removed also the Service annotation. Both are controllers and annotated with Controller annotations. I have RequestMapping annotations with urls on methods and they are different from each other. This is confusing for me too. I'm using Spring 3.0.5-RELEASE – Arsen Alexanyan Oct 30 '13 at 13:48
0

It depends of what you mean by functionnality but if you want to share a method in both controller, why not defining an abstract parent class defining this method and extends both controllers from this parent ?

Thomas
  • 1,410
  • 10
  • 24