Aop lost when bean moved to parent injector

86 views
Skip to first unread message

Vyacheslav Rusakov

unread,
Jun 23, 2015, 1:26:42 AM6/23/15
to google...@googlegroups.com
Hello,

Test ng guice support creates implicit parent injector and creates child injector for your module. So parent injector is out of my control.

If bean has no specific dependencies to other beans in child injector it would be created in parent injector, even if this bean is declared in child injector's module.
I understand this behaviour is by design to solve probles with JIT.
But when such bean moves to parent injector, aop interceptors, defined in child injector, can't affect such bean anymore.

I know that common recomendation for such case is to disable JIT, but I don't want to do it (too radical solution).
Is there any workaround to tie bean to child injector without introduction of some dummy (anchor) dependency on it?

Tavian Barnes

unread,
Jun 23, 2015, 10:05:25 AM6/23/15
to google...@googlegroups.com
bind(SomeBean.class);

in the child module will force it to stay there.

Vyacheslav Rusakov

unread,
Jun 24, 2015, 2:05:37 AM6/24/15
to google...@googlegroups.com

Thank you for answer. You forward me to right direction. I did simple test and it appear that there is a thin moment:

When you have:
bind(IBean.class).to(BeanImpl.class)
And you inject bean as IBean, then it will be created in parent(!) injector.

But it will create bean in child injector if implementation is also binded.
bind(IBean.class).to(BeanImpl.class)
bind(BeanImpl.class)

It would be interesting to know "the why" for such behaviour.


вторник, 23 июня 2015 г., 20:05:25 UTC+6 пользователь Tavian Barnes написал:

Tavian Barnes

unread,
Jun 24, 2015, 10:29:34 AM6/24/15
to google...@googlegroups.com
https://github.com/google/guice/issues/888 describes the general issue and a potential workaround in Guice 4: if you requireExplicitBindings(), it will prevent linked bindings from "bubbling up."

Sam Berlin

unread,
Jun 24, 2015, 10:35:24 AM6/24/15
to google...@googlegroups.com

https://github.com/google/guice/issues/935 is open about the different behaviors between requesting the interface vs requesting the impl... There shouldn't be a difference in behavior, right?

sam


--
You received this message because you are subscribed to the Google Groups "google-guice" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-guice...@googlegroups.com.
To post to this group, send email to google...@googlegroups.com.
Visit this group at http://groups.google.com/group/google-guice.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-guice/fae348f1-ff15-473b-91d4-aa24dfb7903c%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Tavian Barnes

unread,
Jun 24, 2015, 7:40:30 PM6/24/15
to google...@googlegroups.com
That looks like "notabug" to me.  In those examples it's not just the requested type that differs, but how it's bound as well:

bind(ITestAop.class).to(TestAopImpl.class).in(Singleton.class);
ITestAop test = injector.getInstance(ITestAop.class);

vs.

bind(TestAopImpl.class).in(Singleton.class);
ITestAop test = injector.getInstance(TestAopImpl.class);

Vyacheslav Rusakov

unread,
Jun 25, 2015, 3:11:36 AM6/25/15
to google...@googlegroups.com
I think this behaviour is at least confusing.

When you define bean like this
bind(ITestAop.class).to(TestAopImpl.class)

You expect that its correctly binded, but guice create implementation instance following JIT beans rules (its not obvious).

I tend to think that it's not correct behaviour, especially if you inject such type as an interface (ITestAop).

I can understand if guice will create JIT binding if I use the implementation for injection because implementation type is indeed not binded. 


But this type of problems at least has a workaround (to bind also the implementation).
Guice perfectly works with dependency graphs. Even counting bindings bubbling its totally ok because everything works fine.
But it completely lacks aop hints: if you have bean without dependencies and use JIT binding for it it will bubble up which is ok.
But aop, you expect to be working isn't working anymore.

There must be an option to specify aop requirement hint for dependency to let guice count it as dependency too when it decide to bubble.
Something like: bindAopHint(Matcher.annotatedWith(Transactional.class)) - all beans with transactional annotation should remain in child injector
(I understand its weak solution, but just to show the idea)

Or at least it would be great to have ability to tie binding to injector, for example, when I do
injector.getInstance(MyType.class) // injector here is child injector
MyType will be binded in parent injector (suppose it has no deps on other beans). 
But I want it to use aop of my child injector! No way to tell guice about it... (only by using redundant "anchor" dependency in bean)

четверг, 25 июня 2015 г., 5:40:30 UTC+6 пользователь Tavian Barnes написал:

Tavian Barnes

unread,
Jun 25, 2015, 10:22:11 AM6/25/15
to google...@googlegroups.com
I don't think bindAopHint() would even be necessary.  Guice could just run all the matchers already specified with bindInterceptor() to see if any from the child would apply.  If they did then it could keep the binding in the child, or at least raise some kind of warning when it bubbles up to the parent.

But yeah everyone agrees this behaviour is confusing.  TestNG compounds the issue with its mandatory parent injector, which has personally caused me a fair amount of grief for similar reasons.

To save yourself some of that grief I'd recommend always using requireExplitiBindings().
Reply all
Reply to author
Forward
0 new messages