0

Consider simple 2 cases

1)

@Bean
public MyBean myBean(){
    ..create and return
}

@Bean 
public Another anotherBean(){
  new Another(myBean());
  myBean();
  myBean();
  myBean();
}

In such case, some sort of AOP (or not?) will kick in and myBean() will be called ONLY ONCE

2)

@Component 
public class MyClass{

.....

@Autowired
private MyClass self;

@Transactional
public void inTx(){

}

public void doIt(){
   inTx(); //this will NOT be transactional
   self.inTx(); // this will 
}

}

Now, why those 2 cases are different? Why behavior is inconsitent here? I was convinced that in order for AOP in spring to work I ALWAYS have to use scenario 2 and do "external call" on proxied instance. I also thought that scenario 1 will create 4 distinct instances.

So what is the difference and why such inconsistency?

Or maybe scenario 2 is no longer valid because something changed and I just dont know about it?

Antoniossss
  • 31,590
  • 6
  • 57
  • 99
  • Not sure what you mean. The `@Bean` method creates exactly one instance, it's the same as the constructor of the `@Component `, not its method. Your assumption of the four distinct instances being created is just false, it is consistent. – daniu Feb 07 '20 at 18:56
  • Please notice that I am doing "plain call" to that method in `anotherBean`. Normally it would be called eg in the `@Component` - but not here. So why AOP works differently here? – Antoniossss Feb 07 '20 at 18:59
  • Yeah but those calls (I assume) are in a `@Configuration`, which enforces that only one instance is created of the (singleton). beans it provides. – daniu Feb 07 '20 at 19:01
  • I do not have a "why" answer for you, but condition 1 is a special case. Condition 2 still requires `instance.method()` in order to be in a transaction. – Christopher Schneider Feb 07 '20 at 19:04
  • @Daniu you are trying to tell me that it is how it is like I would not know that already? - I just placed a POC here so its solid confirmation that "it is how it is". The point is, why it is different behavior than in `@Component` cases. In @Components self invocation must be done via scenario 2 in order to make pxoxied call to work. – Antoniossss Feb 07 '20 at 19:06
  • One post says it is because of CGLIB proxy. Does that mean if I turn on AOP with CGLIP proxies on, instead of using java.util.proxy, self invocation will be proxied as well (In the components)? I kind of doubt it and starting to think it is not because it is impossible but because it is some sort of design decision - like Christopher suggest between the lines. I would like to know that. Mentioned post https://stackoverflow.com/questions/27990060/calling-a-bean-annotated-method-in-spring-java-configuration – Antoniossss Feb 07 '20 at 19:08
  • If you call `myBean()` from your code you will get a new instance every time you call it. The `@Bean` annotation only works when Spring calls the method, you would then access the Spring bean with the `@Autowired` annotation on a field or constructor then Spring would inject its managed bean. – DCTID Feb 07 '20 at 19:23
  • You did say "I also thought that scenario 1 will create 4 distinct instances" which is not the case? Anyway, the difference is that the `@Bean` method get evaluated during infrastructure setup, ie before AOP activation. Does that answer your question? Otherwise I'm really not sure what your question is, sorry. – daniu Feb 07 '20 at 19:56
  • @DCTID i am calling it "in my code" yet call is intercepter. – Antoniossss Feb 07 '20 at 20:22
  • 2
    Does [this](https://stackoverflow.com/a/56919004/4214241) answer your question ? – R.G Feb 08 '20 at 00:04
  • Comparing apples (bean factory method) with pears (self-invocation of a normal method inside a bean/component) and then wondering why they are different is not a helpful approach. – kriegaex Feb 08 '20 at 03:07

0 Answers0