I have the following code snippet which I use to expose a BridgePropertyPlaceholderConfigurer Bean through Annotation Configuration:
#Configuration
public class SpringConfiguration {
#Bean
public static BridgePropertyPlaceholderConfigurer getProperties() {
File conf = new File(new File(".").getAbsolutePath() + "/configuration.properties");
BridgePropertyPlaceholderConfigurer configurer;
configurer = new BridgePropertyPlaceholderConfigurer();
Resource[] resources = {
new FileSystemResource(conf.getAbsolutePath())
};
configurer.setLocations(resources);
return configurer;
}
}
So basically, I want to expose a properties file that is located in the same folder as the jar. Thats why I'm doing the crazy stuff with File
Is there anyway however which I could convert this into XML configuration?
Something like:
<bean id="bridgePropertyPlaceholder" class="org.apache.camel.spring.spi.BridgePropertyPlaceholderConfigurer">
<property name="location" value="#{new File('.')....}"/>
</bean>
You can create the bean using a factory:
<bean id="bridgePropertyPlaceholderConfigurerFactory"
class="foo.bar.BridgePropertyPlaceholderConfigurerFactory" />
<bean id="bridgePropertyPlaceholder"
factory-bean="bridgePropertyPlaceholderFactory"
factory-method="createBridgePropertyPlaceholderConfigurer" />
Java factory:
public class BridgePropertyPlaceholderConfigurerFactory {
public BridgePropertyPlaceholderConfigurer createBridgePropertyPlaceholderConfigurer() {
// your creation code ..
return ..
}
}
Have a look at the documentation for more details on factory methods.
Related
I am trying to get context.xml parameter through SpEL expresseion but I am getting null.
My code to get paramter is
public class DatabaseProperties extends PropertyPlaceholderConfigurer {
#Value("#{'${myConfigDirectory}'}")
private String dbConfigPath;
#Override
protected void loadProperties(Properties props) throws IOException
Resource location = new FileSystemResource("/spring-data-access.properties");
System.out.println("DB CONFIG PATH "+dbConfigPath);
System.out.println("DB LOCATION + "+location.getFile().getAbsolutePath());
setLocation(location);
super.loadProperties(props);
}
}
here dbConfigPath is always null.
My configuration file is in .xml. here it is
<bean id="propertyConfigurer" class="com.properties.DatabaseProperties">
<property name="ignoreResourceNotFound" value="true"/>
</bean>
I need to do it so that when a war is deployed it should pick properties from outside war using parameter defined in 'context.xm' and when in dev it should pick from resource folder.
you dont need to extend PropertyPlaceholderConfigurer , just declare a bean in configuration.
#Configuration
#PropertySource(
value={"classpath:/spring-data-access.properties"},
ignoreResourceNotFound = true)
public class Config {
#Value("${myConfigDirectory}}")
private String dbConfigPath;
/**
* Property placeholder configurer needed to process #Value annotations
*/
#Bean
public static PropertySourcesPlaceholderConfigurer propertyConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
Java - Spring
I have spring factory bean creation in .xml
<bean id="concurrentHashMapFactory" class="com.abc.HashMapFactory.ConcurrentHashMapFactory"/>
<bean id="idCorpMap" factory-bean="concurrentHashMapFactory" factory-method="createIdCorpMapInstance"/>
but i want to convert above .xml statement into equivalent using annotation any help ?
Roughly like this (I didn't test it)..
#Configuration
public class Config {
#Bean(name = "concurrentHashMapFactory")
public ConcurrentHashMapFactory createConcurrentHashMapFactory() {
return new ConcurrentHashMapFactory();
}
#Bean(name = "idCorpMap")
public IdCorpMapType createIdCorpMap(ConcurrentHashMapFactory factory) {
return factory.createIdCorpMapInstance();
}
}
I'm building a new project, and I thought I'd try a new way of loading my Spring config. I found the #Configuration annotation and decided to give it a try.
#Configuration
#ImportResource("classpath:myApp-config.xml")
public class MyAppConfig
{
#Autowired
private MyClass myClass;
#Bean(name="someOtherBeanName")
public MyClass getMyClass ()
{
return myClass;
}
public void setMyClass( myClass m)
{
this.myClass= m;
}
}
In the spring config file:
<context:annotation-config/>
<bean name="someOtherBeanName" class="com.MyClass">
<property name="myClass">
<map>
<!-- details not relevant -->
</map>
</property>
</bean>
To make use of this, I have code like this:
//class member
private static MyAppConfig cfg = new MyAppConfig();
...
...
...
//In the class that needs the configuration
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(MyAppConfig.class);
ctx.refresh();
//appMgr = cfg.getMyClass();
appMgr = (MyClass) ctx.getBean("someOtherBeanName");
As you can see, I'd thought I could get a spring-configured instances of MyClass from my configuration object, but instead I had to get it from my context object.
I guess I misunderstood the way #Configuration and #Bean work. Am I pretty close or way off?
You cannot get your bean from cfg.getMyClass();, there are some misunderstanding.
#Configuration is only another representation of spring configuration, you should understand it just like your application-context.xml, nothing is new here.
This
private static MyAppConfig cfg = new MyAppConfig();
is not a Spring managed bean so you will get null when calling getMyClass().
Also, the following
#ImportResource("classpath:myApp-config.xml")
with
#Autowired
private MyClass myClass;
#Bean(name="someOtherBeanName")
public MyClass getMyClass ()
{
return myClass;
}
is redundant. Because of the #ImportResource, the bean from the XML configuration is already in the context.
Indicates one or more resources containing bean definitions to import.
You don't need an additional #Bean method in between.
You are pretty way off... going full Java-based config will be for your example:
#Configuration
public class MyAppConfig {
#Bean
public MyClass someOtherBeanName() {
MyClass myClass = new MyClass();
myClass.setMyProp(null /* details not relevant */);
return myClass;
}
}
Somewhere else in the main method (this is unchanged):
//In the class that needs the configuration
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(MyAppConfig.class);
ctx.refresh();
//appMgr = cfg.getMyClass();
appMgr = (MyClass) ctx.getBean("someOtherBeanName");
Add something that you might meet, if u still can not find config.xml or javaconfig.class. Check your file structure.
src
config.xml or javaconfig.java
To save your config in your path(default package is src)
Can you please tell me how to use Spring Javaconfig to directly load/autowire a properties file to a java.util.Properties field?
Thanks!
Later edit - still searching for the answer:
Is it possible to load with Spring JavaConfig a properties file directly into a java.util.Properties field?
The XML base Way:
in spring config:
<util:properties id="myProperties" location="classpath:com/foo/my-production.properties"/>
in your class:
#Autowired
#Qualifier("myProperties")
private Properties myProperties;
JavaConfig Only
It looks like there is an annotation:
#PropertySource("classpath:com/foo/my-production.properties")
Annotating a class with this will load the properties from the file in to the Environment. You then have to autowire the Environment into the class to get the properties.
#Configuration
#PropertySource("classpath:com/foo/my-production.properties")
public class AppConfig {
#Autowired
private Environment env;
public void someMethod() {
String prop = env.getProperty("my.prop.name");
...
}
I do not see a way to directly inject them into the Java.util.properties. But you could create a class that uses this annotation that acts as a wrapper, and builds the properties that way.
declare a PropertiesFactoryBean.
#Bean
public PropertiesFactoryBean mailProperties() {
PropertiesFactoryBean bean = new PropertiesFactoryBean();
bean.setLocation(new ClassPathResource("mail.properties"));
return bean;
}
Legacy code had following config
<bean id="mailConfiguration" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location" value="classpath:mail.properties"/>
</bean>
Converting that to Java config is super easy as shown above.
It is an old subject but there are also a more basic solution.
#Configuration
public class MyConfig {
#Bean
public Properties myPropertyBean() {
Properties properties = new Properties();
properties.load(...);
return properties;
}
}
There is also this approach for injecting properties directly using xml configurations. The context xml has this
<util:properties id="myProps" location="classpath:META-INF/spring/conf/myProps.properties"/>
and the java class just uses
#javax.annotation.Resource
private Properties myProps;
Voila!! it loads.
Spring uses the 'id' attribute in xml to bind to the name of variable in your code.
You can try this
#Configuration
public class PropertyConfig {
#Bean("mailProperties")
#ConfigurationProperties(prefix = "mail")
public Properties getProperties() {
return new Properties();
}
}
Make sure to define properties in application.properties
application.yml:
root-something:
my-properties:
key1: val1
key2: val2
Your type-safe pojo:
import java.util.Properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
#ConfigurationProperties(prefix = "root-something")
public class RootSomethingPojo {
private Properties myProperties;
Your container configuration:
#Configuration
#EnableConfigurationProperties({ RootSomethingPojo .class })
public class MySpringConfiguration {
This will inject the key-value pairs directly into the myProperties field.
How would I specify an anonymous inner bean in a named Spring Service?
#Service("myNamedService")
public class myNamedServiceClass {
private InnerBeanType innerBean;
#Autowired
public void setInnerBean(InnerBeanType innerBean) {
this.innerBean = innerBean;
}
}
I'm basically trying to achieve the equivalent of the following Spring XML wiring:
<bean name="myNamedService" class="somePackage.myNamedServiceClass">
<property name="innerBean">
<bean class="somePackage.InnerBeanType"/>
</property>
</bean>
Equivalent using pure annotations is I think not possible. You can use #Configuration though if the purpose is to not expose innerBean as a visible bean this way:
#Bean
public MyNamedServiceBean myNamedServiceBean(){
MyNamedServiceClass myNamedServiceBean = new MyNamedServiceClass();
myNamedServiceBean.setInnerBean(new InnerBeanType());
return myNamedServiceBean;
}