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
Related
I have a Spring 4 app with hibernate-validator on the classpath. I have a bean class which uses some javax validation annotations for the bean properties and I have another class that accepts that bean in it's constructor.
Java:
public class Config {
#NotNull
#Size(min=10)
public final String test;
#Min(5)
public final int num;
public Config(String test, int num) {
this.test = test;
this.num = num;
}
//getters
}
public class Test {
private Config config;
public Test(#Valid Config config) {
this.config = config;
}
}
My Spring application context is as follows:
<bean id="config" class="com.Config">
<constructor-arg type="java.lang.String">
<value>aaaa</value>
</constructor-arg>
<constructor-arg type="int">
<value>2</value>
</constructor-arg>
</bean>
<bean id="test" class="com.Test">
<constructor-arg ref="config" />
</bean>
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
Note that the validator is defined in the application context. When I run the app as is, I expect an exception to be thrown when the bean is set into the test class constructor because the two arguments do not meet the constraints, but it runs without any exception. Am I missing something else?
The #Valid annotation is meant to be used for Controller methods, so it's not being evaluated here in your constructor.
This old question indicates how you can test the #Valid annotation by exposing and calling a Controller using Spring MVC. Also, if you notice other annotations are not working, make sure you have <mvc:annotation-driven /> somewhere in your context file.
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.
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;
}
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
Within Spring DI, can you "use" your bean within it's own definition? For example, if I have a bean called getTest1 with an inner bean declared within it, can I pass getTest1 to the constructor of that inner bean?
I'm wondering if I can implement a decorator patter-like solution using Spring DI for a work project but don't have much time to play around with it. Thanks!
Haven't tested it but I think you need something like this
<bean id="a" class="com.AClass">
<property name="aProperty" value="y">
<property name="bean2">
<bean class="com.BClass">
<constructor-arg ref="a"/>
</bean>
</property>
</bean>
check here for more help on referencing one bean inside another
The decorator pattern can be expressed in the following way using XML:
<bean id="decorated" class="Outer">
<constructor-arg>
<bean class="Middle">
<constructor-arg>
<bean class="Inner"/>
</constructor-arg>
</bean>
</constructor-arg>
</bean>
This is equivalent to the following Java code:
Common decorated = new Outer(new Middle(new Inner()));
Consider Using #Configuration approach to make this more Java-friendly:
#Bean
public Common outer() {
return new Outer(middle());
}
#Bean
public Common middle() {
return new Middle(inner());
}
#Bean
public Common inner() {
return new Inner();
}