Spring:autowired field is null - java

I need to wire external lib class to my bean,in order to use it as singleton.
.xml config:
<bean id="myBean" class="com.my.MyBean">
<property name="someLib" value="com.ExternalBean" />
</bean>
java bean:
#Service
public class MyBean {
#Autowired
private ExternalBean externalBean;
public void setExternalBean(ExternalBean externalBean) {
this.externalBean = externalBean;
}
Further I use wired variable externalBean in public method ,in order not to instantiate it in every method call.
Problem is it null.
Do I wire bean correctly?What is mistake.

You have to define the external class as a bean in order to make #Autowired work.
<bean id="externalBean" class="some.external.package.ExternalBean">
</bean>
<bean id="myBean" class="com.my.MyBean">
</bean>
Also, if you use #Autowired you don't need the setter for it.

loodakrawa is right. A second thing that can cause a problem is, that you have a xml bean declaration for myBean and additional annotated the bean with #Service. I guess this will cause trouble as soon as use enable component scan.

I think that the better ide ais to use context path scan:
<context:component-scan base-package="some.external.package">
</context:component-scan>
Make sure that all these classes are within the package. Then mark both classes with one of the Annotations (#Repository, #Service, #Component).
One of the benefits, no setter required.
P.S: If you re using scan base you don't need to declare class as bean, annotations are enough

Related

how to inject parent class property with spring annotation

parent class is like this:
public class BaseDAO{
private DBRoute defaultDB;
public DBRoute getDefaultDB()
{
return this.defaultDB;
}
public void setDefaultDB(DBRoute defaultDB)
{
this.defaultDB = defaultDB;
}
}
I have create beans like below:
<bean id="adsConfigDB" class="net.flyingfat.common.dbroute.config.DBRoute">
<constructor-arg value="adsConfig" />
</bean>
<bean id="adsBizDateDB" class="net.flyingfat.common.dbroute.config.DBRoute">
<constructor-arg value="adsBizDate" />
</bean>
I want to inject superclass property defaultDB in subclass through byName, not byType, which is in subclass inject defaultDB using adsConfigDB or adsBizDateDB. Is there any way to do this with spring annotations? I already tried Autowired or Resource with constructor which doesn't work. By the way, I already know this can be done using XML.
#Qualifier annotation – This annotation is used to avoid conflicts in bean mapping and we need to provide the bean name that will be used for autowiring. This way we can avoid issues where multiple beans are defined for same type. This annotation usually works with the #Autowired annotation. For constructors with multiple arguments, we can use this annotation with the argument names in the method.
Your code will be like this..
#Autowired
#Qualifier("adsConfig")
private DBRoute defaultDB;

Why is a Spring ProxyFactoryBean implicit definition working?

I have the following definition:
<bean id="myInterceptor" class="info.fastpace.MyInterceptor"/>
<bean id="alikProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="myClass"/>
<property name="interceptorNames">
<list>
<value>myInterceptor</value>
</list>
</property>
</bean>
I have 2 classes defined: MyInterceptor and MyClass.
The peculiar thing is that Spring knows to invoke the interceptor before invoking class MyClass (capital M), even though the class isn't configured in the commonContext.xml file. The only hint is the myClass (lowercase m) in the proxy bean definition.
When removing the alikProxy bean definition, the interceptor isn't invoked.
How does Spring know to invoke the interceptor for MyClass using an undefined myClass ref?
Looks like you defined a bean of class MyClass, but did not give it any name explicitly, so Spring just gave it a default name myClass, based on class name MyClass.
Update
I suppose somewhere in your Spring context xml you have <context:component-scan> element.
Here is a fragment of book Spring In Action, 3rd Edition:
By default, <context:component-scan> looks for classes that are annotated with one
of a handful of special stereotype annotations:
#Component—A general-purpose stereotype annotation indicating that the class
is a Spring component
...skipped...
For example, suppose that our application context only has the eddie and guitar beans in it. We can eliminate the explicit <bean> declarations from the XML configuration by using <context:component-scan> and annotating the Instrumentalist and Guitar classes with #Component.
...skipped...
When Spring scans the com.springinaction.springidol package, it’ll find that
Guitar is annotated with #Component and will automatically register it in Spring. By default, the bean’s ID will be generated by camel-casing the class name. In the case of Guitar that means that the bean ID will be guitar.

Spring Controller Injected Properties Turn Null

I have a situation very similar to "Inject a file resource into Spring bean"
I have a controller that uses some .jasper compiled files and I am declaring them as such
//...
#Controller
public class InvoicingController {
private Resource quoteTemplate;
...//
And in my context configuration file
<bean id="invoicingController" class="x.x.InvoicingController">
<property name="quoteTemplate" value="/WEB-INF/jasper/Quote.jasper" />
...
I set a breakpoint on the setQuoteTemplate() function and it is being called and the Resource object is being set properly when I initialize the container. However when I actually hit the controller quoteTemplate is null.
I am under the understanding that Controllers are singletons and unless there is a gap in my understanding I am not sure why the values that are set during the container's initialization become null when I hit a url that the controller handles.
EDIT:
Thanks #Sotirios Delimanolis
I ended up declaring beans as such:
<bean id="quoteFile" class="java.io.File">
<constructor-arg value="resources/jasper/Quote.jasper" />
</bean>
<bean id="quoteTemplate" class="org.springframework.core.io.FileSystemResource">
<constructor-arg ref="quoteFile" />
</bean>
And then #Autowireing the dependencies as such
#Autowired #Qualifier("quoteTemplate") private Resource quoteTemplate;
#Qualifier is used because I have multiple Resource implementation classes declared as beans and this makes sure the correct one gets used.
You can't be using both the #Controller annotation and a <bean> declaration, unless you don't have a component-scan. You will end up with two bean definitions where the last one will overwrite the first one.
In this case, it seems like the component-scanned bean definition comes second and overwrites the bean you created with <bean>.
Choose which bean declaration method you want to use.

Declaration of beans in applicationContext.xml

I have a question regarding declaration of classes in applicationContext.xml
In applicationContext.xml do we need to specify all the classes from the application?
E.g.
In my small web application I have a Entity class, Service class and DAO class. So currently it is defined as
<!-- Beans Declaration -->
<bean id="Employees"
class="net.test.model.Employees" />
<!-- User Service Declaration -->
<bean id="
EmployeeService" class="net.test.employees.service.EmployeeService">
<property name="employeesDAO" ref="EmployeeDAOImpl" />
</bean>
<!-- User DAO Declaration -->
<bean id="EmployeeDAO" class="net.test.employee.dao.EmployeeDAOImpl">
<property name="sessionFactory" ref="SessionFactory" />
</bean>
So if I have multiple entity, service and dao classes do I need to mention all those classes in applicationContext.xml?
Any insight into this is highly appreciable.
Regards
Update 1
ManagedBean
#ManagedBean(name="empMB")
#Named
#Scope("request")
public class EmployeesManagedBean implements Serializable {
and I have Inject annotation
#Inject
EmployeesService employeesService;
In EmployeesService I have annotations like
#Named
public class EmployeesService implements IEmployeesService {
#Inject
EmployeesDAO employeesDAO;
#Override
public List<Employees> getEmployees() {
return getEmployeesDAO().getEmployees();
}
and finally in applicationContext.xml I have
<context:component-scan base-package="net.test" />
Now the problem is when I run my application I am getting
java.lang.NullPointerException at
net.test.managed.bean.EmployeesManagedBean.getEmpList(EmployeesManagedBean.java:53)
What am I doing wrongly to get nullpointer exception?
In applicationContext.xml do we need to specify all the classes from
the application?
No. Declaring model classes like your net.test.model.Employees is pointless unless you need a prototype to work with, something like initializing its values, but you can do this directly in the class and just instantiate it.
So if I have multiple entity, service and dao classes do I need to
mention all those classes in applicationContext.xml?
As I explained before, entity classes no. Services and DAOs are ok because most of the time you need DAOs injected to the Services (and that's the point of DI). But of course, if you create 3 DAOs and you want them to be injected in your 3 Services, then mention them in your Spring XML Bean Definition file (what you call applicationContext.xml).
But one thing, you may want to use package scanning autodetection and annotation based config to avoid writing everything in your Bean Definition File.
The bean declaration in the application context is to register the bean in the application container.
If the bean is not registered, the container wouldn't be able to dependency inject any instance of that class, or apply interceptors to the object of the class.
So unless the reference of bean is not required for any task like intercepting it or inject it, or create default singleton object of it, there is no need to declare it in the applicationContext.xml
Hope this helps.
Ideally yes, another way can be using Spring Annotations so that you don't to add multiple entries in xml.

benefit of #Autowired annotation in Java

Maybe, because of my wrong English, I couldn't understand the benefit of using #Autowired annotation.
According to the tutorial we can simplify the first(I.) case to second case(II.) by means of #Autowired.
My question is, what is the meaning of the #Autowired ? Because it doesnt tell any more, since without using #Autowired the compiler can figure out that "EmpDao emDao" and "EmpManager" are closely related according the declaration.
code cited from here
I.
<bean id="empDao" class="EmpDao" />
<bean id="empManager" class="EmpManager">
<property name="empDao" ref="empDao" />
</bean>
public class EmpManager {
private EmpDao empDao;
public EmpDao getEmpDao() {
return empDao;
}
public void setEmpDao(EmpDao empDao) {
this.empDao = empDao;
}
...
}
II.
<context:annotation-config />
<bean id="empManager" class="autowiredexample.EmpManager" />
<bean id="empDao" class="autowiredexample.EmpDao" />
import org.springframework.beans.factory.annotation.Autowired;
public class EmpManager {
#Autowired
private EmpDao empDao;
}
#Autowired is spring-specific. #Inject is the standard equivallent. It is an annotation that tells the context (spring, or in the case of #Inject - any DI framework) to try to set an object into that field.
The compiler has nothing to do with this - it is the DI framework (spring) that instantiates your objects at runtime, and then sets their dependencies at the points you have specified - either via XML or via an annotation.
I agree it is a possible scenario for a DI framework to try to inject dependencies into all fields, even if they are not annotated. (And if you want to exclude a particular field, to annotate it). But they chose the other strategy (configuration-over-convention). By the way:
if using xml config and choose some form of autowiring, the dependencies of the bean will be automatically autowired without the need to specify anything
you can specify per-context autowiring settings.
When the server bootstraps itself. It finds
<context:annotation-config />
in the application context and then goes through the classes defined in the contexts. If there are any beans that are autowired, it injects that into the class by referring the context file.
Basically, it promotes convention over configuration. That's what most frameworks do these days to reduce the development time.
the #Autowired Spring annotation tells Spring to for a bean named 'empDao' and inject it into the EmpManager class, without you having to add the empDao bean as a property in your spring config file.
#Autowired tells Spring to find a bean of the declared type and wire in that bean, rather than requiring an explicit lookup by bean name. It can, under certain circumstances, make configuring applications easier if you only have one implementation of your types in a given Spring context.

Categories

Resources