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.
Related
As I read, singletons are bad and one should avoid using them.
But I develop an App where most Activities and Fragments need to have access to the same dataset. The datas are stored in a an ArrayList and accessible through a singleton class.
What is bad about that? I can't create a new data-class object for each activity because the ArrayLists will be different. What is the alternative?
singletons are bad and one should avoid using them
In Android app development, we use singletons much more than in traditional Java development.
IMHO, the keys are:
Use them carefully, making sure that you do not introduce memory leaks, race conditions, etc.
Use them for specific roles, such as following the repository pattern, rather than just slapping static on everything because you want to make the compiler stop saying mean things to you
Use them reactively (LiveData, RxJava, Kotlin coroutines, etc.), assuming that the data managed by the singleton is coming from something involving I/O (network, database, file, etc.)
What is bad about that?
Possibly nothing. There may be issues with your specific implementation, but we have few details about that.
Singletons aren't bad per se, the problem with them is when you start trying to test your code.
When you have a class/module/component/view that depends on one or more singletons, you have no way to control that dependency, so in a test environment you cant "mock" that singleton dependency or control whats data is in them (you can, but is really annoying having to clean all singletons before each tests, and even though that is error prone).
This can be easily solved using dependency injection. In Android the best framework for that is Dagger: https://google.github.io/dagger/
You can always use dependency injection by hand too, but having a framework that does the hard work for you is nice.
Then, with this approach, you kinda keep having singletons, but they are not really singletons in the way that they are in charge of only creating a single instance, but you (or the framework) are. Those classes are created only once (at the beginning or lazily) and then are injected in the components/clases that depends on them.
This way, you keep having all its features (sharing data between activities, fragments, etc), but, as you are injecting them, you can mock them an inject mocks for testing purposes.
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.
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.
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.
I have been reading the book Spring in Action for a few weeks now to learn about the spring framework. I have about 2 years of programming experience mostly in java with some distractions here and there in Ruby and Python.
After reading the first few chapters, I didn't quite get what the big deal is about dependency injection in spring. I was expecting a AHAAA moment but didn't quite experience that yet. I'm sure I'm missing something important.
Why would I want to wire my beans in xml rather than instantiating them the good old way with the = new myclass();
I understand I can wire beans in the xml via constructor args and properties as well as configure datasources in spring so that I can hide away connection details in an xml file. But why? There is more to this especially when it comes to good software design. Can some one explain the big deal?
Three Words: INVERSION OF CONTROL
In a nutshell:
As soon as you instantaniate "the good old way" you create tight coupling, e.g.: your controller depends on a specific template engine, your entities on a concrete database layer, etc. And that's something you want to prevent and where the dependency injection container (DIC) comes in very handy. It manages your services and you don't really have to care anymore about specific implementations as long as those implement the same interface.
Imagine a simple storage layer class called InMemoryLayer that gets instantiated by you when need it. Now you want to switch it for an awesome new open-source github solution called SuperSecretRemoteCloudLayer. Normally you would now hit "Search and Replace" in your IDE of choice and replace all occurrences of InMemoryLayer with the SuperSecretRemoteCloudLayer. But that's not really handy and quite errorprone, why would you want to do all that hard work by hand? The DIC can do that for you and all you need to take care of, is that both *Layer implement the same interface (so your application won't break).
Spring's big deal is more about dependency injection, not XML-based configuration. As others have noted, Spring has been moving away from XML-based configuration. But DI is core to Spring.
The a-ha is that DI offers a different model for linking components together. Instead of components creating each other directly (and thus being tightly coupled), the components stop doing that, and you inject the linkages from a central location. It turns out that this helps with testing and transaction management in particular.
You don't truly appreciate Spring until you've had to do things the hard way. The hard way being maintaining multiple large projects without a coherent framework. If you have 4 big enterprise wide applications that all have their own way of starting themselves, and managing resources, you're in for a headache. If you know that each application uses spring, then just look for the application context xml! This also makes it incredibly easy to setup a new context for different environments, and test cases, all without mucking up your code base.