Spring Java Config - java

Just wondering what is the correct way to inject a map in my Application.java file to be used in services in other classes using the Spring Java Config approach
If i setup 1 bean like this
#Bean(name = "databaseScheduler")
public SchedulerFactoryBean databaseScheduler() {
...
...
}
And reference if later like this then everything works as expected
#Inject
private SchedulerFactoryBean databaseScheduler;
But when I try and setup a map of SchedulerFactoryBeans as follows
#Bean(name = "databaseSchedulersMap")
public Map<Integer, SchedulerFactoryBean> databaseSchedulersMap() {
....
....
}
And inject it later like so
#Resource
private Map<Integer, SchedulerFactoryBean> databaseSchedulersMap;
It doesnt work and properties on the bean are missing or null
Im setting up the SchedulerFactoryBean in the exact same manner as the single bean instance but its proving really difficult to get this going
Any help on this is greatly appreciated

Apologies #Ma Kro
I tried your suggestion again with the #Resource(name="databaseSchedulersMap") and it worked
I must have had a typo in it the first time or something
Sorry about that

Related

converting java variable to spring beans

I am working on spring boot application. I want to define a variable in a class file as bean so that it is being initialised only once. Below is the source code.
Configuration cfg = new Configuration();
//Load template from source folder
Template template = cfg.getTemplate("src/helloworld.ftl");
// Build the data-model
Map<String, Object> data = new HashMap<String, Object>();
data.put("message", "Hello World!");
// Console output
Writer out = new OutputStreamWriter(System.out);
template.process(data, out);
out.flush();
I want to initialise the configuration object cfg & the template (starting 2 lines of the code) only once during application start and later use them wherever required in application classes.
How can I achieve this with bean?
Or is there any other better way to achieve this?
Create a new class and use the #Configuration annotation to load the beans when the application start up.
#Configuration
public class SpringConfiguration{
#Bean
public Configuration getConfigurationBean(){
return new Configuration();
}
}
One thing you can do is put the instantiation and initialization of the variables in their own method and annotate every method with the #Bean annotation.
If you do this, you should annotate the class with #Configuration.
The 2 methods of yours would look something like this:
#Configuration
public class ConfigurationBean {
#Bean
public Configuration configuration() {
return new Configuration();
}
#Bean
public Template template() {
return configuration().getTemplate("...");
}
}
Additionally, if you don't want to instantiate the Configuration as a separate bean, you can merge the 2 methods above.
======= UPDATE to answer question in the comment =======
If you want to use the newly defined Template bean for example in other classes, you need to annotate those classes with #Component, so that they become beans as well.
An example:
#Component
public class OtherClassBean {
private final Template template;
public OtherClassBean(Template template) {
this.template = template;
}
}
please be careful here, because from now on, you can't manually instantiate OtherClassBean, meaning that a line like new OtherClassBean(...) is wrong in 99% of the cases and might result in unexpected behavior.
This is because all beans are meant to be managed by Spring, which can only be achieved if Spring instantiates those classes.
The only exception from this rule of thumb is in my initial answer, where you instantiate a bean in a method that is annotated with #Bean.
I know this is a confusing topic for most people trying to learn this, so don't be shy to ask more questions.

Calling TransportClient's close() method in #Bean(destroyMethod = "close") instead of finally or try with resource

I'm working on Spring and Elasticsearch integration and for that creating a TransportClient bean in a spring configuration class (annotated with #Configuration) which is further getting injected to service class, however for closing TransportCient bean, I'm doing it thru destroyMethod = "close" as shown below,
#Bean(destroyMethod = "close")
public TransportClient client() {
client = new PreBuiltTransportClient(elasticsearchSettings);
...
...
return client;
}
The bean instantiation and closing works perfectly fine, and this way it also helps me not instantiating bean multiple times which would have happen if I had to put above code in every method which may require to connect ES.
Can someone please tell me if above approach would be correct or there is any other better way to do so. Please let me know if any other details are needed.
Thanks in Advance..!

How to use ebean-spring with SpringBoot?

I want to use SpringBoot with Ebean. I found this article: http://ebean-orm.github.io/docs/setup/spring and I could set it up and make it work with an own implementation of a EbeanServerFactory as shown in the article.
It states, that if I add ebean-spring to my dependencies along with a default-ebean-server.xml than it should work with a default EbeanServerFactoryBean. But what should I write to this file? Where do I set up the FactoryBean to use my datasource etc.? Sorry if my question is silly, but I am really new to SpringBoot and don't understand it deeply.
If I add ebean-spring and remove my own factory I get an error:
No qualifying bean of type [com.avaje.ebean.EbeanServer] found for dependency
So I could solve it after a day of thinking, and trying. In Spring you usually have an Application.java or something which starts your app with your main(). Here you can define a EbeanServer Factory like the following:
#Bean
public EbeanServerFactoryBean ebeanServerFactoryBean() {
EbeanServerFactoryBean ebeanServerFactoryBean = new EbeanServerFactoryBean();
ServerConfig config = new ServerConfig();
config.setName("pg");
config.loadFromProperties();
//other configs
config.setDefaultServer(true);
ebeanServerFactoryBean.setServerConfig(config);
return ebeanServerFactoryBean;
}

Spring Property Injection with Play2 Framework

I like many features of Play Framework 2 (I'm using it with Java) but, as a fan of Dependency Injection, I love also Spring and particularly, its way to inject configuration into objects by just using the #Value annotation.
Therefore, I would love to know how to inject into an instance variable the value of a property using Play's built-in property resolution mechanism. Something like this:
#Component
public class SpringBeanWithinAPlay2Application {
#Value("${application.timeout:10}")
private int timeout;
}
Any clue anyone?
Many thanks in advance.
I had the same problem a while ago and this was my way of making this work:
Firstly, when you boostrap your Spring Application context (I use annotation based configuration but the same should work for XML based), you have to add a custom PropertySource, which is the way Spring enables the addition of new way of resolving properties. Something like this:
public static void initialize() {
ctx = new AnnotationConfigApplicationContext();
ctx.getEnvironment().getPropertySources().addFirst(new PlayFrameworkPropertySource());
ctx.scan("somepackage");
ctx.refresh();
}
The custom class PlayFrameworkPropertySource is the one that does the magic:
public class PlayFrameworkPropertySource extends PropertySource<Object> {
public PlayFrameworkPropertySource() {
super("Play Framework properties resolution mechanism");
}
#Override
public Object getProperty(String propertyName) {
// or ConfigFactory.load().getString(propertyName), as you prefer...
return Configuration.root().getString(propertyName);
}
}
In order for all this to work, you just need to do one more thing: explicitly declare a bean of type PropertySourcesPlaceholderConfigurer in some #Configuration class you might be using:
#Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
Important Note: this bean must be static, as it's a BeanFactoryPostProcessor and it should be loaded prior to any other regular #Bean.
This worked like a charm for me, hope this is helpful to someone else!
Cheers,
Jonathan

#autowired need to add something to xml

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

Categories

Resources