News for hackers. Stuff that matters.
Re:Love It or Hate It, Java Continues to Evolve by nurettin on Monday June 17, 2019 @09:37AM (#20202763)
Just now I embedded an amqp client into my app. To do that, I had to create a configuration class that instantiates necessary queues, exchanges and binds them to eachother using builder syntax and beans. The spring boot app lazily handles rmq client initialization and I didn't have to think of object lifetimes. That kinda sorta simplified my job. However, your point still stands, I had to learn new syntax (I learned to type @Bean) to do all this.
Re:Love It or Hate It, Java Continues to Evolve by unscaled on Monday June 17, 2019 @12:49PM (#20204843)
Nothing precludes you from using Guice or Koin for dependency injection with any framework. Yes, any DI framework would require you to understand some new syntax, but Spring again comes as more magical and mysterious, and the abstractions are always leaky. For instance, when using its magical scopes, it will create proxy instances without you using its magical request scope, bytecode-gen magic (cglib) or plain reflection (which is bound to be just amazing for performance).

This behavior which looks helpful at first glance, is very confusing. If your not proficient with Spring or spend hours reading the documentation you'll never understand that: 1. Your object lifetime is tied to the request. 2. The instance you see at the debugger is actually a subclass that redirects all call to the actual scoped object instance depending on a thread local variable (I guess?) 3. The proxy instance is either slow (JDK Proxy) or could cause you grief when you upgrade to the next version of Java (CGLIB). It's not clear which is which without some investigating.

I rather prefer to go with a lightweight framework + a sane DI framework and do something more explicit, e.g. create a RequestProvider<T> interface:

    interface RequestProvider<T> { 
      get(request: Request): T
    }

    class MyController() {
      val fooProvider: RequestProvider<Foo> by inject(name = "foo")

      fun myHandler(request: Request) {
          val requestScopedFoo = fooProvider.get(request)
      }
    }
This approach is more explicit, but I prefer it.
Re:Love It or Hate It, Java Continues to Evolve by debug-desperado on Monday June 17, 2019 @03:21PM (#20206408)
I don't get all this about Spring being an "insane" way to do DI. It works well enough, and Pivotal is very thorough with their documentation. I would much rather RTFM than dig randomly through the code and hope I find what I'm looking for.

How exactly does Guice differ in request- or session-scoped injections that makes it that much better?

Re:Love It or Hate It, Java Continues to Evolve by Nursie on Monday June 17, 2019 @11:24AM (#20203868)
> Just now I embedded an amqp client into my app.

I have no need for one of those, I'm good building some fairly simple microservices against spark without 'lazy client initialization' or any framework features.

That's kinda the point, it's a simpler toolset for a single purpose. You may have requirements that are made simpler for you by knowing the arcane ins and outs of a feature-rich framework.

Not everyone does, and bringing in said framework to achieve something simple in the name of "Maybe, in future, I may need this" is a prime route to an overcomplex, heavyweight mess. IMHO.

Maybe you've avoided Spring-related hell, but all the java devs I know who survived that era tend to groan whenever it's mentioned.