Spring configuration files: package imports or names in attribute values - java

All the examples I've seen so far about Spring configuration have
<bean class = "org.example.complex.package.path.FooClass" >
I wonder if this can be simplified through a mechanism similar to Java imports, something like:
<beans ...>
<import name = "org.example.complex.package.path.FooClass" />
<import name = "org.example.another-package.*" />
<bean class = "FooClass" >...</bean>
<bean class = "AnotherClass">...</bean>
</beans>
Alternatively (or in addition), does XML support namespaces in attribute values? Something like:
<beans xmlns:foo="org.example.complex.package.path." ...>
<bean class = "foo:FooClass" ...>
...
I would need this for other purposes too (e.g., working with RDF's URIs). My understanding is that this is supported by some software, but not a standard XML feature.

No way. Spring uses import tag to import / add another beans definition xml file to the current context.

Related

what are the spring integration classes used stdin-channel-adapter?

I am interested to know the classes used in spring integration tag so that I can get more details of the tags by going through the javadoc of the classes.
I have two basic questions:
Do the spring integration xml tags (for example stdin-channel-adapter) convert to <bean class=".." /> tags?
how to figure out the bean class associated with the spring integration tags?
Here is a simple example of spring integration xml context file:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-stream="http://www.springframework.org/schema/integration/stream"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-4.0.xsd
http://www.springframework.org/schema/integration/stream http://www.springframework.org/schema/integration/stream/spring-integration-stream-4.0.xsd">
<int-stream:stdin-channel-adapter id="producer" channel="messageChannel" />
<int:poller id="defaultPoller" default="true" max-messages-per-poll="2" fixed-rate="100" />
<int-stream:stdout-channel-adapter id="consumer" channel="messageChannel" append-newline="true" />
<int:channel id="messageChannel" />
</beans>
Thanks
I think you have some mistake in your first question. See Andreas' comment.
Anyway the answer for you is like.
Any custom tags in Spring are handler by the particular NamespaceHandler. Typically you can find the target impl in file like META-INF/spring.handlers in the particular Spring jar, e.g.:
http\://www.springframework.org/schema/integration/stream=org.springframework.integration.stream.config.StreamNamespaceHandler
With that in hands you can find the code like:
this.registerBeanDefinitionParser("stdin-channel-adapter", new ConsoleInboundChannelAdapterParser());
Where you can determine that a ConsoleInboundChannelAdapterParser is responsible for parsing and instantiation beans for <stdin-channel-adapter> tag.
And there you can find the code like:
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(
"org.springframework.integration.stream.CharacterStreamReadingMessageSource");
So, the real class for target bean instance is CharacterStreamReadingMessageSource. But that's not all.
Please, look here for the design and model: http://docs.spring.io/spring-integration/docs/4.3.0.RELEASE/reference/html/overview.html#programming-tips

How to control sequence of Spring beans creation?

I am using some third-part jars that PARTLY migrated to spring. The pain point is that there are lots of initialization module that mot migrated to spring. There initialization module need to be executed first before lots' of beans creation.
I also read Spring 3 bean instantiation sequence, the problem here is, the third part library uses #Component for bean creation (which depends on initialization module that not migrated to spring, wired right...?).
Now I can write a spring bean to wrap all initialization modules. And create the bean before beans that need it.
So is there a way to specify the bean creation sequence to create the initialization bean first?
Also I checked some documents, spring bean creation is in single thread so this would work.
You can use BeanPostProcessor and add your initizaling module as the dependency
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<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-3.2.xsd">
<bean class="com.foo.CustomBeanPostProcessor" depends-on="com.foo.InitModuleBean"/>
<bean class="com.foo.BarBean" />
<bean id="com.foo.InitModuleBean" class="com.foo.InitModuleBean" />
</beans>
you put the wraperBean that initialize as the first Bean in your xmlConfig file then spring will process the initialization by initializing that Wraper An other solution is to add depends-on attribute to all your beans that depend on that Wrapper and you specify the id of that wrapper bean inside the attribute depends-on like this
<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="modules" class="com.mycompany.ModulesWrapper" />
<bean class="com.foo.ClientBean" depends-on="modules" />
</beans>

GWT vs Spring: applicationContext is null if I change the page

I am inheriting a project from a developer who left, and I am trying to understand GWT and Spring Framework.
The original problem that lead me to this path: GWT had one module where I loaded ALL third party javascripts... that could result in conflicts. Example, I would include chart drawing libraries, etc. all in one page.
Possible solutions: Have the chart drawing library in an iframe so that it would not conflict with other third party libraries of javascript... OR open the page in a new window.
I decided to go with a new window.
So I did this:
Window.Location.assign(GWT.getHostPageBaseURL()
+ "chartModule.html?gwt.codesvr=127.0.0.1:9997/");
However, in my new chartModule.java (GWT) the problem I have is I do not have the beans/classses defined in (Spring framework) applicationContext.xml anymore:
#Autowired
ApplicationContext applicationContext;
And applicationContext is null after I have changed the host page url... so I do not have any beans that I tried autowiring...
Is it possible to reload the beans from applicationContext.xml??
Here is my applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<!-- Activates various annotations to be detected in bean classes -->
<context:annotation-config />
<!-- This file has properties that are used by other XML files loaded via ${var name} syntax -->
<context:property-placeholder location="/WEB-INF/classes/environment.properties" />
<import resource="spring-security-cas.xml" />
<!-- Scans the classpath for annotated components that will be auto-registered
as Spring beans. For example #Controller and #Service. Make sure to set the
correct base-package -->
<context:component-scan base-package="com.javamango.sixtydegrees" />
<import resource="mongo-config.xml" />
<import resource="rabbitmq-context.xml" />
<import resource="spring-mail.xml" />
</beans>
You cannot use spring beans on client side. If you want retriewe some data from spring in gwt, you can do this at two ways:
1) use server side library like gwt-sl to inject spring beans in gwt servlet
#Service("greetingService")
public class GreetingServiceImpl extends RemoteServiceServlet implements GreetingService
{
#SuppressWarnings("unused")
private static final Logger LOGGER = LoggerFactory.getLogger(GreetingServiceImpl.class);
#Autowired
UserFileService userFileService;
#Autowired
UserService userService;
}
now you can autowire spring beans and obtain data via gwt-rpc
2) put data via jsp in hidden html form fields and retriewe data from it
<input type="hidden" value="7" id="documentid"/>
String id = (InputElement) (Element) DOM.getElementById("documentid").value

