Hey guys, welcome to Concept and Coding and today we are going to see a new topic in Spring Boot that is Bean Scopes. And here till now we have covered all these topics and also all this green which I have highlighted and today... dependency injection we have already covered we have already seen bean everything its life cycle and today i am covering the scopes very important okay so we have covered till here Okay, so let's start without any wasting time. So the first and foremost, what is the prerequisite to understand the scope?
So you have to have the understanding of bean and its life cycle, which we have covered in the previous session. So there I have told you this bean lifecycle right. This is the flow it goes.
So this is very important to understand the scope right. Why because there are multiple different type of scopes single turn prototype request session and also there are one more application. Right, so there are five types of scopes and generally if you know this life cycle of a bean, it would be helpful for you to picture eyes like okay at what time the object is getting created.
Okay, so please have a look at this bean and life cycle before you jump into the scope video. Okay, let's start with singleton. So this is the default scope. So here, consider this classes.
This is the class we have already seen, you can create it as a rest controller where you can define an API like I have given get mapping we have already seen that. Okay, so does I have defined any scope here? No, no scope. have defined here.
So what would be the default scope here, singleton. So what does singleton means only one instance created per IOC. What does that mean?
I told you when you start an application, let's say when you start an application, you see that you will see a new one. web server application context has started right so that's actually your IOC is getting started so only one instance created per IOC right or you can say that in most of the manner one instance per application considering that one application is running only one IOC okay and one more thing if you remember I told you that singleton are eagerly initialized by IOC And I have showed you the example of eagerly and the lazy initialization also. While I was explaining you this life cycle. I have explained both eagerly and lazy.
So, singleton are eagerly initialized. Let's see an example. You will recall it better.
So, this is one class. Very basic class. I haven't defined anything here.
No scope. So, what would be the default? Singleton. Singleton. This is another test controller too, but here if you see I can also do this at the rate scope.
You can do value equals to like this configurable bean factory dot scope singleton. So this is like even though singleton is default is singleton only I don't have to write it. But just for demo purpose that you can also specifically write also in this way. So. So there is another class which I write user which is a component and I can write it like this also at the risk of scope and direct you can put a string singleton right internally this enum it's actually.
actually string only singleton right so anything whichever you like you can use it either you can use directly string or enum or you don't do anything in all manner It's this class is a singleton class. Now what would happen when you start the application? What would happen?
So if you know the lifecycle of a bean, what would happen is when you start the application, IOC started and when IOC started, what it will do is it will look for the classes which need to be managed by a spring. So it will look for at the right component at the right rest controller kind of classes. So it found this test controller one first.
So what it will do is it will call its constructor test controller one instance initialization. Test controller one instance initialization. But this object is not fully constructed yet. As you know the lifecycle, right? First it construct a bean, then it inject the dependency then called post construct.
So, currently it created a bean but dependencies are not injected. So now it will look for okay is there any dependency yes user. So now user would be invoked.
So user initialization will happen. Here if you see second is user initialization. So user has any dependency? No, no dependency.
So means user now goes to the next lifecycle post constructor user object created and hits hash code is this. So one user object is created user object created. So now let's say that user object got created with hash code. some 1140202235 something something ok now this dependency is injected here in the test controller so in the test controller in the user this got injected test controller 1 Okay, so now is there any more dependency here?
No. So now it's post construct will come. So now it will write test controller object hash code. So it's hash code. And also I am writing user hash code.
So printing this. So what it will print? test controller object hash code some new hash code like say this is this object hash code and we are also printing this object hash code what would be the same 1140 it would put the same like 1140 this this and this would be same same user object it would have right so currently only one object of user is created one object of test controller one is created Okay, so this constructor is done eagerly initialize now spring will say okay, is there any other class for which I need to create eagerly initialize?
Yes, test controller two, it will see that okay, it is singleton, it can be do eagerly initialize. So what it will do is test controller to instance initialization. Test controller to instance initialization.
Now the second step is inject the dependency. Now it says that user. So user is singleton means only one object would be created and it's already created.
Right? So the same object would be into the test controller to into the user the same object would be inserted. The same object would be inserted and after that it will reach out to post construct as there are no more auto wire. So test controller hashcode some new hashcode for this one.
It's hashcode this object hashcode and for this user it would be like the same this only so test controller object hashcode user is same so the same one so you got it like in a single turn only one object is created per IOC So this is just a different way of telling a class that it's a singleton. And when you start an application, it is eagerly initialized. And I have shown you with an example that this is how generally it resolves it create if the object is not created, it will create and once it is created, the same object is used everywhere.
and now if you are invoking an api let's say you are invoking this fetch user api or fetch user to api no object construction will happen it will simply invoke the particular api all the objects are created before itself we have seen okay so singleton is clear right cool Now there is one other important is something called prototype. Right? So what does prototype says that each time a new object is created? No matter if you are.
If a class is defined as prototype, new object is created each and every time. Very simple. Another important part, very very important, it's lazily initialized.
It's not eagerly initialized. So what lazily initialized means, when object is created, or you can say that when object is actually needed, actually needed, then only, it would get created. Okay, so when object is actually needed then only it's get created.
So I will explain you with this simple example. Right. So here, test controller one class, this is a rest controller. So there are some API's I have defined here. So this is how the prototype you can do at the rate scope and you can use this enum configurable bean factory scope prototype right.
So this class has this two injection dependencies one is user one is a student. Let's see a student first. So a student is a component and there is no scope means it is a Singleton.
Ok, very simple class and this student is dependent on user. So this is dependent on this user. Ok So and test controller is also dependent on user. So it is also dependent on this user. And what is this user class is prototype.
So now see here I can define a prototype like this using enum. Or you can use even a string like directly add a prototype in double quotes. So means user is prototype class scope and test controller one is also a prototype. So means every time a new object would be created for it. Student is singleton means only one object would be created in the system.
So now if I run the application, what would happen? So now let's say if I run the application, what is IOC will see that it will say, okay, rest controller, it would find it. Now it will see it's a scope. Hey, is it singleton? No, it's a prototype.
Prototype is lazily initialized, not at the time of application startup. So it will skip it. No, I won't create its object until it's not used.
Then it find let's say user user is component its scope is prototype okay this is also lazily I will not invoke it I will not create its object then it will find student okay this is singleton singleton is eagerly initialized I can create its object so first it will create student instance initialization so it will create student instance initialization and after this what would happen is it will look for dependency second step now the dependency is on user so it has to be resolved right so now user is prototype so now at this time user object is created because it is now it is required it is now used right so now user object would is initialized User is initialized. Does user has any dependency? No.
So its post construct would be called that its bean is properly constructed. User hash code. Some user hash code is got that this is the user object.
So this user object is now injected here. Now anymore auto-wire no, so now it's post construct will be involved. Student object hash code, some hash code, user object.
So this is the user object would be seeing here. So this is student object hash code and this user object which was created. This is what created right?
So this is injected here. Okay. till now all done right so now application got started properly now what would happen let's say you hit the api fetch user so fetch user is here this api you hit now when you invoke this api you know that This object would be created by IOC, right? So this is a prototype.
So means IOC has to create a new object of test controller, right? So it will create call its constructor test controller one instance initialization. So Till here we have seen application started. Now we hit the API.
So test controller one instance initialization. So what would happen after this, it will look for dependency resolution. First user So user is marked as prototype.
I told you that prototype means every time create a new object. Even though user object is already created and injected here in the student. But here now this is also again object requested for in test controller new object would be created.
So for user User new object would be created. So with this hash code earlier when a student created it was this hash code, right? So now here if you see user is created with different different object is created for the user.
Ok, why because it's a prototype then a student a student is Singleton so means only one object so it was eagerly initialized. So whatever the object was There it would get injected here. So whatever the hash code of a student was there The same ultimately got injected here also.
So 2092450685 So because it's a singleton. So same object is used in test controller 1 dependency. But for user a new object is constructed. Not this one. Because it's a prototype.
Because user is prototype. Every time new object is constructed. Right?
So you understand like every time new object is constructed if you hit this API can you just check one more time if you hit another time fetch user what would happen? If you hit another time what would happen? Since this class is marked as prototype a new object would be constructed for this so you will see one more like test controller one instance initialization one more object would be created.
Okay, so prototype is very simple every time new object is constructed and it's lazily initialized. Third is request. This is where ultimately confusion comes in because that's where one more things comes into the picture when I show you this part. this proxy mode. So this proxy mode also comes into the picture here and that's what make engineers get confused with this request.
Request Cisco. So what does it mean? New object is created for each http request.
For each http request, let's say fetch user. This is one http request. new object will be created for all the classes which are marked as request. And if in this API, if a particular object is required four times, we will not create four objects, only one time. Let's see that with an example.
And again, it is lazily initialized. So example is very simple. Again, I have created a test controller class. Right, so it has one this API and I have marked this as request.
This has two dependency one is on user one is on student. So let's see user first. So user also I have marked as request, right? So means for each HTTP request a new object has to be created.
No dependency on this one. And for the student. I called it as a prototype means every time no matter what every time new object should be there and it has a dependency on user so now let's see that when you start an application what would happen and when you invoke this http api what would happen how this dependency resolution happen and the scopes comes into the picture so when you start an app application, IOC will look for all the component at the right rest controller and try to create a bean.
So this it would find test controller one scope is request. So this is lazy initialize, nothing would happen. Then it next goes to student it found this at the right component. Scope is prototype again a lazily initialize nothing will happen. Then it will look able to see user because it is marked as at the right component.
But again, its scope is also request which is lazily initialized so no object is created at the application startup so at application startup here you see that started springboard application but no object is created okay makes sense now i am hitting the api fetch user the first time http request is coming now http request is coming now what would happen So it has to create an object. So this is request right? So I called fetch user.
So now with for this HTTP request first test controller object would be created. Test controller one. Test controller one instance initialization. Okay, this will get printed.
Then second it will look to resolve the dependency. So it will goes to the user first. User is also marked as request.
So means only one instance or new instance should be created for each request. So for this request is there any user request now? No, so it will create new object user initialization. so user initialization would happen.
Any dependency no. So post construct would be user object hash code. So some hash code would get come here. Okay.
So user will get injected here. After that it will resolve student. Student is prototype. No matter whether this same request, different request, new object has to be created.
So student. Student instance initialization. Now it will go and resolve the dependency.
It says that user. Now here if you see that user is marked as request. One object per request. So one object is already created.
So student will use this. No new object would be created. So student will use this user. right and student hash code so his hash code will come and what would be the user it's gonna use this user hash code so like this so this is the will expectation so test controller initialization happen so test controller ultimately goes to our user Right, so we have seen that we have seen that user user object created with this one.
And this got injected into this test controller. Now then a student. So student is prototype. So new instance would be created.
And the student is dependent on a user. And user is marked as request right so same object would be used. Right the same thing is happening which we have seen with diagram. So you got it right.
And this ultimately the test controller. Has this user. And this student object.
Okay. So this is if this is clear if this is clear the same thing is actually printing in the logs actually. Now what would happen if the second time you are hitting the API?
When the second time you are hitting the API what would happen? So till here this is first call. Right this is first call.
Now from here. Now from here second call happening this now when the second call happening again I have also copy pasted the same diagram here so that I don't have to scroll much. So this is request right so now second request is coming so means a new object would be created for this one.
So, it goes to again auto wired user, user is again request a new object would be created for this one. Student is anyway prototype doesn't matter right it will use it will create a new object itself. So, I will show you that.
Test controller instance initialization. So now here if you see when I hit the second time it is trying to create a new bean for the test controller one. Then it goes to the user and it create a new object for the user.
Earlier was this now it's a different object because user is marked as request and this is the new http request. Then it goes to the student, student is prototype so no matter same request whatever new object would be created. And then test controller, in the test controller it has an object and student right. So now here if you see it has this user. and student also has the same user.
So in the one request one HTTP request no duplicate objects is created only one time so test controller class student class both wanted user object so user is created only one time double eight nine to nine right the same double eight nine to nine so both test controller and student is using the same user class okay and each http request a new object is created I hope it's clear what does it HTTP scope request means. Now the problem comes in can you answer me this one? Consider this below request.
I have a test controller which I marked as singleton. I have a class user which I marked as scope request. So test controller one is dependent on this user. What would happen?
Okay so our basic understanding now is that singleton is eagerly initialized request scope is Lazy plus it is attached with HTTP request, right? Attached with HTTP request. So when you start an application, so IOC will see that, okay, rest controller.
This is singleton. So I can do legally initialize. So it will try to create its object.
So, what it will do is test controller one instance initialization test controller one instance initialization. Now it will try to solve this dependency it goes to the user. Okay, it say that hey user.
What is your scope? It's a request Is there any during application startup? Is there any active HTTP request is present? No, because the application is starting there is no HTTP request.
So The spring will not create its object and that's why it will get fail error creating bean Because it won't be it so the bean fail a bean creation fail for this Because this dependency is not not resolved because scope for this user is request and request is tied up with an HTTP request during eagerly initialization application startup. There is no active HTTP request which I can bound to. So how do you resolve this? The question comes if you have any class which is singleton and it wanted to access or it has a dependency on a class which is a scope request. How do you resolve this?
Because during eager initialization it will fail. So there is something called proxy mode. So in your user class, which is request, scope is request.
If you put a proxy mode, like, like say. scope proxy mode target underscore class. So if you use this what you are telling to spring boot is that hey create a proxy object at the time of eagerly initialization even though there is no HTTP request present.
You can create one proxy object of it like dummy object of a user and use it for your object creation, bean creation. But when ultimately you're going to invoke me, right, then you can create a real object and type. up with the HTTP request.
So I'll show you with an example. Now the same example, but I have just added proxy mode here and started the application. Now what would happen?
IOC will see this singleton. Test controller one instance initialization test controller one instance initialization. Now it has a dependency on user.
So generally it should be like user initialization printing right? But no this user is request scope. It should be with the HTTP request, but I have put a proxy.
Okay, if there is no HTTP request present, create a dummy object. So what it would is create one dummy object, dummy user object, and insert it here inside a user. So, here if you see there is no user initialization call means user object is not created, but somehow dummy object got inserted into.
this one so it created inserted it and then post construct here user object some hash code comes so some dummy object created so this success the bin creation of test controller now got success now when you hit this api now when i am hitting this api so now this is one http request So now this API what would happen is this actual dependency would get resolved. So now here if you see when I hit this API at this point of time, it is actually creating the user initialization. User initialization, there is no dependency, user object and now this user object ultimately get inserted into here. Content update. So you got it like what is request and the lot of confusion happened with there.
So this request you understood that it is always tied up with HTTP request and if you are trying to create it, let's say you are singleton or any application startup you are trying to access this class. You have to use proxy otherwise it would fail. Then there is something called session very very similar to http request but only thing is object is created for each http session.
You know that once http session is created http session created you can call many http calls so http request 1 http request 2, request 3, request 4 so on till you don't end http session right so now its not tied up with each http request one object is created per each http session so it is lazily initialized Right and generally when user access any endpoint right first session is created generally. Right and it's remain active till it do not expire and you can so there might be some default expire time. You can also configure the expire time in the application dot properties.
I think there is some like servlet dot session. session.expiry some time. You can check this one but there is certain property which can tell, which tells that this session should get expired after this time. Otherwise it's been used some default time. Right?
So I have created one test controller one. Now I can you can use this scope like this session. It is dependent on this user.
So user is singleton. Right, very basic. Now what would happen when you start an application?
So when you start an application, this is lazily initialized. So session so nothing will happen for this. IOC will see that okay, it is singleton lazy initialization is possible.
So user is initialized. There is no dependency. So user object hash code will also get printed. User initialized user hash code printed. Now the first I am hitting this fetch user.
So I am hitting this so HTTP session would get created. Right the first time it is creating so its object would create it. Test controller one instance initialization. So test controller one instance initialization till here we have seen. After that.
any dependency yes it has dependency so it will see that okay this is singleton only one object should exist per ioc right so whatever the same object that will get injected here and then it will goes to the post construct so test controller one hash code and user hash code so whatever the user hash code same would come here because the same is got injected here you So test controller hash code whatever the object is created and inside this test controller the dependency of user is the same one because this is singleton one nine okay now I am calling the API again Same, so session is still running. HTTP session is created when you call the first time. So it is not yet ended.
So it is still in running. So now I call the fetch user again. So it is session. So it will not create new object because this is just a new HTTP request not a new session.
HTTP session is still valid. It's not a new session. So will it create new object?
No, it will not create new object. So it just called the API. No object creation happened.
Now here in the third I am calling logout API which ends this session. Which end http session. So here if you see this is the logout API I have called.
In this http servlet I specifically get the session and make it invalidate manually. Right? You can also automate it using configuration but just to demo it I manually invalidated this session.
So, now in the logout I end the session. Now I am calling the API again. What would happen? Now you are calling the fetch user API again.
So now it will create a new session again because there is no session exist. So new session again means new test controller one instance initialization. here test controller 1 instance initialization after ending new object and this depend on user but user is singleton so same singleton object would be used no new object should get created.
So what initially user was created at 619. It's the same because it's a singleton. But new object for test controller is created because old session was closed and new session is started. So you got it session also.
So these are the main scopes and there is something called application. So application is like very very similar to singleton. Singleton is like one object per IOC.
Application says that one object within different IOCs, let's say there are 3 IOCs running IOC 1, IOC 2, IOC 3 there are 3 IOCs are running, to be honest in this 9 years of experience I haven't find out this use case, like 1 IOC is running at a time but still, it's better to understand this, when multiple IOCs are running and you want that only one object is shared among them then use application right singleton just make sure that in one ioc object only one object is constructed application make sure that one object across multiple iocs okay so but that's why i haven't included it because i don't think it's very much popular but yes it's better to learn it but that's just my opinion Okay, so see you guys. I hope you will find this useful. Please do share it with your connection if you like it. Thank you. Bye.