Spring Java Based Configuration - java

I'm facing issue in converting xml based bean configuration to Java based bean configuration in Spring MVC project. I need to convert the below xml configuration to Java based by using # bean. Please help me.. Thanks in advance
<bean class="someclass">
<property name="somename">
<util:list>
<bean id="someid" class="someotherclass"/>
</util:list>
</property>
</bean>

You need to create the OtherClass bean, like this:
#Bean
private SomeClass someclassBean() {
SomeClass sc = new SomeClass();
sc.setSomeName(Arrays.asList(new SomeOtherClass()));
return sc;
}
In your specific needs, try this:
#Bean
AnnotationMethodHandlerAdapter annotationMethodHandlerAdapter() {
AnnotationMethodHandlerAdapter bean = new AnnotationMethodHandlerAdapter()
bean.setMessageConverters(Arrays.asList(new ByteArrayHttpMessageConverter()));
return bean;
}

Related

Spring #Value is always null

I'm using spring in my app and I have a .properties file which has some values defined.
In a java class there is a String value:
#Value("${test}")
public String value;
The point is that if I inject this value in beans definition:
<bean id="customClass" class="package.customClass.CustomClassImpl">
<property name="value" value="${test}"></property>
</bean>
It works fine, but if I use #Value, there is always a null... Why is that happening?
And no, I'm not doing any "new" no instantiate "customClass", I get it with context.getBean("customClass).
EDIT: I have configured a property placeholder in the context:
<bean id="properties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:config.properties</value>
<value>classpath:constants.properties</value>
</list>
</property>
</bean>
Thanks in advance.
Remember, your class need a stereotype annotation like #Component or #Service
If you are creating spring boot application and your goal is to provide configuration parameter(s) via (application).properties there is a way to do it without explicit #Value declaration.
Create YourClassProperties with annotation #ConfigurationProperties("some.prefix"):
#ConfigurationProperties("my.example")
public class MyClassProperties {
private String foo;
public String getFoo() {
return foo;
}
public void setFoo(String foo) {
this.foo = foo;
}
}
Add defined properties to (application).properties:
my.example.foo=bar
And then, in your application you can autowire needed properties...
#Autowired
private MyClassProperties myClassProperties;
... and use them as you would any other properties:
LOG.info("Value of the foo: {}", myClassProperties.getFoo());
Solve, you need to enable annotation config in configuration file: <context:annotation-config/>
You need to declare your .properties file using #PropertySource. Not sure it's doable using xml config.
Also, are you sure about this "$", it's "#" in this example :
http://forum.spring.io/forum/spring-projects/container/61645-value-and-propertyplaceholderconfigurer

How to convert java based bean configuration to xml based config

