I'm new to Spring. I read something about #Autowired. In the document, it seems when I use #Autowired, I have to modify the XML file, such as applicationContext.xml.
However, I read the code, and I just saw #Autowired in Java code, but I didn't see XML file at all. And it works well. How to use #Autowired, do I still need xml, if needed, how to use it?
Spring application can be configured using java. In that case you dont need application.xml.
#Configuration
public class AppConfig {
#Autowired
Environment env;
#Bean
public MyBean myBean(){
return new MyBean()
}
}
Here #Configuration bean enables the #autowired. Following is another good example on using autowiring
http://www.mkyong.com/spring/spring-auto-wiring-beans-with-autowired-annotation/
Hope it helps
Related
Anybody know if #RefreshScope, applied to class for reloading properties/yml files dinamically works with a configuration class annotated only with #PropertySource?
I have to refresh an external configuration file, but i cant do something like :
#Bean
#RefreshScope
public FileProperties refreshListConfig() {
return new FileProperties(); //why ?
}
#Configuration //Configuration or new instance as above?
#PropertySource("file:${path.properties}")
#ConfigurationProperties(prefix="multitenancy")
public class FileProperties {
private List<DirProps> dir =new ArrayList<DirProps>();
private String tenantsFilePath;
..
class DirProps { ..}
...
}
I know that #RefreshScope doesn't work with #Configuration, but can I use #PropertySource without #Configuration?
Javadoc :
Annotation providing a convenient and declarative mechanism for adding a PropertySource to Spring's Environment. To be used in conjunction with #Configuration classes.
So, can't i use #RefreshScope without move external properties in application properties and removing #PropertySource and #Configuration annotations from FileProperties class? Do you know if exists a working approach without move the properties?
Thanks
I am absolutely new to TestNG, Spring framework etc. and I'm trying to use the annotation #Value access to configuration file via the #Configuration annotation.
All I'm trying to achieve here is to make the console write out "hi" from the config file accessing the value via #Value. I must be obviously missing the whole point of the #Value annotation (or #Autowired or some other annotations) as all I'm gettting is java.lang.NullPointerException.
I have the following three files (reduced to the absolute minimum):
config.properties
a="hi"
TestConfiguration.java
#Configuration
#PropertySource("config.properties")
public class TestConfiguration {
#Value("${a}")
public String A;
}
TrialTest.java
public class TrialTest {
#Autowired
private TestConfiguration testConfiguration;
#Test
public void test() {
System.out.println(testConfiguration.A);
}
}
Thanks a lot.
Try annotate your test class with these:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes={TestConfiguration.class})
[Edit] sorry I didn't see that OP was using TestNG. The essential point is still that the problem is caused by Spring not being bootstrapped. In TestNG that can be done via extending AbstractTestNGSpringContextTests.
Make sure that in your config, you are declaring the PropertySourcesPlaceholderConfigurer bean which can resolve the #Value expressions. Declare this bean:
#Configuration
#PropertySource("config.properties")
public class TestConfiguration {
#Value("${a}")
public String A;
#Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer()
{
return new PropertySourcesPlaceholderConfigurer();
}
}
Note that you do not have to do anything with this bean, just by declaring it, it will allow the #Value annotation expressions to work as expected.
You can either redundantly declare this bean in every class that uses a #Value annotation, but that would be bad practice/style as it would keep overwriting the bean in each new declaration. Instead, place this bean at the top most config which imports other configs using #Value and you can recycle the PropertySourcesPlaceholderConfigurer bean from the one place.
I noticed a strange behaviour when using #Value with CamelConfiguration
Having an example properties file:
test.list=foo,bar,baz
and having a PropertySourcesPlaceholderConfigurer, a ConversionService and when referencing the property in some regular Spring configuration:
#Configuration
#PropertySource(value = "file:example.properties")
public class RegularConfig {
#Value("${test.list}")
List<String> testList;
}
Everything works as intended (testList contains three values: foo, bar, and baz), but when the configuration class extends org.apache.camel.spring.javaconfig.CamelConfiguration:
#Configuration
#PropertySource(value = "file:example.properties")
public class RegularConfig extends CamelConfiguration {
#Value("${test.list}")
List<String> testList;
}
(see minimal running example for both cases at https://github.com/michalmela/stackoverflow-questions/tree/master/35719697)
the testList contains one, joined value: foo,bar,baz.
Is this a misconfiguration on my side? Or some kind of bug (or feature)?
(I know the obvious workaround is to split the values manually, which is what I already went with, but I'd just like to understand what is going on here)
CamelConfiguration declare a BeanPostProcessor (camelBeanPostProcessor). BeanPostProcessor-s are instantiated by spring at first (because they have to see all others beans instantiation).
When Spring instantiate this camelBeanPostProcessor, it creates an instance of your class extending CamelConfiguration, inject the properties, and invoke camelBeanPostProcessor().
So, properties injected in this instance are injected at the beginning of the Spring ApplicationContext initialization. At this time, your ConversionService is not yet registered: The default converter is used, instead of the StringToCollectionConverter.
As a workaround, you can register explicitly a ConversionService before refreshing the applicationContext :
AnnotationConfigApplicationContext ctxt = new AnnotationConfigApplicationContext();
ctxt.getBeanFactory().setConversionService(new DefaultConversionService());
ctxt.register(...);
I know it may sound stupid but are you sure the configuration worked correctly before extending CamelConfiguration class? It doesn't look to me that #Value without using SpEL will split the list. I would use this configuration
#Value(value = "#{'${test.list}'.split(',')}")
Which version of Spring are you using?. Thanks
I'm getting back into Spring (currently v4). It's all wonderful now with #SpringBootApplication and the other annotations but all the documentation seems to forget to mention how I define other beans in XML!
For example I'd like to create an "SFTP Session Factory" as defined at:
http://docs.spring.io/spring-integration/reference/html/sftp.html
There is a nice bit of XML to define the bean but where on earth do I put it and how do I link it in? Previously I did a:
ApplicationContext context = new ClassPathXmlApplicationContext(
"classpath:applicationContext.xml");
to specify the file name and location but now that I'm trying to use:
ApplicationContext ctx = SpringApplication.run(Application.class);
Where do I put the XML file? Is there a magic spring name to call it?
As long as you're starting with a base #Configuration class to begin with, which it maybe sounds like you are with #SpringBootApplication, you can use the #ImportResource annotation to include an XML configuration file as well.
#SpringBootApplication
#ImportResource("classpath:spring-sftp-config.xml")
public class SpringConfiguration {
//
}
You also can translate the XML config to a Java config. In your case it would look like:
#Bean
public DefaultSftpSessionFactory sftpSessionFactory() {
DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory();
factory.setHost("localhost");
factory.setPrivateKey(new ClassPathResource("classpath:META-INF/keys/sftpTest"));
factory.setPrivateKeyPassphrase("springIntegration");
factory.setPort(22);
factory.setUser("kermit");
return factory;
}
You can put this method in the class with the #SpringBootApplication annotation.
Spring boot ideal concept is avoid xml file. but if you want to keep xml bean, you can just add #ImportResource("classPath:beanFileName.xml").
I would recommend remove the spring-sftp-config.xml file. And, convert this file to spring annotation based bean. So, whatever class has been created as bean. Just write #Service or #Component annotation before class name. for example:
XML based:
<bean ID="id name" class="com.example.Employee">
Annotation:
#Service or #Component
class Employee{
}
And, add #ComponentScan("Give the package name"). This is the best approach.
So in the latest version of Spring we are able to use the #Configuration annotation to setup our configurations for Spring. Now in JavaConfig it is possible to use the #AnnotationDrivenTx (#AnnotationDrivenTx Reference Link) annotation to setup transactions in our Config class. But since JavaConfig has been decommissioned I was wondering if anyone knew how to setup something similar without JavaConfig and without needing to add anything to the application-context.xml. Here is what I basically have for my Config class
#Configuration
#ImportResource("config/application-context.xml")
public class Config {
public #Bean DataSource dataSource() {
//get and return datasource
}
public #Bean Service1 getService1() {
//return service1Impl
}
}
And I'd like to make Service1 transactional. If anyone has any ideas on how to do this or if this is just not possible please let me know.
Thanks!
You can now use #EnableTransactionManagement.
See this post for more details: http://blog.springsource.com/2011/06/10/spring-3-1-m2-configuration-enhancements/
It seems like it isn't possible according to this forum post:
there may be a more first-class
mechanism for enabling
annotation-driven TX in #Configuration
classes in Spring 3.1, but in the
meantime, the recommended approach is
to use #ImportResource to include a
snippet of XML that declares
<tx:annotation-driven/>
Wait: but you seem to have an XML context anyway. Why not add <tx:annotation-driven/> to it and use #Transactional?
Take a look at http://blog.springsource.com/2011/02/17/spring-3-1-m1-featurespec. Spring 3.1's FeatureSpecification classes such as TxAnnotationDriven are designed to solve exactly the problem described above.