3 ms·
Spring class names are the stuff of legend, but most of those classes you wouldn't deliberately use in your application. They're there so Spring can layer up it
by niftich 6y ago
Spring class names are the stuff of legend, but most of those classes you wouldn't deliberately use in your application. They're there so Spring can layer up its own functionality feature by feature. The only problematic part about this is when these class names leak into error messages, and the level of indirection becomes difficult to follow.
The way you use the core inversion-of-control framework people often just call "Spring" is you take your homegrown, doesn't-depend-on-Spring business logic, you make a config file, and if you're not executing it a servlet container, you make one entry-point class to start it all up [1].
There other projects under the Spring umbrella, and some of them are meant to be called from your code. Like Spring JDBC for database access, whose framework-like nature is apparent, yet in terms of its usage pattern, it resembles a library [2].
[1] https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans https://docs.spring.io/spring/docs/current/spring-framework-... [2] https://docs.spring.io/spring/docs/current/spring-framework-reference/data-access.html#jdbc https://docs.spring.io/spring/docs/current/spring-framework-...
- pscanf 6y agoI agree in theory, but in practice I've found it very hard to keep Spring (Boot) out of my code. Part of the blame I think falls on Spring's DI container, which is "too good". It makes it easy to pull in any bean, even the wrong one, which means developers have to be disciplined managing how beans depend on each other, and you end up with controllers returning entities. Of course, any codebase turns into a mess if you're not disciplined, but my impression is that developers tend to be less careful when working within the confines of a framework like Spring because it gives them the false sense that they can do no wrong. Recently I started a side project with Spring Boot (after all I like the framework), trying to organise it following Uncle Bob's Clean Architecture approach, which aims to isolate the core business logic of an app from its implementation details like database code and external interfaces. The core turned out pretty well isolated, but the rest is all Spring. Database access? Spring Data. External interface? Spring MVC. Communication with external services? Spring RestTemplate. I'm not saying it's bad, it's actually awfully convenient, but it's not so easy to swap out - say - Spring MVC for http4k, so you end up with Spring being everywhere. Which again, not a bad thing, just something to consider.
- rumanator 6y ago> The core turned out pretty well isolated, but the rest is all Spring. Database access? Spring Data. External interface? Spring MVC. Communication with external services? Spring RestTemplate. I'm not saying it's bad, it's actually awfully convenient, but it's not so easy to swap out External interfaces are just isolated interfaces, which end up being tied to a framework as frameworks do most if not all of the heavy lifting. Just because you picked Spring Database to implement your persistence layer it doesn't mean you are bound to Spring to add a webapi or a web app, though. If for some reason your frameworks are leaking out of any of your external interfaces then that's an issue with how you designed your app, not the frameworks you used. As an example, some Clean Architecture examples using ASP.NET Core decide to implement their persistence layer passing around Entity Framework classes as their interface. That, obviously, tightly couples the whole app to Entity Framework in particular and ASP.NET Core in general. This coupling in turn is completely eliminated by passing a generic repository interface, but using Entity Framework's convenience often forces us to ignore that.
- pscanf 6y ago> Just because you picked Spring Database to implement your persistence layer it doesn't mean you are bound to Spring to add a webapi or a web app, though. I agree, you're definitely not bound to, but again, in theory. For what I've observed in practice, factors like convenience and friction in going off the beaten path mean that when you pick Spring your app ends up being 90% Spring stuff. Which is not necessarily bad, there are certainly many good things about using the well supported, robust, and predictable set of Spring components. But I wouldn't say that Spring is the kind of framework that merely helps you tie together your app, that otherwise stays out of the way, and that you can swap out at any time.
- niftich 6y agoWith Spring Core (the DI container) the only parts of your code that have to depend on Spring are the config and your entry-point. You can choose to import facade-style Spring libraries, and write your code against them -- like Spring JDBC, Spring JMS, TaskScheduler -- if you want something that does some heavy lifting for you, but doesn't tie you to a vendor implementation directly. Meanwhile, Spring Boot is a fully-opinionated framework based around the combination of defaults and on-the-fly auto-configuration, and giving you a single runnable uber-JAR at the end. And you're right about it: if you're using Spring Boot, it makes sense to depend on other Spring libraries, because (1) the docs guide you into them, and (2) the two will interact to auto-configure. For example, you can just run your DB code, and it can auto-configure an in-memory instance as you're developing [1]. Then, when you've gotten the real database, just specify the real config. Spring Boot really shines in bootstrapping a greenfield project to get going quickly, especially if you're willing to compile its annotations into your code. You can then go back and incrementally override behavior and configs once you realize you want them a certain way. [1] https://docs.spring.io/spring-boot/docs/2.2.7.RELEASE/reference/html/spring-boot-features.html#boot-features-sql https://docs.spring.io/spring-boot/docs/2.2.7.RELEASE/refere...
- nickbauman 6y agoDI/IoC is just another way of expressing global variables. The global variables exist because of the constraint of class-orientation getting in the way, among other things. Spring exists because of the relative weakness of the Java language. You won't see this kind of technology emerging in more powerful languages.
- delusional 6y agoThis is very often the case. So often you see these stateless "service" classes injected everywhere. It's not an object at all, it just free functions packaged in a namespace with a vtable in front of it that now need to be allocated. A language with free function support alleviates that problem.
- ljm 6y agoI'm having to do a lot of this now and I cannot imagine having to write any code, in any language, this way without depending on a magic IDE and other magic libaries. To be fair, at least Spring and Lombok don't require me to maintain loads of yaml/XML files to describe the DI stuff, but annotations in java aren't always the most intuitive thing. Requiring a class representation of literally everything is a huge limitation, and I wish there were other alternatives to this style of DDD that abstracts everything to an absurd degree.
- therealdrag0 6y agoIf they were JUST functions they could be static utils and wouldn't need to be beens. But these service classes themselves have their own fields/dependencies. The Service class holds an instance of the Caching class and the Database class, each of those hold an instance of clients with connections, for example. Can you explain how language support would remove this pattern? I'm currently working on Scala services, and we don't have any DI, which is actually kinda nice, but it just means we "new-up" all these classes manually in our Main class and pass them through as arguments one to the next. So far I like how there is no "spring magic"; however, in the end the pattern of dependencies is the same.