Netflix / karyon

The nucleus or the base container for Applications and Services built using the NetflixOSS ecosystem
Apache License 2.0
497 stars 153 forks source link

Karyon guice, governator and Auto Binding #218

Closed victuxbb closed 9 years ago

victuxbb commented 9 years ago

Hi! First of all, apologies if the question is not very clear, I'm newbe in the NetflixOSS ecosystem :)

I'm trying to use the Auto Binding from governator in this example of karyon:

https://github.com/Netflix/karyon/blob/master/karyon2-examples/src/main/java/netflix/karyon/examples/hellonoss/server/jersey/JerseyHelloWorldApp.java

Since I understand...using a manual "bind" with guice you can use the annotation @inject in your classes...


protected void configureServer() {
            bind(AuthenticationService.class).to(AuthenticationServiceImpl.class);
            interceptorSupport().forUri("/*").intercept(LoggingInterceptor.class);
            interceptorSupport().forUri("/hello").interceptIn(AuthInterceptor.class);
            server().port(8888).threadPoolSize(100);
        }
@Inject
    public AuthInterceptor(AuthenticationService authService) {
        this.authService = authService;
    }

But Governator gives you a @AutoBindSingleton to avoid this "manual" declarations since I understand... In the documentation talks about a "usingBasePackages()" I have found and example using the LifecycleInjector...

final Injector injector;
            try {
                injector = LifecycleInjector.builder()
                        .usingBasePackages("com.company.microservice")
                        .build()
                        .createInjector();
                LifecycleManager manager = injector.getInstance(LifecycleManager.class);
                manager.start();
            } catch (Throwable t) {
                t.getStackTrace();
            }

But I'm a bit confused and I don't know how to handle through Karyon this initial configuration of Governator.

Maybe someone can enlighten me :)

Thanks!

NiteshKant commented 9 years ago

@victuxbb in general AutoBindSingleton is not a recommended approach. Over time using it in applications inside Netflix, we have found out that it is anti-pattern as it relies on class path scanning and an application owner looses control on which objects get initialized in their applications.

Using explicit bindings is the recommended approach with karyon.

victuxbb commented 9 years ago

looses the control over the objects? Maybe I don't understand the docs but... in the documentation of Governator explains that only the classes with the annotation are binded

@AutoBindSingleton(BaseClass.class)
public class MyClass implements BaseClass {
   ...
}

If MyClass is in a package specified via usingBasePackages(), Governator will automatically bind it as:

binder.bind(BaseClass.class).to(MyClass.class).asEagerSingleton();

As I see it's change from a manual "bind" to an annotations in classes. May be I misunderstood something?

Thanks!

NiteshKant commented 9 years ago

Sorry, I should have explained better. The problem comes when libraries (dependencies provided by third-party) used in an application start using AutoBindSingleton. Since, AutoBindSingleton uses classpath scanning to discover classes, any AutoBindSingleton in the classpath starts to get initialized (due to it being an eager singleton). This gets out of control if an application uses a lot of libraries which define a number of AutoBindSingleton classes and hence causes inconvenience for application developers in terms of gaining control of what gets initialized in an application.

So, it is better to define bindings via modules and hence the application owner decides which modules are to be added to the application. This results in a more predictable and easier to maintain/operate environment.

victuxbb commented 9 years ago

Ok I understand, thanks for the info :+1: