Non-managed objects in Spring application (best practice) - java

I have been working on a few web applications and REST web services recently (Spring IoC/MVC/Data JPA etc). They usually follow the same pattern: Controller classes --> Service classes (which have several "utility"/business logic classes autowired) --> Spring Data Repositories.
Pretty much all of the classes above are Spring singletons. I feel like this makes the code and some functions within a class dirtier; for example, I can't have a state in a class, I need to pass a lot parameters between methods, and I don't really like having more than 1-2 parameters (although I know sometimes it is necessary).
I was wondering how this problem is overcome in the big (e.g. enterprise) kind of application.
Is it a common practice to use non-Spring managed classes in the Spring application? If so, how do you pass dependencies into it (the ones that would normally be autowired)? If I use constructor injection for example, then I need to autowire all necessary dependencies into the class that creates the object and I wanted to avoid that. Also, I don't really want to be messing with load time weaving etc. to autowire beans into non-Spring objects.
Is using prototype scoped beans a good solution? The only thing is that I need to use AOP's scoped proxies (or method injection etc) to make sure that I get a new instance for any bean that is autowired into a singleton in the first place. Is that a "clean" and reliable option (i.e., is it certain that there will be no concurrency type of issues)? Can I still autowire any singletons into those classes with no issues?
Does anyone that worked on a large system (and actually managed to keep the structure not "bloated" and clean) have any recommendations? Maybe there are some patterns I am not aware and could use?
Any help appreciated.

Spring is well designed, you must not worry about about IoC implementation of DI. The pattern that you have mentioned /Controller Layer -> Service Layer -> Data Access Layer/ is good in practice, and it is ok that these singleton objects does not have state because of rule of OOP: "Think about objects as service providers that does one thing well". Models can have state as JPA units for storing something in Database. Is not mandatory that in large systems you will have dirty code how you mentioned passing a lot of parameters, it just depends on your design decision that will need a deeper construction.

Related

Spring Dependency Injection usage

I'm still learning about the Spring Framework and I'm trying to really get a good understanding of when and how to use Dependency Injection
Should all dependencies be managed via Interfaces?
Use interfaces for dependencies that expose an API of some sort and that have an implementation that may need to be swapped out (e.g. using mocks in unit tests). One common case is the DAO (data access object), which in Spring Data refers to as a Repository, which ties your data model to a persistence layer. Another common case is a Service which exposes operations on your domain model. Typically a Service will depend on the data access layer, so to unit test the service you will mock the DAO/repository. Another example is a third-party service; these are often only used by production systems, but must be simulated in development and testing environments. In this case, an interface is far superior to, say, embedding boolean flags in your code and hoping you don't have any logic errors.
The key thing to remember about managing dependencies is actually managing your use of the new keyword. Any time you use new, you are creating a dependency on an implementation. The goal of dependency injection is to separate how you use things you depend on with how you get them. You can depend on either an interface or a class, for a simple, obvious reason: Java supports subclassing. So even if you depend on a class instead of an interface, you might end up with a subclass. Spring framework actually does this automatically in many cases.
If you find yourself needing to create objects and you're not sure that you should depend on them, have your dependency injection framework give you a Factory for those objects. How this works is obviously framework-dependent, but all frameworks that I know of support factories. If you're not using a framework, you can still write factories and use them instead of using new all the time.
If you write a code without using spring IOC container, you have to write some factory classes to create objects and hook them up. For an example instance consider a service class which has a reference to the DAO instance. You have to write some initialization factory for the service class which guarantees a singleton access to the service class and makes sure that the service class is instantiated with an instance of DAO. Creating new instances everywhere in your code is not a good practice, hence factory pattern is used. But if you use Spring IOC container it will take care of all these things. Usually it creates singleton instances so you don't need to use new keyword in your code lending you to write more clear code. Your code is loosely coupled and more maintainable with this approach. If you have only one public constructor you can now have the liberty of doing a constructor injection, without using #Autowire invasive annotation with the new spring version.
There are three DI mechanisma used in spring as stated here. Out of the three constructor injection is recommended since it is more testable and does not lead to any invariant. Field injection using #Autowire is evil and not recommended since it is not testable solution.
Hope this helps. Happy coding.

