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

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.>
}

Related

Spring Java Unit Testing; How do i initialise a beans property at the point of #BeforeClass?

In a test class I have a static
.
.
.
#BeforeClass
public static void setUpBeforeClass() throws Exception {
//Set utility beans property
// Not a System property.
}
At this point, How do i initialize or set the property of a bean ?
Thanks
If you want to setup in setUpBeforeClass() method, this is impossible. But if you just want to setup it and you're using xml configuration this is an other way.
Generally speaking, you need to create an applicationContext.test.xml which overide the applicationContext.xml. Use it in JUnit instead of applicationContext.xml
For e.g. here is your applicationContext.xml
<?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:annotation-config />
<bean name="utilBean" class="UtilBean">
<property name="prop1" value="1"/>
</bean>
<bean name="anotherBean" class="AnotherBean">
<property name="propAnother" value="10"/>
</bean>
</beans>
For setting the 'prop1' with 2 in 'utilBean', you should create a new applicationContext.test.xml like this:
<?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">
<!-- import the original one -->
<import resource="classpath*:applicationContext.xml" />
<!-- Override utilBean -->
<bean name="utilBean" class="UtilBean">
<!-- Override prop1 value -->
<property name="prop1" value="2"/>
</bean>
</beans>
Then in your JUnit class, use applicationContext.test.xml instead of applicationContext.xml
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = { "classpath*:applicationContext.test.xml" })
public class JunitTest {
// your tests
}
Your prop1 value of utilBean is set with '2' in your JunitTest, but in your original process it will always be '1'
You can also use antoherBean in your JUnit, it's 'propAnother' value equals to 10, both in JUnit and in original process.
Sorry I didn't saw comments... In your case, override the configuration in this way:
#Import(ApplicationContext.class)
#Configuration
public class TestApplicationContext {
...
}
Then override your bean. Use this configuration class instead of the original one in your JUnitClass
In your test class declaration:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration
public class MyTest {
//... your tests
#Configuration
public static class Config {
//your configuration for the test
}
} // end of test class

Spring AOP Pointcut not called

i work with JSF 2.2 + Spring framework 3.2.4
So, i have this applicationContent.xml
<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:aop="http://www.springframework.org/schema/aop"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<aop:aspectj-autoproxy proxy-target-class="true" />
<tx:annotation-driven transaction-manager="transactionManager"/>
<context:annotation-config/>
<context:component-scan base-package="com.vulcan.controller" />
<context:component-scan base-package="com.vulcan.service" />
<context:component-scan base-package="com.vulcan.dao" />
<context:component-scan base-package="com.vulcan.spring.aop" />
.....
Then i have aspect component
in
package com.vulcan.spring.aop;
#Aspect
public class LoggingService {
private Log log = LogFactory.getLog(this.getClass());
#Pointcut("execution(* *.*(..))")
protected void loggingOperation() {}
#Before("loggingOperation()")
public void logJoinPoint()
{
System.out.println ("Hello");
}
....
With this type of execution i assume this pointcut will be triggered on every methods. But the problem is, this pointcut isn't triggered ? Any idea why ? Thanks
FYI, i using glassfish 4, and when i deploy my web app i didn't receive any error configuration. So i assume my configuration is fine.
#Aspect annotate classes aren't automatically detected by Spring and because it isn't detected it isn't known to the <aop:aspectj-autoproxy /> beans. So basically there is no aspect.
Either add #Component to your #Aspect annotated class(es) so that Spring can detect and use the aspect.
#Compopnent
#Aspect
public class LoggingService { ... }
or declare the aspect explictly in your xml file
<bean class="LoggingService" />
Either way the aspect will be picked up by the <aop:aspectj-autoproxy /> beans and the advice will be run.
Try using execution(* *(..)).

#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.

How to initialized java bean with annotation in spring framework?

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="/**"/>

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