Hi
I have a LogInterceptor service that I need to run early in the application startup sequence. So I injected it in AppLifecycle Context listener to initialize it.
@Component(LogService.NAME)
public class LogInterceptor extends AbstractService implements LogService {
private static final org.slf4j.Logger log = LoggerFactory.getLogger(LogInterceptor.class);
//---
@Inject
public GlobalEventBus eventBus;
@Inject
BusyConfig conf;
@Component("busy_AppLifecycle")
public class AppLifecycle implements AppContext.Listener {
//---
@Autowired
LogService logService;
As you can see, it injects an instance of GlobalEventBus, I was expecting it to be a singleton for the whole life of the application.
Then later, I need the GlobalEventBus in another class ExtAppMainWindow :
public class ExtAppMainWindow extends AppMainWindow {
private final static Logger log = LoggerFactory.getLogger(ExtAppMainWindow.class);
@Inject
GlobalEventBus bus;
I noticed instance of GlobalEventBus was different than the one injected when initializing the LogService earlier, which breaks what I’m trying to do. So I tried to inject instances of LogService and GlobalEventBus in Editor screens to see which ones I would have. I also tried with custom @Component classes.
My conclusion is that Injection reliabily provides Singletons each time except the first one, and I’m not sure to understand why.
This is confirmed with the log :
2017-04-26 11:21:52.280 INFO [localhost-startStop-1] com.busy.app.service.LogInterceptor - init com.busy.app.service.LogInterceptor@457cdf4b
2017-04-26 11:21:52.280 INFO [localhost-startStop-1] com.busy.app.service.LogInterceptor - init EB com.busy.app.events.GlobalEventBus@815cb90
2017-04-26 11:22:01.075 INFO [http-nio-8080-exec-3/app/admin] com.busy.app.web.screens.ExtAppMainWindow - EAMWLS : com.busy.app.service.LogInterceptor@38a1e44f
2017-04-26 11:22:01.076 INFO [http-nio-8080-exec-3/app/admin] com.busy.app.web.screens.ExtAppMainWindow - EAMWLSEB : com.busy.app.events.GlobalEventBus@75a88945
2017-04-26 11:22:09.151 INFO [http-nio-8080-exec-11/app/admin] com.busy.app.web.customer.CustomerEdit - CE : com.busy.app.events.GlobalEventBus@75a88945
2017-04-26 11:22:09.152 INFO [http-nio-8080-exec-11/app/admin] com.busy.app.web.customer.CustomerEdit - CELS : com.busy.app.service.LogInterceptor@38a1e44f
2017-04-26 11:22:09.152 INFO [http-nio-8080-exec-11/app/admin] com.busy.app.web.customer.CustomerEdit - CELSEB : com.busy.app.events.GlobalEventBus@75a88945
You can see the the two first instances are different than the ones injected afterwards. I suspect that this is because the first injections are done through direct Spring, and the subsequent ones are done through CUBA own injection mechanism. And they are not sharing the same list of singletons. Am I right ?
Working with this assumption, I thought about using @Autowired everywhere, even if less elegant, in order to bypass CUBA injection. But CUBA classes are not @Component so it will not work. Thus I’m stuck here.
Any guidance appreciated. If I cannot make it work with injection, I’ll have to rely on the old and ugly Singleton anti-pattern with static ‘getInstance()’.
Mike