spring java xml configuration

im using spring for my java web app. the site has got bigger and i would like to set some configurations.
i have been researching and came across things like document builder factory, replacing spring xml with java config and others. i dunno where to start.
im thinking of implementing the configurations in xml (WEB/newConfig.xml) and have it read by the java beans. basically i wanna input my cofiguration values into xml and have it load by a java bean so that i can use it in controllers and jstl.
im just giving some examples here. for example xml configurations:
<property name="numberOfCars" value="3" />
<property name="webSiteName" value="New Spring Web App" />
....
and i read it in my java class:
class Config {
public getNumberOfCars() {
return numOfCars;
}
public getWebSiteName() {
return webSiteName;
}
}
where should i start and what online materials can i read?
==============================
update
here is what i have created.
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd 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 http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<context:property-placeholder location="/WEB-INF/your_prop_file.properties" />
<bean id="ConfigMgr" class="org.domain.class.ConfigMgr">
<property name="username" value="${username}">
</bean>
</beans>
you_prop_file.properties
username=hello world name
ConfigMgr.java
public class ConfigMgr {
private String username;
...getter
...setter
}
in my controller, here is what i did:
ConfigMgr config = new ConfigMgr();
sysout.out.println(config.getUsername());
i am getting null and i am sure im missing something here. where should i set the username value to the ConfigMgr class?
Spring Java configuration is a newer feature that allows you to configure your Spring application using Java classes instead of XML files. Its just an alternative for XML configuration. XML way is equally feature rich.
From what I could figure out from your problem, you want to move the hardcoded values of params (numberOfCars,webSiteName.. ) outisde your configuration file.
If that is the case, you don't have to go that far.
Just use :-
<context:property-placeholder location="classpath:your_prop_file.properties" />
in your spring xml file and replace the param values like:-
<property name="webSiteName" value="${website.name}" />
You need to have a your_prop_file.properties file in your classpath with enteries like:-
website.name=New Spring Web App
You are not injecting the ConfigMgr bean that you created in XML file.
What you are doing is you are creating a new Object in controller which does not have a clue about properties file.
Now you can inject it using either #Autowired inside your controller or through xml configuration.
There are plenty of examples available in google on basic spring dependency injection.

Using/converting an XML file to a Spring bean definition

I have defined a Spring application context xml which will be edited by end users to add new beans.Something like:
<bean name="myBeanName1" class="com.xxx.Yyy">
<property name="type" value="type1" />
<property name="name" value="name1" />
<property name="arguments" value="arg1" />
</bean>
<bean name="myBeanName2" class="com.xxx.Yyy">
<property name="type" value="type2" />
<property name="name" value="name2" />
<property name="arguments" value="arg2" />
</bean>
.
.
.
Now I am asked to change this to a normal xml so that users wont be bothered by bean property and class names:
<def name="Name1">
<type>type1</type>
<argument>arg1</argument
</def>
<def name="Name2">
<type>type2</type>
<argument>arg2</argument
</def>
As my code is using the bean, how can I use the new xml with minimal code change so that it is converted to a bean definition as earlier and things work as before?.
I dont know if Spring has a solution for this out of the box. What I thought was applying stylesheet to the new xml to create my older bean. Any other better/elegant solution for this?
Edit: Now that user input is not inside the bean anymore, is it possible to use the new xml to inject to a #Component class?
Spring supports creating custom tags. You need to create xsd schema, NamespaceHandlerm, implement BeanDefinitionParsers and make spring aware of these by creating spring.handlers & spring.schemas special files.
Have a look at Extensible XML authoring
Example:
<beans xmlns declaration goes here>
<yournamespace:yourcustomtag id="some id">
<yournamespace:some_other_tag your-custom-attribute="some value" />
</yournamespace:yourcustomtag>
</beans>

Categories