Should we use spring singletons for DAOs

In our web application, we are using Spring as dependency injection mechanism. We have multiple DAOs and Manager spring beans which has a default scope of singleton.We have made sure that all of these beans are stateless. I have read at multiple places why singleton pattern is bad : What is so bad about singletons? .Forgive me if this is asked already but please answer if the above mentioned design comes under bad coding practice and also how improvements can be made to same.
As you can see in the first response to the link you posted (what is so bad about singleton) three problems of singleton are:
Hide dependencies of the application in the code
Violation of single responsible principle
Code strong coupled
None of them is present if you use the singleton via spring dependency injection, because:
Dependencies are stored in the configuration file, not in the code
The single responsible principle is not broken because the construction of your dao is handled by the spring engine, not by your dao
Code is not strong coupled because the configuration can be changed without changing the code
So yes using spring singletons can be a very nice solution not having problems of real singletons.
Spring singleton beans are not using the singleton pattern. They just happen to be instantiated once by the framework, and injected into every component that needs them.
The singleton pattern is considered an anti-pattern mainly because it makes all the classes relying on it hard to test. Spring singleton beans don't have this problem at all.
The primary disadvantage of singletons is that they tend to cause entanglements between different client classes if they have any state. Well-designed service classes should not have any operation-specific state (they'll usually have something like a reference to a database pool or other resources, injected at instantiation and then not changed after), and it's perfectly fine to use a singleton-scoped bean for such services.
If you read the answers from the question you've linked, they don't really apply to Spring singletons. When using Spring beans in singleton scope they're not hard to test, they do not control their own creation, and they are accessed through an interface (or at least should be!).

Is it advantageous to create a Spring bean when I can access the only static method directly with class name

I think my understanding of spring beans is a bit off.
I was working on my project and I was thinking about this situation.
Say I have class Foo
class Foo(){
public void doSomething(Object a , Object b){ // input parameters does not matter actually.
//do something
}
}
If I am using this class in another class like :
class Scheduler{
....
#Autowired
private Foo foo;
someMethod(){
foo.doSomeThind(a,b);
}
....
}
In the above case Instead of Autowiring the Foo, I can make doSomeThing static and directly use Foo.doSomeThing(a,b)
I was just wondering if there any advantage of creating a bean or if there any disadvantage of using static methods like this?
If they are same, When should I go for spring bean and when should do I simply use a static method?
Static methods are ok for small utility functions. The limitation of static code is that you can't change it's behavior without changing code itself.
Spring, on the other hand, gives you flexibility.
IoC. Your classes don't know about the exact implementation of their dependencies, they just rely on the API defined by interface. All connections are specified in configuration, that can be different for production/test/other.
Power of metaprogramming. You can change the behavior of your methods by merely marking them (via annotations of in xml). Thus, you can wrap method in transactions, make it asynchronous or scheduled, add custom AOP interceptors, etc.
Spring can instrument your POJO method to make it an endpoint to remote web service/RPC.
http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/
Methods in Spring beans can benefit from dependency injection whereas static methods cannot. So, an ideal candidate for static method is the one that does things more or less independently and is not envisioned to ever need any other dependency (say a DAO or Service)
People use Spring not because of some narrow specific futures that cannot be replaced by static classes or DI or whatever. People use Spring because of a more abstracted features and ideas it provide out of the box.
Here is a nice quote from Someone`s blog:
Following are some of the major benefits offered by the Spring Framework:
Spring Enables POJO Programming. Spring enables programmers to develop enterprise-class applications using POJOs. With Spring, you are able to choose your own services and persistence framework. You program in POJOs and add enterprise services to them with configuration files. You build your program out of POJOs and configure it, and the rest is hidden from you.
Spring Provides Better Leverage. With Spring, more work can be done with each line of code. You code in a more fast way, and maintain less. There’s no transaction processing. Spring allows you to build configuration code to handle that. You don’t have to close the session to manage resources. You don’t have to do configuration on your own. Besides you are free to manage the exceptions at the most appropriate place not facing the necessity of managing them at this level as the exceptions are unchecked.
Dependency Injection Helps Testability. Spring greatly improves your testability through a design pattern called Dependency Injection (DI). DI lets you code a production dependency and a test dependency. Testing of a Spring based application is easy because all the related environment and dependent code is moved into the framework.
Inversion of Control Simplifies JDBC. JDBC applications are quite verbose and time-taking. What may help is a good abstraction layer. With Spring you can customize a default JDBC method with a query and an anonymous inner class to lessen much of the hard work.
Spring’s coherence. Spring is a combination of ideas into a coherent whole, along with an overall architectural vision to facilitate effective use, so it is much better to use Spring than create your own equivalent solution.
Basis on existing technologies. The spring framework is based on existing technologies like logging framework, ORM framework, Java EE, JDK timers, Quartz and other view related technologies.
During unit testing you have more flexibility using bean because you can easily mock your bean methods. However, that is not the same with static methods where you may have to resort to PowerMock (which I recommend you stay away from if you can).
It actually depends on the role of the component you are referring to: Is this feature:
An internal tooling: you can use static (you wouldn't wrap Math.abs or String.trim in a bean)
Or a module of the project: design it to be a bean/module-class (a DAO class is best modular to be able to change/mock it easily)
Globally, you should decide w.r.t your project design what are beans and what are not. I think many dev put too much stuff inside bean by default and forget that every bean is an public api that will be more difficult to maintain when refactoring (i.e. restrained visibility is a good thing).
In general, there are already several answers describing the advantages of using spring beans, so I won't develop on that. And also note that you don't need spring to use bean/module design. Then here are the main reasons not to use it:
type-safety: Spring bean are connected "only" at runtime. Not using it, you (can) get much more guaranties at compile time
It can be easier to track your code as there is no indirection due to IoC
You don't need the additional spring dependency/ies which get quite heavy
Obviously, the (3) is correct only if you don't use spring at all in your project/lib.
Also, The (1) and (2) really depend on how you code. And the most important is to have and maintain a clean, readable code. Spring provides a framework that forces you to follow some standard that many people like. I personally don't because of (1) and (2), but I have seen that in heterogeneous dev teams it is better to use it than nothing. So, if not using spring, you have to follow some strong coding guidelines.

Static util class with Spring, unsure if I should make it a SpringBean, design concerns

Quick high level concept of my design..
CLI tool to create AWS EBS snapshots
CLI tool just calls Java class com.util.SnapshotUtil
com.util.Snapshot calls AWS Interfacing class com.aws.AWSAdapter
example usage from command line..
cli-tool create-snapshot.. calls java class eventually calling below method
SnapshotUtil.createSnapshot() // statically call AWSAdapter.createSnapshot();
Currently everything is static and outside of Spring.
Now I am wondering if AWSAdapter should not be static, and loaded by Spring, which would mean my SnapshotUtil would need to create the Adapter through ApplicationContext, I believe, as well as supplying it an XML with the Adapter bean info.
Originally I thought since this is a simple util to deal with ebs snapshots, I could ignore Spring, but the AWSAdapter could potentially be used by other means, however, not sure if being static would be a pro or a con.
The Adapter is designed to only deal with an EBS Snapshot, so its basically either creating / deleting / viewing snapshots by using an AmazonEC2Client instance. Even if a Spring managed class wanted to use this Adapter, my question is if it matters if it loads the Adapter through Spring or just statically call it.
edit in response to answer:
I started turning it into a bean and removed all static references, I gave it a method getInstance() which will load itself through applicationContext and return to caller after initializing other dependencies and configurations. When I call this from outside of spring, is that okay? it seems to be working, is it still considered 'injecting'? I am pretty sure its not injecting, since the caller is not spring managed, but I feel this may be hacky? As in, I am using a spring bean in non spring class, so im never spring managed, so I feel there is no reason to turn the utility into a bean. I am still going to do it because I understand the benefits.
One reason I 'have' to turn it into a bean, is that it uses another spring bean I need to handle authenticating, however I thought about it and I could easily just instantiate the other bean using the 'new' keyword.
Am I correct when I say I turned my class into a bean but it is not 'injected' to callers, at least when using the getInstance() method? if I use the getInstance method() in a spring bean, would there be any difference if I were to 'inject' the utility through spring configurations instead?
Generally, you should favor non-static over static. Regarding your specific example, you should go with Spring beans, because that gives you much more flexibility when you start extending your application/module with more complex features.
For example, very soon static-only classes will require some resources from other parts of the system (and we all know how DI helps here).
Or you will need to advise static invocations with some aspects (be it only simple ones as logging of each request, but think of the more complex cases like transactions). With Spring beans this is very simple to achieve and, very important, simple to add afterwards without a big re-engineering and re-testing.
Also, you will much easier integrate beans with other Spring APIs and frameworks that are already well integrated with Spring. For example, you will easy use your bean in an Apache Camel route.
These are just a few points that came to my mind, there are many more of them. But, as always, consider all the pros and cons and pick the right tool for the job.
Edited part of the question
"When I call this from outside of spring, is that okay?"
Yes, it's fine to obtain the bean instance from the Spring application context directly in a class that is not managed by Spring or when the bean name is not known until runtime. In my example with Apache Camel route, that's exactly what Camel does. :)
"Am I correct when I say I turned my class into a bean but it is not 'injected' to callers, at least when using the getInstance() method?"
Yes, it is still a bean with all of the bean's functionality (with other beans injected in it, with aspects around it, etc).
"If I use the getInstance method() in a spring bean, would there be any difference if I were to 'inject' the utility through spring configurations instead?"
Regarding this, you may take a look at this question and at the article written by Martin Fowler, which is also referenced from the question.
In my opinion, you should not do it, it is less readable and quite unnecessary. Injecting the resources as fields is a type safe and a clean mechanism for a class to declare its dependent resources.
Also, bean lookup may be costly if executed frequently. I experienced this on a project I worked on in the past. I don't know why, but it takes some time for Spring (at least the Spring version we used then) to look up and return the bean, and it is noticeable if executed in a loop.

Better way of distributing objects/classes inside a project

I have some Classes like Clipboard or ProcessRegister that I only want to run once in my Project, so only one instance.
My Question in now: How do I distribute those instances best in my Project.
ATM both are singleton and object they use the get an instance over the getInstance().
Another Idea of mine is to create a class Project, that has some static methods like getProjectClipboard()or getProcessRegister()that return the instances.
What is the best way to distribute them? Are there any patterns for that?
Greetings Dennis
There are mainly two patterns that can be used: the service locator, and dependency injection. The service locator pattern is probably the one you are referring to, where everywhere you look for a reference for these objects you explicitly retrieve it from a central location, which for simple java applications is usually a bunch of static methods. this is OK, and I don't think there is an overall better approach here, just make sure that you have only one static method for each singleton, and that you call it always.
Then a few years ago, a shift of mentality became mainstream, dependency injection, and its more popular framework... Spring, with this paradigm, in each place you need to access this singletons, you don't specify where they are, but your object get the correct references injected...
I would recommend you to look into dependency injection... and probably Spring, as it is the mainstream solution for it... I think that giving you more insgight into Spring is out of the scope of the question, but there is A LOT of documentation in Internet if you search for Spring tutorials or something similar...
Basically what you would do is create as spring beans each of your singletons, and then have spring injecting them into your objects... The caveat to this approach is that all of your objects have to be built by Spring, but in practice it doesn't suppose any disadvantage, it will actually make your life easier in terms of testings, maintenance...
Singletons, when done at language level, are global objects. This may work for small projects but is not the best idea when the project grows. There may evolve a situation where suddenly a singleton is only a singleton relative to a certain scope. Then you have to touch the object and every access to it.
That said if you have a Project object or an Application object these are good places to have accessors to Project-relative singletons. If Project is just a class that provides a lot of static accessors it is like a namespace. It is a win in clarity and will make refactoring easier but it doesn't change much in terms of architecture.
Best way to do singletons is not on language level but on application level. Very helpful are application and dependency frameworks like Spring (where the standard scope for beans is in fact singleton). If you later on see that the object isn't singleton you just change the configuration - but not the object itself.
As someone who is usually against the usage of stateful singletons (except for caching purposes), I would say: have one instance of these classes per running application and inject them where you need them (see Dependency Injection). That will also allow you to run the same application multiple times with different configuration in the same JVM.

Categories