I'm a newbie to spring and wonder how java based configs can be converted to xml based bean configs. I know that annotation based configs are more used now a days. But my requirement is to use xml based configs.
Bean configuration is added below.
#Bean
DataStoreWriter<String> dataStoreWriter(org.apache.hadoop.conf.Configuration hadoopConfiguration) {
TextFileWriter writer = new TextFileWriter(hadoopConfiguration, new Path(basePath), null);
return writer;
You can create bean directly in xml configuration
<bean id="dataStoreWriter" class="TextFileWriter">
<constructor-arg index="0" ref="hadoopConfigBean"/>
<constructor-arg index="1">
<bean class="Path">
<constructor-arg index="0" value="/tmp"/>
</bean>
</constructor-arg>
</bean>
If you need non-trivial bean configuration then you can use factory method call in xml configuration
<bean id="dataStoreWriter" class="DataStoreFactory" factory-method="dataStoreWriter">
<constructor-arg index="0" ref="hadoopConfigBean"/>
<constructor-arg index="1" value="/tmp"/>
</bean>
Factory class should look like
public class DataStoreFactory {
public static DataStoreWriter<String> dataStoreWriter(Configuration hadoopConfiguration, String basePath) {
// do something here
TextFileWriter writer = new TextFileWriter(hadoopConfiguration, new Path(basePath), null);
return writer;
}
}
From spring doc
#Bean is a method-level annotation and a direct analog of the XML element. The annotation supports most of the attributes offered by , such as: init-method, destroy-method, autowiring, lazy-init, dependency-check, depends-on and scope.
When you annotate method #bean spring container will execute that method and register the return value as a bean within a BeanFactory. By default, the bean name will be the same as the method name.
#Configuration
public class AppConfig {
#Bean
public TransferService transferService() {
return new TransferServiceImpl();
}
}
Note :Use #bean along with #configuration

Bean inheritance via annotation

How I can provide bean inheritance in Spring using annotations? In XML config I used <parent="parentBean"> tag. Is there some annotation?
For example, I have two beans(cacheEventLogger extends fileEventLogger):
<bean id="fileEventLogger" class="com.myuspring.core.loggers.FileEventLogger" init-method="init">
<constructor-arg value="d:/1.txt"/>
</bean>
<bean id="cacheEventLogger" class="com.myspring.core.loggers.CacheFileEventLogger" init-method="init"
parent="fileEventLogger" >
<constructor-arg value="15"/>
<property name="cacheSize" value="2"/>
I've create AppConfig class:
#Configuration
public class AppConfig {
#Bean(initMethod = "init")
public FileEventLogger fileEventLogger() {
return new FileEventLogger("d:/1.txt");
}
#Bean(initMethod = "init")
public CacheFileEventLogger cacheFileEventLogger() {
???
}
}
What annotation should I set to cacheEventLogger for extending fileEventLogger?
Spring annotations doesn't have an equivalent of spring XML parent tag/attribute. There is a workaround specified in the JIRA with some custom coding.
Refer to the related spring JIRA https://jira.spring.io/browse/SPR-5580 and a reference to stackoverflow answer from this JIRA Bean definition inheritance with annotations?
I think this is what you are looking for.
There's no such parent property for the Spring-specific annotations, because the Java language provides everything needed (i.e inheritance, abstraction) to create a template and use it as a parent for some Spring-beans.

#Bean configuration instead of context.xml

i am using following config in my spring context.xml to register patterns for Java melody configuration.
i want to move this out as a spring bean. can anyone help me with this? i am having trouble setting it up properly.
<bean id="facadeMonitoringAdvisor" class="net.bull.javamelody.MonitoringSpringAdvisor">
<property name="pointcut">
<bean class="org.springframework.aop.support.JdkRegexpMethodPointcut">
<property name="patterns" value="com.abc.service.*.*(..)" />
<property name="excludedPatterns" value="com.abc.service.*.getEntityManager(),com.abc.service.xyz.integration.gateway.*,com.abc.service.xyz.webservice.*" />
</bean>
</property>
</bean>
You should create a #Configuration class. For each bean tag in xml, create a method annotated with #Bean. In this case it would look something like this:
#Configuration
public class MonitoringContext
{
#Bean(name="facadeMonitoringAdvisor")
public MonitoringSpringAdvisor getMonitoringSpringAdvisor() {
MonitoringSpringAdvisor msa = new MonitoringSpringAdvisor();
msa.setPointcut(getJdkRegexpMethodPointcut());
return msa;
}
#Bean
public JdkRegexpMethodPointcut getJdkRegexpMethodPointcut() {
JdkRegexpMethodPointcut jrm = new JdkRegexpMethodPointcut();
jrm.setPatterns("com.abc.service.*.*(..)");
jrm.setExcludedPatterns("com.abc.service.*.getEntityManager(),com.abc.service.xyz.integration.gateway.*,com.abc.service.xyz.webservice.*");
return jrm;
}
}
Check out the Spring documentation for AOP here

how to set SqlMapClient outside of spring xmls

I have the following in my xml configurations. I would like to convert these to my code because I am doing some unit/integration testing outside of the container.
xmls:
<bean id="MyMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation" value="classpath:sql-map-config-oracle.xml"/>
<property name="dataSource" ref="IbatisDataSourceOracle"/>
</bean>
<bean id="IbatisDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jdbc/my/mydb"/>
</bean>
code I used to fetch stuff from above xmls:
this.setSqlMapClient((SqlMapClient)ApplicationInitializer.getApplicationContext().getBean("MyMapClient"));
my code (for unit testing purposes):
SqlMapClientFactoryBean bean = new SqlMapClientFactoryBean();
UrlResource urlrc = new UrlResource("file:/data/config.xml");
bean.setConfigLocation(urlrc);
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("oracle.jdbc.OracleDriver");
dataSource.setUrl("jdbc:oracle:thin:#123.210.85.56:1522:ORCL");
dataSource.setUsername("dbo_mine");
dataSource.setPassword("dbo_mypwd");
bean.setDataSource(dataSource);
SqlMapClient sql = (SqlMapClient) bean; //code fails here
when the xml's are used then SqlMapClient is the class that sets up then how come I cant convert SqlMapClientFactoryBean to SqlMapClient
SqlMapClientFactoryBean is a FactoryBean. It does not implement the SqlMapClient interface itself, but manufactures instances of SqlMapClient which are returned when it's getObject() method is called. The Spring container knows about FactoryBeans, and makes them look just like normal beans from the perspective of the caller. I'm not sure that using the FactoryBean outside a container will work - you may get a "not initialized" exception if you call getObject() outside of the container lifecycle ...
Why not create a separate, stripped down Spring config for your test cases, instantiate that, and obtain the beans from there? Alternatively, you could create the SqlMapClient the non-Spring way and set that on your DAO
SqlMapClientFactoryBean factory = new SqlMapClientFactoryBean();
factory.setConfigLocation(YOUR_SQL_MAP_CONFIG_RESOURCE);
factory.afterPropertiesSet(); //omitting try/catch code
client = (SqlMapClient)factory.getObject();
voila
I want to add what worked for me. Had to work with some legacy code and in till I can transition to MyBatis I want to convert the old applicationContext xml to spring #Configuration classes.
#Bean
public SqlMapClient sqlMap() throws Exception
{
SqlMapClientFactoryBean factory = new SqlMapClientFactoryBean();
factory.setConfigLocation(new ClassPathResource("conf/ibatis.xml"));
DataSource dataSource = this.dataSource;
factory.setDataSource(dataSource);
factory.afterPropertiesSet();
return (SqlMapClient) factory.getObject();
}

Categories

Resources