I need to Inject a Map to a bean property and when map entries are traversed it should return them in insertion order. In Java, this is similar to the LinkedHashMap. But as I can't find anything in spring documentation related to the ordering of tag, I'm not sure whether I can use to use it in this scenario.
Can someone please let me know the whether I can use for this purpose.
Many thanks
Use this construct:
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
...
<util:map id="mymap" map-class="java.util.LinkedHashMap">
<entry key="a" value="b" />
<entry key="c" value="d" />
</util:map>
...
</beans>
to declare the map with ordered keys. You can then use this map using <ref id="mymap" /> or you can use this construct directly while declaring the value of Map property.
The default is LinkedHashMap - MapFactoryBean is used to create instances of Map. According to docs:
Simple factory for shared Map instances. Allows for central setup of
Maps via the "map" element in XML bean definitions.
and its setTargetMapClass method:
Set the class to use for the target Map. Can be populated with a fully
qualified class name when defined in a Spring application context.
Default is a linked HashMap, keeping the registration order.
See Also: LinkedHashMap
so no need to use <util:map> here.
Related
I have a java project, using Spring. I have defined three classes: BaseClass, SubClass1 and SubClass2. Two SubClassx both extend BaseClass.
Now, I need to define two beans, one is in a specific profile:
<bean id="newBean" class="SubClass1">
and
<beans profile="xxx">
<bean id="newBean" class="SubClass2">
</beans>
they are in different xml files. I use lombok to inject SubClass2 newBean in a Class:
public class WarmUpAgent extends WarmUpAgent {
#Setter(onMethod = #__(#Required))
private SubClass2 subClass2;
...
<bean id="warmUpAgent" class="WarmUpAgent">
<property name="subClass2" ref="newBean" />
</bean>
But when I run the project with profile "xxx", it throws:
IllegalStateException: Cannot convert value of type [SubClass1] to required type [SubClass2] for property 'subClass2'
It seems that fail to overwrite bean newBean with SubClass2, even though I have activated profile "xxx". Is there any way to use profile, to define two beans, with same name and different class?
Thank you very much.
========================================================================
I put
<bean id="newBean" class="SubClass1">
and
<beans profile="xxx">
<bean id="newBean" class="SubClass2">
</beans>
in one xml file, and it works. But I'd like to separate them into two xml files, according to the project organization. Any solutions to implement this?
Try restricting the first bean to the default profile
<beans profile="default">
<bean id="newBean" class="SubClass1">
</beans>
<beans profile="xxx">
<bean id="newBean" class="SubClass2">
</beans>
Try using same name instead of id.
<bean name="newBean" class="SubClass1">
<beans profile="xxx">
<bean name="newBean" class="SubClass2">
</beans>
I want to combine Akka, Apache Camel, Spring and do not know the way forward for leveraging the three things in the same project.
I was successfully able to
1. write some working code with akka, akka-camel extension and camel routes(Java DSL)
2. use camel and spring (use java DSL but spring for transactions and etc..)
Now I need to combine 1 and 2. Can anyone suggest me the simplest way to achieve this?
EDIT
Some say AKKA no longer supports Spring due to conflict in object instantiation as per the link below
Why spring integration doc for akka exists only for 1.3.1 but not for next versions
Also a similar question is there without a proper solution being presented but the post is about 2 years old
akka-camel 2.2.1 route definition using Spring XML
In one blog post (which I can't get hold of the link right now) a method has been described which is in summary, the actors are defined and used Akka way and what ever the processing Akka actors does to be wired using Spring. But there wasn't any solid example.
I imagine your #2 looks like this:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ctx="http://www.springframework.org/schema/context"
xmlns:camel="http://camel.apache.org/schema/spring"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd >
<!-- Camel route configuration -->
<camelContext id = "testCamelRouteContext" xmlns="http://camel.apache.org/schema/spring">
<route id="test_data_webservice">
<from uri="jetty:http://localhost:8888/myTestService"/>
<log logName="HTTP LOG" loggingLevel="INFO" message="HTTP REQUEST: ${in.header.testdata}"/>
<process ref="myTestService"/>
</route>
</camelContext>
<context:annotation-config />
<bean class="com.package.service" id="myTestService"/>
<bean id="genericDao" class="com.dao.Impl">
<property name="dataSource" ref="datasource" />
</bean>
<bean id="testingDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
datasource stuff
</bean>
</beans>
Is it possible that you can get this camel context through Akka? Something like.
Add in your Akka config:
akka.camel.context-provider="myNewContext"
New ContextProvider class:
class myNewContext extends ContextProvider{
override def getContext(system: ExtendedActorSystem): SpringCamelHybridContext
}
I am guessing this is where the bean injection collision between Spring and Akka could occur. I have never used Akka before so my answer is trivial but I wanted to see if I could provide some help to you.
Reviving an old thread.
akka-springctx-camel library is there to make your life painless to integrate Akka, Spring, Camel, CXF etc.
Add artifact :
<dependency>
<groupId>com.github.PuspenduBanerjee</groupId>
<artifactId>akka-springctx-camel</artifactId>
<version>1.0.0</version>
</dependency>
Add Camel Context Provider in Akka config:
akka.camel.context-provider=system.SpringCamelContextProvider
Get hold of ActorSystem :
implicit val system = SpringContextActorSystemProvider.create
Create a custom RouteBuilder[other way could be Akka Consumer]
class CustomRouteBuilder(system: ActorSystem, echoActor: ActorRef)
extends RouteBuilder {
def configure {
from("direct:testEP")
.routeId("test-route")
.to(echoActor)
}
Get Camel(Spring) Context and add routes to it:
val camel = CamelExtension(system)
camel.context.addRoutes(
new CustomRouteBuilder(system, system.actorOf(Props[EchoActor])))
This test case will give you a detailed idea: https://github.com/PuspenduBanerjee/akka-springctx-camel/blob/master/src/test/scala/AkkaSpringCtxTestSpec.scala
What is the differences between
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
and
<beans:beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
Could you please explain what is the difference between these two.
It's an XML namespace used to separate potentially conflicting element names, so there's no real difference.
XML Namespaces
They are equivalent.
You can say the full name of the element is ns : elementName
e.g.:
http://www.springframework.org/schema/beans : beans
if you say xmlns="http://www.springframework.org/schema/beans" than it means "if you see an element without a namespace prefix, assume a default namespace of "http://www.springframework.org/schema/beans"
if you say xmlns:beans="http://www.springframework.org/schema/beans" than it means "if you see an element with a beans: prefix, assume it's shorthand for "http://www.springframework.org/schema/beans"
The key to understand this is the xmlns value. In both of the cases it's:
xmlns="http://www.springframework.org/schema/beans"
This specifies the default schema for the document. This means that every tag in the XML will should be part of this schema, unless explicitly specify which other schema is it part of.
Specifying that a tag comes from another schema is usually done by <schemaName:tagName> pattern. So, for example, if the tag name is part of the schema foo, you have to use it with <foo:name>.
When picking a default schema for the document, you're allowed to skip the schema name, like in your example with <beans>. In this case, the <beans> tag must be specified in the schema, pointed with xmlns.
In the other case, you're explicitly specifying that the tag beans is part of the schema with alias beans, which result to <beans:beans>. However, if you don't have a xmlns:beans=http://www.springframework.org/schema/beans definition, you'd result with an invalid XML.
Personally, I'd prefer always explicitly provide the schema alias, though.
The first one is correct and the second one isn't. The difference comes from your "default namespace". Your default namespace is beans. If your default namespace would be something else, like context for example, then you would need to explicitly define a beans namespace (which you haven't done in your example) and use the beans:beans style.
There is a different use case for nested <beans> element where you use a new <beans> tag inside your root <beans> tag:
for the purpose of defining a subset of beans with certain default values or to be registered only when certain profile(s) are active. Any such nested element must be declared as the last element in the document.
but your examples aren't related to this.
Simply, it allows you NOT to add the namespace in front of the element you choose that belongs the default namespace.
xmlns="namespace"
From the above example if:
i)xmlns="http://www.springframework.org/schema/beans"
Then you can use element <beans> as well as <beans:beans> - explicit syntax.
ii) xmlns="http://www.springframework.org/schema/p"
Then you can use <p> as well as <xmlns:p> - explicit syntax.
NOTE: You can only set the default namespace once using xmlns!
So, I have springDM managed properties
<beans:beans xmlns="http://www.springframework.org/schema/osgi-compendium"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:osgix="http://www.springframework.org/schema/osgi-compendium"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/osgi-compendium
http://www.springframework.org/schema/osgi-compendium/spring-osgi-compendium.xsd">
<beans:bean id="configurationBean" class="com.eugene.PropertiesBean">
<osgix:managed-properties persistent-id="MyPid" update-strategy="container-managed"/>
<beans:property name="host" value="localhost"></beans:property>
<beans:property name="port" value="5698"></beans:property>
</beans:bean>
</beans:beans>
Now, here is what I do. Deploy the bundle to Virgo, everything works great, the default properties (because the MyPid.properties is not deployed) get injected into the bean.
Deploy MyPid.properties where BOTH host and port are changed, they are both re-injected also.
That's great. But here is the thing, can I have one single method that would tell me that the bean has changed? The properties have been re-injected? Something like : afterPropertiesSet or init in XML config? Because right now having an afterPropertiesSet or init works only the first time the properties get injected, not the second, third and so on... Which is somehow logic.
I do not know (googleed it) if spring DM offers such a thing.
Thx! Eugene.
This is a known issue actually. We had to switch to bean-managed updates.
Let's say I have following Spring config (version of Spring is 3.0.3):
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="theFactoryBean" class="wax.MyFactoryBean"/>
<bean id="factoryBeanUser" class="wax.FactoryBeanUser">
<!-- what should be placed here?-->
</bean>
</beans>
I have instance of FactoryBean implementation and some other instance. I need Spring to inject to other instance FactoryBean, not the object it produces.
There are two possible ways to solve it.
First one, obvious and malfunctional:
<bean id="factoryBeanUser" class="wax.FactoryBeanUser">
<property name="myFactoryBean" ref="&theFactoryBean"/>
</bean>
With this config Spring throws following exception on start:
[skipped irrelevant part]
Caused by: org.xml.sax.SAXParseException: The reference to entity "theFactoryBean" must end with the ';' delimiter.
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:195)
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:174)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:388)
at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(XMLScanner.java:1414)
I found this solution Spring: Getting FactoryBean object instead of FactoryBean.getObject(), this question is maked as answered and four people voted for it. So I assume that this solution might work, but currently there is something wrong in my code.
Second one, working but awkward:
public class FactoryBeanUser implements ApplicationContextAware{
private MyFactoryBean myFactoryBean;
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
myFactoryBean = (MyFactoryBean)applicationContext.getBean("&theFactoryBean");
}
}
My question is it possible to make first approach functional or I should stick with a second way?
It seems the XML parser interprets the ampersand (&) as a start of an XML-entity. You can try using ref="&theFactoryBean".
The spring docs is not clear whether this syntax is allowed in an xml file, or only with programatic lookup. But then the xml configuration is used by the app context, so I assume the & should work (although it seems it has not been the best choice for a special symbol)
Here's why I'd suggest another thing - if you really need the factory bean rather than its product, create another bean, that does not implement FactoryBean, define a method createObject() or something like that, and use it in all factories that need it.
A sidenote - better reference the xsd with the version included:
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd