How to initialized java bean with annotation in spring framework? - spring

I have a Java bean:
public class User{
private Integer userid;
private String username;
private String password;
private boolean enable;
//getter and setter
}
I am able to initialize it as a spring bean at context.xml via:
<context:component-scan base-package="com.myCompany.myProject" />
But I don't want initialize it in xml. How can I initialize it with sring 3 annotation. I tried with the following:
#Component
public class User{
private Integer userid;
private String username;
private String password;
private boolean enable;
//getter and setter
}
But the above did not work for me. Any ideas?

I believe that is because you have enable component scan on the package com.myCompany.myProject and not on the package com.myCompany.myProject.db
Change your scan definition to this : <context:component-scan base-package="com.myCompany.myProject.db" /> (or add a new one, if you want classes from the other package as well) and you can remove the bean definition from XML and have your annotation work for you.
Silly, but still, ensure that the #Component annotation is that of Spring's. I've at times faced this silly issue of defining an annotation that is actually not from the desired library (owing to the same name of the annotation, by different libraries in my classpath).

You need to add
<context:annotation-config />
With this XML my Autowiring works flawless:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<context:annotation-config />
<context:component-scan base-package="com.vanilla.example"></context:component-scan>
</beans>

you shouldn't need to have both declared.
Use of context:annotation-config allows for autowiring of beans via annotations etc
Use of context:component-scan provides everything that context:annotation-config, but allows for autodiscovery of beans. The package you supply in context:component-scan will scan that package plus all sub packages.
Hope this helps

Be sure that the "User" class is the package or sub-package of the
"com.myCompany.myProject".
You do NOT need to include <context: annotation-config/>, it is
included with component-scan.
The bean is available with the name "user" by default, unless you
specify the bean name with #Component("myBeanName")
Once that is done, you can autowire the bean into another with:
#Autowired
User user;
OR
#Inject
User user;
NOTES:
#Inject is a javax.inject annotation the injection is NOT required.
#Autowired is a Spring annotation and the injection is required.
#Autowired can be used in one of the following ways:
just above the member variable
constructor that accepts a User bean
setter that accepts a User bean.

I have configured my xml file in this way , this will help you to solve the problem.
For Context-componentscan use
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.java.Controllers"></context:component-scan>
<context:component-scan base-package="com.java.dao"></context:component-scan>
<context:component-scan base-package="com.java.bean"></context:component-scan>
Or else u can use
<context:component-scan base-package="com.java.*"></context:component-scan>
next for annotation driven use
<mvc:annotation-driven />
For resources use this
<mvc:resources location="/" mapping="/**"/>

Related

Set resource annotated field of a class in unit tests

I have a class.
public class Definitions{
#Resource(name="schemas")
private Collection<String> schemas;
}
This class is initialized via spring.
Spring file:test.xml
<util:list id="schemas">
<value>"A"</value>
<value>"b"</value>
</util:list
<bean id="Definitions" />
Is there some way I can insert value to private field schemas(annotated with Resource) in my unit test without using spring. I tried using setting private variable via Reflection but that also did not help(probably due to security restrictions).
Even using spring,
ApplicationContext context = new ClassPathXmlApplicationContext("test.xml");
It is not able to load schemas in Definitions bean. I get "NullPointerException" while accessing schemas.
Add a setter for it:
public class Definitions{
private Collection<String> schemas;
#Resource(name="schemas")
public void setSchemas(Collection<String> schemas) {
this.schemas = schemas;
}
}
This is the principle of dependency injection: you inject dependencies manually, vis constructor or setter injection, in your unit tests.
Try to do the following:
Insert the list in you spring.xml:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<util:list id="listTest">
<value>Valor 1</value>
<value>Valor 2</value>
</util:list>
</beans>
Reference the list in your code:
#Resource(name = "listTest")
private List<String> listTest;
I've tested here and it works fine on Spring 4 and 3, there's no need to implement a setter method.

#Autowired doesn't work if component-scan removed

