8

I have a spring bean that extends HibernateDaoSupport. I want this bean injected into my Controllers, but I do NOT want it to implement any interface. I just want to refer to the concrete class from within the rest of my code (not use the AopProxy perhaps?) Does anyone have a way of doing this?

<bean id="mySampleService" class="com.sample.MySampleService">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>

@Autowired
private MySampleService mySampleService;

... getters and setters ....

I know it's a good idea to use the interface and that's the whole point of IoC, but PLEASE DON'T suggest I use the interface.

ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
fandang
  • 605
  • 1
  • 6
  • 14
  • What is currently forcing you to use an interface? – Adam Paynter Jul 17 '12 at 18:03
  • Good point axtavt (and Adam) - It gives a java.lang.ClassNotFoundException: MySampleService, but the class is absolutely there. It only started giving that when I removed the corresponding "MySampleInterface" from my project.... – fandang Jul 17 '12 at 18:08
  • 1
    Do you have your MySampleService implementing any other interface at all - any marker interface etc? Also, do you have any annotations like `@Transactional` on MySampleService? – Biju Kunjummen Jul 17 '12 at 18:17
  • Yes MySampleService has @Transactional(readOnly = false) at the class level, and implements only what its superclass (HibernateDaoSupport) implements....thanks! – fandang Jul 17 '12 at 18:19
  • this error is in the trace too - org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.sample.MySampleService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} – fandang Jul 17 '12 at 18:30

3 Answers3

12

If class to be proxied (by transactional proxy in your case) implements any interface (InitializingBean implemented by HibernateDaoSupport in your case), Spring by default uses proxying strategy based on JDK dynamic proxies.

So, it creates a proxy of type InitializingBean, that, obviously, cannot be injected into a field of type MySampleService.

If you don't want to use interface you can override the strategy used by transactional aspect by declaring <tx:annotation-driven> with proxy-target-class = "true".

See also:

axtavt
  • 239,438
  • 41
  • 511
  • 482
  • 2
    also, don't make the concrete class final, or you won't be able to proxy it this way. – Matt Jul 17 '12 at 20:55
  • 1
    axtavt Thank you, that worked :) the bean is now there and not null, exactly what I wanted, would never have figured out that tx:annotation attribute so thanks again! – fandang Jul 18 '12 at 12:57
  • and make sure it has an empty constructor as mentioned by Alf [here](http://stackoverflow.com/questions/8922135/why-always-have-single-implementaion-interfaces-in-service-and-dao-layers) – Glenn Lawrence Apr 19 '15 at 21:06
0

Check the following. Ensure you have CGLIB on your classpath.

http://static.springsource.org/spring/docs/3.0.0.M3/spring-framework-reference/html/ch08s06.html

Alan Hay
  • 22,665
  • 4
  • 56
  • 110
  • the classpath is fine, because like I said, it all worked before removing the interface....could not have been working before without cglib.... – fandang Jul 17 '12 at 18:55
0

you can write everything including the mapped controller in the xml as beans, then you don't need to write interfaces. otherwise, with using annotation you need to build interfaces to proxy them.

Prog Mania
  • 615
  • 9
  • 14