15

I'd like to expose a component's interface as an interface and the implementing class would be package protected (and maybe in some other package):

package baz.iface

interface Foo {
    void bar();
}  


package baz.whatever

@Component
class SpringyFoo implements baz.iface.Foo {
    public void bar() { frobnicate(); }
}

Assuming baz.whatever is in the component-scan, will Spring be able to autowire a baz.iface.Foo somewhere else?

class FooClient {
    @Autowired
    private baz.iface.Foo;
}
chrylis -cautiouslyoptimistic-
  • 75,269
  • 21
  • 115
  • 152

3 Answers3

14

No, components don't have to be public. The only requirement is that they have a no-arg constructor.

Ahmed Ashour
  • 5,179
  • 10
  • 35
  • 56
Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275
  • 5
    you can also use arguments in constructors for constructor injection: http://static.springsource.org/spring/docs/3.0.x/reference/beans.html#beans-constructor-injection – Christopher Taylor Aug 20 '13 at 09:51
1

Yes, Spring will search for objects of type Foo.
SpringyFoo implements Foo and can be used in place of object of type Foo.

Ajinkya
  • 22,324
  • 33
  • 110
  • 161
0

You can't make your bar() "package-protected" because it has to be public:

Every method declaration in the body of an interface is implicitly public.

Spring's reflection system will find all of your classes, even ones with default access, but it's a compile-time error for your bar() method not to be public.

chrylis -cautiouslyoptimistic-
  • 75,269
  • 21
  • 115
  • 152
  • That is probably a typo in `SpringyFoo`. Also you don't have to declare interface methods to be `public` as [they are always public](http://stackoverflow.com/questions/5376970/protected-in-interfaces). – Adam Gent Aug 19 '13 at 12:45
  • This question is poorly written and asks two diametrically opposed questions. I'm restating. – chrylis -cautiouslyoptimistic- Aug 19 '13 at 12:47
  • 2
    Well the real issue is that he should just try it. With Java Reflection / Byte code manipulation and a corresponding loose security manager you can do just about anything including even setting final fields. – Adam Gent Aug 19 '13 at 12:48
  • yes, the missing `public` before `bar()` was a typo in `SpringyFoo`. I've updated the question. I did try it and it seemed to work. However, all the docs/examples I could find always used public classes, so I wanted to know if this was supported behaviour. – Christopher Taylor Aug 20 '13 at 09:44
  • I'm editing your question; let me know if it's not what you meant. – chrylis -cautiouslyoptimistic- Aug 20 '13 at 09:45