I'm facing the problem, that the annotation #Autowired doesn't work anymore (in all Java classes that uses this annotation) if I remove the component-scan tag from config
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="efco.auth" />
here are some beans...
There is only one class in the efco.auth package, and this one has no relation to the following class EfcoBasketLogic.
and a class that uses #Autowired:
package efco.logic;
public class EfcoBasketLogic extends BasketLogicImpl {
#Autowired
private EfcoErpService erpService;
This Bean is defined in an other spring config file:
<bean id="BasketLogic" class="efco.logic.EfcoBasketLogic">
<property name="documentLogic" ref="DocumentLogic" />
<property name="stateAccess" ref="StateAccess" />
<property name="contextAccess" ref="ContextAccess" />
</bean>
As you can see, erpService is not defined. The other three properties are on BasketLogicImpl and have setters.
What I'm doing wrong?
As Tomasz says, you need <context:annotation-config/> for #Autowired to work. When you had <context:component-scan/>, it implicitly included annotation-config for you.
Adding either autowire="byType" or autowire="byName" to your bean declaration should do the job.

Spring 3 doesn't fill #Value annotated fields with property values

I want to fill some fields with the property values using Spring 3.1.1 but the fields always remain null.
Added to the applicationContext.xml
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.0.xsd">
<util:properties id="props" location="classpath:application.properties" />
application.properties:
myProp=value
java class:
#Value("#{props[myProp]}")
private String myField;
But on bean creation myField is not filled with "value" from the properties file but remains null.
Also tried (without success):
#Value("#{props.myProp}")
private String myField;
and
#Value("#{myProp}")
private String myField;
The application.properties file is found because I got an "file not found" after I moved it.
Here the stacktrace: http://pastebin.com/5A8i5gF8
What do I have to change?
Have you declared or configured your class which has myField class variable into applicationContext.xml?
try with the char $ instead of #
example:
#Value("${myProp}")
private String myField;
You may be missing <context:component-scan/> or <context:annotation-config/> in your application context - it registers a bean called AutowiredAnnotationBeanPostProcessor which actually processes the #Value tag. If it is not there, just add one of the two and it should work.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:cxf="http://cxf.apache.org/core"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://cxf.apache.org/core
http://cxf.apache.org/schemas/core.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.0.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<context:annotation-config />
<context:component-scan base-package="my.base.package" />
<util:properties id="props" location="classpath:application.properties" />
... <some beans (transactions, persistence, ws-endpoints) not used by the test class > ....
<cxf:bus>
<cxf:features>
<cxf:logging />
</cxf:features>
</cxf:bus>
</beans>
Sorry for posting new answer but in comments code doesn't get formatted properly.
#Repository
#Qualifier(value = "myStrategy")
public class MyClass implements MyInterface {
#Value("${prop1}")
private String prop1;
MyClass(){
<prop1 is passed to a method to set a config.>
}

Spring's #Autowired doesn't inject dependency

I have a project that consists of various modules.
Basically, I've worked with Spring MVC & JUnit 4, and everything was working good.
But Now, I added few classes which aren't related to testing or MVC, and the #Autowired annotation doesn't inject objects to them.
The same objects are injected to the MVC and JUnit classes, so I realy confused.
This is the Spring Context XML:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<context:component-scan base-package="com.justic.more" />
<mvc:annotation-driven />
<context:annotation-config />
<bean id="monkDAO" class="com.justic.more.data.monkDAO" />
<bean id="BidDAO" class="com.justic.more.data.BidDAO" />
</beans>
The Class that I want to inject to:
#Component
Public Class Tesser {
#Autowired
MonkDAO monkdao;
...
blablabla
...
}
From the chat with OP it became clear that he created the object like Tesser tesser = new Tesser() instead of injecting it into the test class.
Spring has no chance to autowire dependencies in beans that it does not create itself.
The solution is to autowire the Tesser object into the test class so Spring can inject the dependencies.
#Autowired
private Tesser tesser;
#Test
public void testSth() {
assertTrue(tesser.someBoolReturningMethodUtilizingMonkDAO());
}
Add qualifiers:
#Resource(name = "monkDAO")
If you start with annotations, go all the way.

Adding Xml configurations to a Spring ApplicationContext that is already setup

I was wondering if there is a way to do the following:
have my wep app startup with its servle-context.xml
When, at a certain point, one particular bean in this xml config is instantiated, it will add it's own xml configuration to the application context (or to a child perhaps?).
I'm asking this because I want to pack some functionality in a stand alone library and then reuse it in different projects, so that initializing a bean of this library will load its xml config.
What I wrote is:
public class IrisLibHelper {
ApplicationContext context;
ApplicationContext irisContext;
#Required
#Autowired
public void setContext(ApplicationContext ctx){
this.context = ctx;
ClassPathXmlApplicationContext xap = new ClassPathXmlApplicationContext(ctx);
xap.setConfigLocation("classpath:com/dariodario/irislib/xmldefs/irisconfig.xml");
this.irisContext = xap;
}
public ApplicationContext getIrisContext() {
return irisContext;
}
public void setIrisContext(ApplicationContext irisContext) {
this.irisContext = irisContext;
}
}
and the irisconfig.xml is:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<!-- <context:component-scan base-package="com.dariodario"></context:component-scan> -->
<mvc:annotation-driven />
<bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"
p:synchronizeOnSession="true" />
<context:component-scan base-package="com.dariodario.iris.controllers"></context:component-scan>
</beans>
The problem is that it doesn't seem to scan the com.dariodario.iris.controllers package, in fact the controllers don't get mapped! (I've logging debugging on and I don't seen anything).
Why not use the tag <import resource="classpath:applicationConfig.xml" /> ? You can load a spring configuration file which is in jar. In a jar, the Spring XML configuration is always at the root. But if not, you can use this notation: <import resource="${configurablePath}/applicationConfig.xml" /> where configurablePath can be reach by a property place holder or other.
I think this way is cleaner than merging two Spring context.

Resources