Currently we have a number of classes that extend TemplateMethodModelEx which we construct using Spring and then inject into the Freemarker Configuration as shared variables so they are available as functions to all of our templates.
However, it would be nicer to have more fine grained control and make these methods available on demand in individual templates. One can instantiate them using the ?new built in, but internally that uses the general Java reflection mechanism for instantiating the class, and these models need to be constructed via Spring to get their dependencies.
In a perfect world, I'd like to make it so that the ?new built in use Spring to construct the class. It looks like to do that I would need to find a way to overload BeansWrapper.newInstance(Class, List) to use Spring, but I'm unclear on the best way to accomplish that.
Note that we are currently using Freemarker 2.3.23
Related
I've been working a lot with Symfony recently, and I really like the ability to define routes in a routing.yml file. I was looking into Spring's routing system and I couldn't find any options other than placing routes in annotations on controller methods. Is it possible to accomplish something like this in Spring?
My first thought was creating an abstract controller that grabs the routes from a .yml file, but that seemed a bit hacky.
EDIT:
For some added context, I am looking to build a simple Database API with Spring. After some digging it looks like the routing.yml file is best suited for working with server-rendered pages, which is not what I aim to do with my Spring project.
Symfony and Spring are different framework. You are used to one use and want to use same it in another entirely different system. It will not work. You have to adapt to frameworks.
Spring will scan your project and collect your specific annotation like Controller/Component/Configuration/... and configures itself. Therefore, there is no need predefined project structure, unlike, for example, Laravel. So, you can define this structure if you want. Or every class can be in one package, just not beautiful.
Back to routing. You can configure them by the value of annotations only. This is interpreted at compile time. (Ofc, there are runtime annotations, but I focused parameters of annotation.) So, you can not use configuration from the file because it is already runtime. So, you should use constants or hardcode.
Or, you can use an alternative: Annotate the interfaces, then the controllers will be the implementations.
Alternative #2: If you use Spring with Kotlin, In Kotlin, you can have several classes or interfaces in one file.
I want to remove spring from a little library that really doesn't need it in favour of wiring the classes together in code. I feel it should be possible to auto-generate the code to stick the library together using the same logic Spring does to do it at runtime. Does code to do this already exist?
(Of course it might be more complicated for any AOP type stuff Spring is doing - but when it's just vanilla instantiation and autowiring it should be relatively simple?)
Can I use spring-boot with freemarker but I need to create my template in runtime, load from a db, I only find sample using the return in a controller
At least if you don't need Spring MVC (spring-web) functionality, you can just use the FreeMarker API directly. You will need a freemarker.template.Configuration singleton bean (maybe the one that Spring creates for Spring MVC is sufficient, but creating your own is perhaps cleaner), and then you can use new Template(null, someString, cfg).process(dataModel, outputWriter). If performance is a concern, you might want to cache the resulting Template objects of course.
Also note that if you provide a such TemplateLoader implementation, FreeMarker can load template directly from the database, (in which case you would use Configuration.getTemplate(templateName) to get the Template object). That has the advantage that then the templates in the database can be #import-ed/#include-ed, and also that FreeMarker will cache the Template objects for you. And of course, in case you need this for Spring MVC, then you could just do things as usual in Spring MVC, you don't need "inline templates".
I have read that dependency injection is good for testing, in that a class can be tested without its dependencies, but the question comes to my mind if Class A depends on Class B or C or any class, testing Class A independent of some class is yielding a test result of zero, not a failed or past test.
Class A was created to do something and if it is not fed anything whether using new key word or setting up the extra files in Spring, Class A won't do any work.
About the idea of making code modular, readable and maintainable: so business classes became cleaner, but all we did was shift confusion from dirty Java business classes to convoluted XML files and having to delete interfaces used to inject to our loosened objects.
In short, it seems we have to make edits and changes to a file somewhere,right?
Please feel free to put me in my place if my understanding is lacking, just a little irritated with learning Spring because I see the same amount of work just rearranged.
Dependency injection is good for unit testing because you can individually test each method without that method depending on anything else. That way each unit test can test exactly one method.
I would say that if the xml is what’s annoying you check out Spring boot. It’s based on a java configuration so no xml and it simplifies a lot of configuration for you based on your class path. When I first started spring I found the xml very daunting coming from a java background but the annotation based configuration and the auto configuring done by spring boot is extremely helpful for quickly getting applications working.
IMO biggest advantage of using the spring is dependency injection which makes your life easy. For example if you would like to create a new service with three dependencies, then you can create a class very easily using Spring. But without spring, you will end up writing different factory methods which will return you the instances you are looking for. This makes your code very verbose with static method calls. You may want to take a look at the code repositories before spring era.
Again if you would like to use Spring or not is your personal call based on project complexity. But it's other features/advantages cant be overlooked.
And XML files or Java configs are the ways of achieving spring configuration - where you would like to add your business logic is personal flavour. Only thing is you should be consistent all across your project.
I would suggest that you read Martin Fowler's great article on Inversion of Control and Dependency Injection to gain a better understanding of why frameworks like Spring can be really useful to solve a well known set of common dependency injection problems when writing software.
As others have mentioned, there is no obligation to use Spring; and whatever you can do with Spring, you can probably do it by other means like abstract factories, factory methods, or service locators.
If your project is small enough, then you probably wouldn't mind solving the dependency injection issues on your own using some design patterns like those mentioned above. However, depending on the size of your project, many would prefer to use a framework or a library that already packs a bunch of solutions to these recurrent head scratchers.
In regards to the advantages of dependency injection frameworks when doing unit testing is the idea that you don't need to test the dependencies of your class, but only your class.
For example, most likely your application has a layered design. It is very common to have a data access class or a repository that you use to retrieve data from a datasource. Logically, you also have a class where you use that DAO.
Evidently, you already wrote unit testing for your DAO, and therefore, when you're testing your business class (where the DAO is being used) you don't care about testing your DAO again.
Fortunately, since Spring requires some form of dependency injection for your DAO, this means your class must provide a constructor or a setter method through which we can inject that DAO into our business class, right?
Well, then during unit testing of your business class, you can conveniently use those injection points to inject your own fake DAO (i.e. a mock object). That way, you can focus on the testing of your business class and forget about retesting the DAO again.
Now compare this idea with other solutions you may have done on your own:
You inject the dependency directly by instantiating the DAO within your business class.
You use a static factory method within your code to gain access to the DAO.
You use a static method from a service locator within your code to gain access to the DAO.
None of these solutions would make your code easy to test because there is no simple manner to get in the way of choosing exactly what dependency I want injected into my business class while testing it (e.g. how do you change the static factory method to use a fake DAO for testing purposes?).
So, in Spring, using XML configuration or annotations, you can easily have different dependencies being injected into your service object based on a number of conditions. For example, you may have some configurations for testing that evidently would be different than those used in production. And if you have a staging environment, you may even have different XML configurations of dependencies for your application depending on whether it is running in production or integration environments.
This pluggability of dependencies is the key winning factor here in my opinion.
So, as I was saying, my suggestion to you is that you first expand your understanding of what problems Spring core (and in general all dependency injection frameworks) is trying to solve and why it matters, and that will give you a broader perspective and understanding of these problems in a way that you could to determine when it is a good idea to use Spring and when it is not.
I have years of Java experience on Eclipse and now would like to get my feet wet with Spring. After read some tutorials I have such a question: is it easy (or even possible) to find classes/methods references in any IDE that supports Spring? By using Spring there should be no direct references among some classes, instead they are configured in xml files.
Even further: how to manage those xml files if my project gets large, say with thousands or hundreds classes? I mean perhaps it is easy to get lost among those complicated configuration files.
Spring is a dependency injection engine. This means that it injects instances of A into beans which are dependent on A. So if bean B has a dependency on A, it will have a field of type A, and Spring will initialize this field for you.
Finding the references is thus trivial: select one of A's methods, choose "Call hierarchy", and if B calls this method of A, Eclipse will find it. It's not different from any other Java project not using Spring.
Regarding the size of the XML files, Spring also uses annotations to inject beans, so the XML file can be reduced to a minimum.
With STS or the Spring-IDE plugin, it is possible to click on the class definition in the spring xml file and you will be direcly "forwarded" to the class.
And for example you build a view where the bean instances are displayed in an uml like class diagram. To get an overview how which bean is connected to other once.
But really you will not need that.
If you implement against an interface then it should not matter which concrete class is implementing the interface.
And if you implement against an class, then you know that class already.