Good question - quite a few actually. @ConditionalOnMissingBean on every public @Bean method, proxyBeanMethods = false on every @Configuration class, the thin wrapper pattern (auto-config classes must have empty bodies) - those are all structurally checkable. CAS doesn't use ArchUnit specifically, but the consistency you see in the codebase didn't happen by accident. The patterns that can't be easily enforced statically are the harder ones - like making sure every module contributes to shared capabilities through the configurer pattern instead of direct coupling. That's where code review discipline fills the gap.
This is a Spring specific gripe and I know this blog post doesn't assume Spring, but I hate seeing `new ObjectMapper()`. Spring Boot auto configures an ObjectMapper for you and you probably want the customization it gives you, including `java.time` handling and classpath scanning. I've wrestled with so many bugs caused by not using the `ObjectMapper` bean.
If you really want to write really performant java code, the word "spring" should not even be mentioned. Same thing for Jackson, write you own lazy json library if the data is bigger than a few 100k.
The code will not look pretty but it will be very fast.
Speaking of Jackson and performance... I have been working on Jagger for a while now, which aims to replace all that reflection during databind with annotation processing.
I am trying to aim for something like Mapstruct for the developer experience, since everybody loves Mapstruct. With Jagger, you bring a parser (JSON/XML/whatever), define some databind methods, and it generates the implementation for you.
So far I've only had my own use cases, so I would love to have some wider feedback.
Have always really liked Java, but yeah, Spring overall has been terrible for the language. Autowiring is against the principles of a typesafe programming language - Don't make me guess what what object is going to be attached to a reference. And if you do, at least figure out what linked object is at compile time, not at run time.
Spring autowiring makes Java seem as a whole unnecessarily complex. Think it should be highly discouraged in the language (unless it is revamped and made apart of the compiler).
... not sure how this applies to the ObjectMapper, as I haven't programmed in Java in awhile.
... and my gripe doesn't apply to SpringBoot though:)
> Autowiring is against the principles of a typesafe programming language
Constructor autowiring is the application of the inversion of control and dependency injection pattern. If there was no autowiring, you could autowire the components together just the same with normal code calling constructors in the correct order. Spring just finds the components and does the construction for you.
Yeah, for me at least, personally believe inversion of control should be used more surgically instead of blanketing the system with it. On the one hand, freeing your application layer from direct dependencies with the lower-level objects conceptually seems like a good idea, but think in practice, this is hardly ever helpful especially when used for every dependency.
At least from my experience, seems like we don't change the objects we use that often, that once a object is set on a reference var, a very, very large majority of them won't change.
And because of this, seems like that for most objects dependencies, we should just new them directly, and if later on we do need to change them, then at that time, we can refactor the code to use more abstraction (like inversion of control) to break the direct dependency, but only for the code that needs it (or if there is a important situation where having a direct dependency could be highly problematic in the future, like to a DB provider).
It's like the performance optimization problem. One guideline that is often quoted is that it's best not to over optimize the performance of your code, until you actually can test it in real-world test cases, because you very often optimize things that aren't the bottleneck. Same with the over usage of inversion of control. Spring makes it so we're using IOC everywhere, but it's just adding unnecessary complexity.
Think that if inversion of control is used, should be used mainly at a higher level, for components instead of on every class like often happens. But even for components, think you should be careful when deciding to do so.
... and agreed, you could just use the factory pattern instead of Spring.
For large applications, having the implementation (or multiple implementations) of certain functionality decoupled from the code using it, improves maintainability and configurability of the application. That is where inversion of control helps. And then manually writing the instatiation, scoping, dependency ordering and cleanup code to manage all of that is not useful to write yourself. Any dependency injection framework will work, although Spring is well used and has many integrations.
Yeah, I get the idea, abstractions allow decoupling. But, think that it should be used in a thoughtful way - there is quote from the original Design Patterns book that said something like a careful considered use of Design Patterns should make the system easier to work with, or something like that (sorry, don't have it on hand).
We can go back and forth on this, so will just say, in my opinion, Spring autowiring overall doesn't provide enough benefit versus its downsides, which to me are: increased complexity and doesn't work well enough (it should be easier to debug autowiring problems for one).
You seem very knowledgeable about design, and, of course, you're entitled to your opinion, so seems like we'll probably just have to disagree on this:)
For me at least, being statically typed is overall a strength. Yeah, it's not that much work to include types when declaring vars, but the benefits are you don't have the problems with types in expressions that you do with dynamically typed languages (Javascript for example, which is one the reasons why Typescript was created).
... although, Java have does support some dynamic typing, as you now don't need to have the type when instantiating objects, using the "var" keyword and the compiler will infer the type from the object that is being set to it (although, this is just syntactic sugar).
`var` has nothing to do with dynamic typing. It is still statically (compile time) typed, so the type can not change at runtime. Compare that to JavaScript where you could easily switch the type of a variable from Number to String.
agreed, it's not (as mentioned, it's just syntactic sugar). Still, how often is changing the type of a var needed? (besides minor casting issues)
And not saying that dynamic typing doesn't have a place, I really like working in Python, it's just that for more complicated code, prefer statically typed as it leads to less problems with your expressions. To each their own.
It won't delete unmerged branches by default. The line with the marker for the current branch throws an error but it does no harm. And I just run it with `develop` checked out. If I delete develop by accident I can recreate it from origin/develop.
Sometimes I intentionally delete develop if my develop branch is far behind the feature branch I'm on. If I don't and I have to switch to a really old develop and pull before merging in my feature branch, it creates unnecessary churn on my files and makes my IDE waste time trying to build the obsolete stuff. And depending how obsolete it is and what files have changed, it can be disruptive to the IDE.
Senior Backend Engineer. 13 years of experience. Excited to work in any interesting programming languages. Keen to step up to a role with leadership and mentorship responsibilities.
They just sent out email about the scam. I was so annoyed that even after opening the app, the notification icon still persists, wondering if the hack on the notifications exploits some loophole in the Betterment app
reply