Instantiating spring bean objects - java

I've been playing with Spring and had a quick question...
I have a loop within class A which instantiates new objects of class B. To do this I've used the new operator however I cannot reference any Spring beans injected into instances of class B as I get a null pointer exception. I think I understand that this would be due to spring not managing these instances as beans and therefore not being able to manage the lifecycle however I was just wondering what the best way to go about creating multiple instances would be i.e. should I used appContext.getBean("beanA"); ?

First - are right with your assumptions. Using new means spring doesn't manage the object.
Solutions can be:
appContext.getBean("beanA"), where the bean is of scope "prototype". You obtain the appContext by injecting it, or by implementing ApplicationContextAware
using #Configurable and apsectJ weaving. That way even objects instantiated with new become managed by spring (the weaver plugs into the compiler or the vm)
using a lookup-method - it's the same as the first option (again requires prototype-scoped bean), but you get a method of your class that returns a new instance each time you call it.
Normally, however, you shouldn't need that. In the rare cases you do, I'd recommend the 3rd option.

Related

What is the difference between autowiring and object creation?

What is the difference, if I autowire a class and provide value and instantiate an object of class and provide some value?
For example-
#Autowired
private UserService userService;
userService.findUser(userName, password);
And
User user = new user();
userService.findUser(user.getuserName(),user.getpassword());
What is the difference in Autowiring and sending the data and instantiating the object and sending the data to some service class?
I'm trying to clarify the concepts in spring.
When you use #Autowired you are leaving it up to the Spring framework to find and instantiate the userService. This is usually controlled through some configuration file or some other configuration, which allows you to change the behaviour of your application without changing the code itself.
On the other hand, when you instantiate the object yourself, you are specifying which object you are after and what type of class you want. This could leave you with less ambiguous code since you know what type of object is being initialized, but to make a change in your application's behaviour you would need to change your code.
In essence, the first option is less coupled than the second option, which is usually the recommended way of building things.
Your example doesn't make a lot of sense; this User class, which looks like some plain data object, isn't adding anything to the second snippet.
The idea of "autowiring" is that some class, like maybe a Web controller, will need a UserService in order to get its work done. When Spring autowires the UserService, it goes into the context and finds a matching object and provides it to the class that needs it. This is technically separate from creating the object.
That said, the best practice is to use constructor injection--simply declare the other objects you need as constructor parameters and annotate the constructor with #Autowired (or #Inject). Spring will know to look up all the dependencies you need and call the constructor with them. This means that it's also very simple to provide mocks of those objects for testing or development.
Well, the main difference is that in case u use #Autowired the object is also created, however, it's created by container and container decide when to do that.
I want to give you a simple example:
You have four classes 1,2,3 and 4. Three of them (1,2,3) uses the 4th. So, if you use new(), it`s hard to decide where to create object(in class 1, or 2, or 3, or even in each of them) of 4th class. Moreover, later you can delete class with object initialization and other 2 classes won't work (in case you created one object). Autowired annotation injects the object but you don't initialize object in class, so no problems appear
This is like the simplest answer.
the above answers are good i would like to tell a major difference between them .the purpose of autowiring is to avoid the dependencies between the class
if you are creating objects with new making a change to one class will effect all the classes.

Bean instantiation notification in Spring

I know Spring framework and have worked in it and have used ApplicationContext to instantiate and load beans.
Lets say I write the following piece of code
ApplicationContext context=new ClassPathXmlApplicationContext("appContext.xml");
Now, after the above statement, how do i get to know if the beans, that are defined in appContext.xml, has been instantiated and loaded by Spring?
Note : I want to know it before accessing any bean
Try retrieving one:
MyClass myClass = (MyClass) context.getBean("MyBean");
I agree with Reimeus, and #jbx's comment. If nothing is thrown you should be good to go. If you really want to be sure though, consider using a logger, or even some sort of AOP to trigger an event when a bean is created.
I think I know what you're getting at, and it's something that's hard for us to do as programmers. Dependency injection (What spring does by creating beans in an application context) takes away the step of explicitly creating beans (ie. "Thing something = new Thing()") and that can be frightening, especially in early development when not everything is working, and you're not sure why.
Your objects are instantiated. You've just got to trust that Spring is doing it's thing--it will let you know if it's not :D
(also check out the BeanFactoryPost processor http://javasourcecode.org/html/open-source/spring/spring-3.0.5/org/springframework/beans/factory/config/BeanFactoryPostProcessor.html , it will allow you to see what's there if you really want)

Keep track of all the classes that implement a particular interface?

It's difficult to explain what I really want. I have an interface which has a method getRuntimeInfo() which provides me all the runtime debug information for the variables of a class. I want to see the list of all the classes that implement this interface. I am using Java and Spring.
One way I can do this is to get all the beans from the Spring Context and check using the instanceof operator. But i wouldn't want to do that for obvious performance impacts. Do i have some other option?
What about this solution:
#Component
public class WithAllMyInterfaceImpls {
#Autowire
List<MyInterface> allBeansThatImplementTheMyInterface;
}
The List is only populated once (at start up) so it should not have a significant impact in the "normal" runtime performance.
Comment:
can you explain your code
You know Spring is a IOC Container. #Component tells Spring that it should create an instance of this class (a so called Spring Managed Bean). IOC means also that the Container is responsible to inject references to other instances (Spring Managed Beans). #Autowire (as well as #Resource and #Inject -- all do the same) is such an annotation that tells Spring that this field should be populated by Spring. Spring itself tries to figure out with what instances the field should be populates. A default technique that spring uses is by type this means that Spring inspect the type of the field, and search for matching beans. In your case it is a generic List - this is a bit special. In this case Spring populate the field with an list, where the elements are all beans that match the generic type.
How about the getBeansOfType method from ApplicationContext? It returns a Map of the beans implementing your interface?
http://static.springsource.org/spring/docs/1.2.x/api/org/springframework/beans/factory/ListableBeanFactory.html#getBeansOfType(java.lang.Class)

In simple layman's terms what does getBean do in Spring?

Consider a line of code like this
AutomobileDriver ad=(AutomobileDriver)appContext.getBean("increaseSpeed");
Assume there is an IncreaseSpeed class which inherits from AutomobileDriver class
What does getBean do? What is the main function of this?
In "simple layman's terms":
This assumes that Spring was told to create an object instance (possibly in an XML config file) that is identified (by Spring) as with the id "increaseSpeed" and has a class or parent class of AutomobileDriver.
You are asking the Spring context for a reference to (a) by default, the previously created object (this is called a singleton) or (b) a new instance of that object (prototype).
In Spring, you can define a bean and give it an id. Usually, Spring would prefer that you use dependency injection to access the bean. However, Spring provides getBean as another way to access a bean by its id.
Basically, your code will return an instance of the bean with id "increaseSpeed".
This code is requesting the bean named increaseSpeed from the Spring Application Context. Think of the application context as the pool of available objects, which has been configured from your Spring configuration XML. When the application context is started, it creates the beans in the configuration. This call simply asks for the one which is already there. The application context returns this "bean" as a java.lang.Object so you have to cast it to the appropriate type.
You might see this call as an entry point in a Spring application. This call is needed to get the first object out from the application context - from there, this object may have links to other objects which have been injected by Spring.
A bean is a component that provides some functionality, the name of the bean indicates that it would be increase speed.
Those components are registered in a context called 'application context' and can be looked up by name. So if you want to increase the speed look at your apps-context for something that could do this.
More tecnical:
http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/

Get access to all spring beans of a given type

I have a Spring application (Spring Batch not web application). In a test class, I want to grab access to all of my beans of a given type.
I understand that in Spring you should generally use IOC and let the container inject your beans. However in this case, I want to loop through a variable number of beans that extend a given class (org.springframework.batch.item.database.JdbcCursorItemReader), and do something (want it to be a unit/integration test that just connects it to the database and reads 1 row, so we can confirm at test time that all of the JdbcCursorItemReader in the system have valid SQL and row mappers).
Problem 1) I can only get beans one at a time. I can have my class implement BeanFactoryAware to get a reference to my beanfactory. Then I can do beanFactory.getBean("name"); to get access to a single bean. How do I instead get ALL beans? I can loop through and drop the ones that aren't the class I want.. but somehow I need a list of all beans the beanfactory knows about or something.
Problem 2) The bean I get back from the beanfactory is a proxy. If I try to cast and use my bean I get something like
java.lang.ClassCastException: $Proxy0 cannot be cast to org.springframework.batch.item.database.JdbcCursorItemReader
You can get around the first problem by using ApplicationContextAware instead of BeanFactoryAware. This will pass in the ApplicationContext, which has the getBeansOfType() method which lets you retrieve all beans that are of a given type.
The second problem is likely caused because something is creating AOP proxies around your JdbcCursorItemReader bean. These generated proxies will, by default, implement the same interfaces that JdbcCursorItemReader does (specifically, ItemReader and ItemStream). Your code should not try and cast to the class type (JdbcCursorItemReader), but to one of those interface types instead. It's usually possible to force the proxy to extend the proxied class directly, but without knowing anything about your setup, I can't help you with that.

Categories

Resources