I got stuck in a situation where I have two options to implement a part of a project.
I have a handler interface which internally contains a couple of methods to handle the incoming requests. The interface has been implemented by multiple concrete classes.
Option 1
I have a domain object that I can pass it to constructor by defining the related handler object with new keyword. So, it would be a stateful class, where I can not get benefit from having bean. In other words, I can not annotate the class with bean annotations such #component or #service.
Option 2
I can define handler classes as spring bean. But, in this case I will have to pass the domain object to each method (stateless) that is defined in the interface. It is a bit weird.
Can you tell me what is the disadvantage of option 1 in terms of memory? You know for each request I will need to create a new object in option 1, whereas I will use the bean which will be handled by spring ioc in the option 2.
The both solution works as I implemented and tried. But, I want to know pros/cons.
Related
I am learning Spring Boot and have quite a theoretical question. In this Udacity Example the
model class is initiated manually:
ChatMessage newMessage = new ChatMessage();
Is it good practice?
I will elaborate further on this. Let's say I have a DateUtil class that does some date conversions, should I register it using #Component annotation or manage its dependency myself (DateUtil dateUtil = new DateUtil())?
So the main summarized question: How to know when to use component annotations and when to initialize classes manually?
Thanks a lot!!!
The answer to the first question is, yes, it's still okay, because beans are assumed to be singletones, although not always. In this case, it makes no sense to mark the ChatMessage class as a bean, since instances of this class will be created many times and it is absolutely unclear what benefit will be obtained if they are all beans and are located in the application context.
Answer to the second question: I think the DateUtil class should be instantiated in the usual way, because it looks like a regular utility class like StringUtils. Perhaps you should make its methods static and then you won't have to instantiate it at all. But if this is a complex class that contains business logic and / or is initialized with some data received from outside the application when it starts and this object of this class is used in other classes of the application, then it may be worth making it a bean.
The answer to the third question: it is difficult to give an unambiguous answer. Beans are worth creating when you want to achieve an inversion of control and not depend on the class you are injecting. Declaring a class as a component so that its instances become beans must make sense, bring an advantage to the design of the application.
You need experience with Spring applications to understand when to make beans. Take a look at some well-known Spring applications to understand in which case and which class instances are beaned.
As I know, when you create class with #Component (I like use #Service), Spring will create bean inside IoC. Then you can use that bean by #Autowired, with #Component you create only one instance, that will be shared all over the application. When you use 'new' method to create object, you create object by yourself. Check more info in bean scope doc.
I am trying to apply ioc into a school project. I have an abstract class Application without any field
public abstract class Application {
abstract public void execute(ArrayList<String> args, OutputStream outputStream, InputStream inputStream) throws IOException;
}
And I will call the concrete class that extends Application by
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Application app = (Application)context.getBean(appName);
My questions are:
Is it a bad practice to initialise a bean without any field (or all the fields are constants) using Spring?
As there is no dependency to other classes in Application, are we still consider this as a dependency injection or IOC? If no, what is the difference between this and a normal factory pattern? It seems that what Spring does here is simply matching the class and initializing it.
UPDATE
Here is the code snippet of the class where the instance of Application is needed.
String appName = argument.get(0);
Application app = ApplicationFactory.getApplication(appName);
ArrayList<String> appArgs
= new ArrayList<String>(argument.subList(1, argument.size()));
app.execute(appArgs, outputStream, inputStream);
Further questions:
in my code the class X will call the instance of Application by specifying a concrete application class name. In this case, it is still not possible for Spring to inject the dependency to Application, right? As what I need is a concrete class but not Application itself.
if Application does have fields but these fields are initialsed somewhere higher than X (X receives them as inputs and passes them to Application), can I use DI in this case?
Is it a bad practice to initialise a bean without any field (or all the fields are constants) using Spring?
No, its totally fine. Its true that you won't be able to "take advantage" of the automatic dependency injection mechanisms provided by spring (because obviously there are no dependencies in the class Application in your example), however spring can still:
Make sure that the Application as a singleton "obeys" the rule of being a single instance in the whole application context. For "manually" maintaining singletons you need to write code. Spring does it for you.
Manages the lifecycle of the object. Example, Spring has "postConstruct"/"preDestroy" methods that can can be run in the appropriate time and make example any custom code of the class Application.
If this class does some heavy-lifting (even without spring) than it can make sense to define it "lazy" so that the initialization of this instance will actually be done upon the first request to it.
Sometimes you/or spring itself will create a proxy of this class in runtime (for many different reasons, for example this aforementioned lazy functionality, but there are also other use cases). This is something that spring can do for you only if it manages the Application and not if its defined outside the spring.
Ok, you don't have dependencies in the application, This means that this Application class has some useful methods (at least on method, like public void foo() for
simplicity). But this in turn means that there is some class (lets call it X) that calls this method. So this class has an instance of Application as a dependency. So now the real question is who manages this class X. Probably it makes sense to manage it in Spring as well, and then you will benefit of the Dependency Injection mechanisms in this class X only because Application is also managed by Spring. In general Spring can inject dependencies only if these dependencies are managed by Spring.
I know, this last paragraph may sound vague given the use case you've presented, but you've got a point, for example in real application people make an initial bootstrapping in very certain places. Usually also people use spring boot that kind of encapsulates this kind of things for you.
As there is no dependency to other classes in Application, are we still consider this as a dependency injection or IOC? If no, what is the difference between this and a normal factory pattern? It seems that what Spring does here is simply matching the class and initializing it.
So as you see, the concept of DI container goes far beyond of what the factory pattern has to offer. In short, factory pattern only specifies the way to create the objects. Spring on the other hand, not only creates the objects but also manages them.
First, I very strongly suggest that you use Spring Boot instead of manually manipulating Spring at a low level like this.
It's perfectly ordinary to use beans that don't have their own fields for settings, but this is usually so that other beans can have pluggable strategies or providers and you can define in your application setup which to use.
If your Application class doesn't need anything else, then there really is not much advantage to Spring. Most real-world programs get complicated soon, however, and that's where it becomes useful.
Finally, you should almost never pass ArrayList as a parameter; use List instead. In the code you showed, however, if you have String[] args, you couldn't say app.execute(Arrays.asList(args), System.out).
I have some model object or so called POJO object in my application.
Those objects are meant only to store data and will not perform any action.
I know that In most cases Spring Beans are not POJOs. E.g mostly i declare DAOs, Service, Controller classes as Spring Beans.
But if I will initialize the POJO or even a List object with new keyword
I am tightly coupling it to the implementation class.
So if later someone will extend my POJO to add some member variable he will not be able to inject it to the services classes.
I thought of using the Application context Aware to do it but then I am tightly coupling my application to Spring.
So my question is
What is the best way to initialize POJO object that it can be extendable later.
I prefer to do it using the spring Spring IOC container
First of all I wouldn'be so concerned about tying code to implementation classes. You're correct in that IoC is used to provide flexible points to a code base (extension over modification), but unless you're writing a framework, there's no reason to not use the new keyword to instantiate a POJO. When someone are going to extend your POJO, they will most likely be capable enough to inject the extension to the relevant services.
If you really want to use Spring, you will have to register a bean in the IoC-container. If you don't want a singleton, you can use #Scope to have Spring instantiate a new instance every time the bean is requested:
#Component
#Scope("prototype")
public class Foo {
}
In the Spring Framework, it seems like beans are the preferred way of creating objects to use in business logic.
[Dependency injection] is a process whereby objects define their dependencies, that is, the other objects they work with, only through constructor arguments, arguments to a factory method, or properties that are set on the object instance after it is constructed or returned from a factory method. The container then injects those dependencies when it creates the bean. This process is fundamentally the inverse, hence the name Inversion of Control (IoC), of the bean itself controlling the instantiation or location of its dependencies by using direct construction of classes, or a mechanism such as the Service Locator pattern.
So from my simple understanding, the difference is something like this:
// Plain ol' Java
Foo f = new Foo();
// Using beans in Spring Framework
Foo f = FooFactory.get();
Is it an oversimplification to say that as a rule, in methods outside of #Configuration classes and #Bean definitions, developers should only get objects using beans? Specifically, in the case where I want a fresh object, should I inject a prototype bean instead of using the new keyword directly?
One example of code where I'm not sure I'm following Spring conventions is shown below.
// Construct a new object that will be created in the database
RecordDto record = new RecordDto();
// Or should I be using some bean factory?
RecordDto record = RecordDtoFactory.get();
Please read this Article from beloved martin fowler.
I think the IOC concepts is useful when some component in your application has a dependency to other component for some functionality to complete. IoC container will be responsible for managing creation and lifecycle of software components and also inject them in dependent components instead of manually get access to these components instances.
For example, when some Service require an instance of DAO, it will get it from container instead of creating it.
But in case of DTO, they will just hold the data and that is not a real dependency. So I think using "new" is better in this case.
I am new to Spring concept, so I have little confusion about #Component which by default is a singleton which creates an instance whenever a class is loaded and the same instance is reused; same happens with new operator. If a class is declared as singleton we can change the properties of the class using setters and getters same with new operator also.
When you call new , you are creating the instance during runtime manually.
Assume , you have a controller being called 'N' number of times which im turn calls a Service.
Java
In plain java, you will be creating a New Object by calling new. Which means , you are creating 'n'number of objects
Spring
In Spring, when you just deploy the application in the server or load the spring XML/Configuration class, the Spring creates an instances of all the classes which are annotated , and stores in the spring container. Now,even if your controller is called 'n'times, spring will use the same object again and again
Because you wont call new instead use another annotation called Autowired
#Component annotation says that the object is managed by Spring: i.e. the framework creates it. Usually you should use the dependenci injection mechanism using Spring: I mean you don't need to create the component instance by yourself but inject the provided one into your code.
Read about the IoC paradigm here: https://en.wikipedia.org/wiki/Inversion_of_control
Also you can actually change the scope of the Spring managed bean to different then singleton (see tutorial here) but if you already implenemted some singleton class on your own you can't override it's behavior
BTW you shouldn't use the new operator for singletons (actually you can't because of private constructor), use method like getInstance() instead