Create bean in spring context - java

<bean id="configuration" class="com.mypackage.util.Configuration" factory-method="getInstance">
<property name="path" value="${path.props.app.dev}"></property>
</bean>
Then I have the following in my class
Configuration.getInstance();
Whereas the spring application context is loaded in another class Factory like this
private Factory() {
context = new ClassPathXmlApplicationContext("META-INF/spring.xml");
}
The problem is that before Factory class is accessed the context does not load and the configuration object gives null for path whereas when Factory is accessed and after that path property is accessed it gives the correct path.
Please tell me how to do it correctly? That is how can i get my member variable path with correct data without accessing Factory class.

Assuming that you are using Spring WebMVC. There are 2 ways:
Putting you bean configurations to dispatcher config XML (mvc-dispatcher-servlet.xml)
Remain your spring.xml and specify it in web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>spring.xml</param-value>
</context-param>
In both cases, you will no longer need a class like Factory. Besides, because of that Spring creates beans in singleton scope by default, you do not need to implement a getInstance() method for your com.mypackage.util.Configuration class.

Related

Injecting property files overriding the one defined in the application

I need some help on injecting property value to a bean which is defined outside the web application.
The web application has a property file under src/main/resource.The spring application context xml has the property place holder defined as
<context:property-placeholder
location="classpath:test.properties,file:/etc/test1.properties"
ignore-resource-not-found="true"
/>
where test1.properties is another file which resides outside the application.The bean is injected with the property which is defined in the application (test.properties) ,but I want to inject the property that is defined in test1.properties (ideally the idea is to override the property values from application and read the one defined outside the application).
Thanks.
Hi use like below in applicationContext.xml
<util:properties id="property" location="classpath:test.properties"/>
In Java,
#Autowired
protected Properties property;
I guess this is what you are looking for
<context:property-placeholder location="file:c:/kp/sec.properties" order="1" ignore-resource-not-found="true" ignore-unresolvable="true" />
<context:property-placeholder location="classpath:kp-props.properties" order="2" />
If the file sec.properties exists take the value from sec.properties, if file or properties does not exist take the property from kp-props.properties file from resources directory(if the property is not found in either of place application will fail)
And say you have property my.prop and you can inject the property as follows.
#Component
public class KPProps {
#Value("${my.prop}")
private int props;
public void print(){
System.out.println(props);
}
}

Loading a Map in field of Class Object, before the Class instance is returned by getBean method of Spring?

I have a .properties file having 10 key-values pairs say age =10, name=Jon etc. I have configured a bean in spring which has a map as a member variable.
When the bean is loaded by Spring once I call the getBean method, before that the Map should be loaded with the properties from files. How to do that ?
I know this should be done in one of the lifecycle methods like afterPropertiesSet using InitializingBean or init-method configuration. Is there any other better way to do this ?
You can enable annotations in your beans:
<context:annotation-config />
Then you can define method with #PostConstruct annotation. Spring will execute it during bean initialization process:
class MyBean {
private Map<String, String> properties;
#PostConstruct
public void initialize() {
// read properties and initialize map
}
}
Another option is to inject Properties directly into your bean and provide map-like API to access them:
<util:properties id="myProperties" location="classpath:my-props.properties">
<bean id="myBean" class="com.example.MyBean">
<property name="properties" ref="myProperties" />
</bean>
you can use context property-placeholder within XML spring configuration file using ${...} or from java class configuration file using #value.

initializing java.util.ArrayList using spring bean

i'm developing a web application using spring 3. i'm using tomcat 6 as the web container.
in my web.xml file i bound the file named applicationContext.xml as the spring definition file.
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
from inside the applicationContext.xml file i'm trying to initialize a array list variable using the spring bean definition. i'm following the below configurations.. (im using jidea)
<bean id="registationController" class="com.test.RegistrationController">
<property name="registrationService" ref="registrationService"/>
<property name="validUrlsList" ref="myList"/>
</bean>
<util:list id="myList" value-type="java.lang.String">
<value>10.1.200.104</value>
<value>10.1.200.205</value>
</util:list>
i have loaded the
xmlns:util="http://www.springframework.org/schema/util"
namespace, and in RegistrationController.java class i have generated the getter and setter for the validUrlsList variable, jidea shows that my definitions are correct and i have properyly bound my vaiable to the bean definition. but when i try out the code it doesn't initialize the validUrlList variable? it's giving a null value? any thing i'm doing wrong here? any suggestions to sort this out?
java code is as follows.,,
private ArrayList validUrlsList;
public void setValidUrlsList(ArrayList validUrlsList) {
this.validUrlsList = validUrlsList;
}
public ArrayList getValidUrlsList() {
return validUrlsList;
}
then i call the method getRemoteIp by just passing the variable as follows.
if (getRemoteIP(req, validUrlsList)) {
-- Regards,Rangana
util:list is creating java.util.List instance, it is not said to create java.util.ArrayList.
You should change your declaration from
private ArrayList validUrlsList;
to
private List validUrlsList;
(and setter and getter as well).

Spring as a JNDI provider?

I would like to use Spring as a JNDI provider. This means that I would like to configure a bean in my Spring context, which can be accessed via JNDI. This would look something like this:
<bean class="org.some.thing.here">
<property name="beans">
<map>
<entry key="w/t/f">
<bean class="some.thing.Else">
// rest ommitted
</bean>
</entry>
</map>
</property>
</bean>
Then, in my application (lets say a Controller), I want to be able to grab this bean via:
Context ctx = new InitialContext();
some.thing.Else bar = (some.thing.Else) ctx.lookup("w/t/f");
How could I go about doing this? I've looked at XBean, however the project looks out of date (doesn't work with Spring 3.0.X I don't think), and there is very little documentation.
Any other options? I would also considering rolling my own jndi provider class if it isn't too hard to do.
EDIT: I should add that I don't have an option using JNDI, I have a library we have to use which requires certain components to be loaded via JNDI. I would like to use Spring as the provider.
Why use JNDI at all? Just get the Spring ApplicationContext and get the bean from that.
Assuming you initialized Spring using ContextLoaderListener in your webapp, you should be able to retrieve the application context from the ServletContext. From there you can get any bean you declared in Spring.
ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(servletContext);
Object bean = context.getBean(some.thing.Else.class);
If you have to use JDNI, then you can create a ServletContextListener that does something like the following in contextInitialized():
ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(servletContext);
Object bean = context.getBean(some.thing.Else.class);
Context initCtx = new InitialContext();
Context springCtx = initCtx.createSubcontext("spring");
springCtx.bind("bean", bean);
Then, you should be able to lookup the Spring bean at "spring/bean" from the InitialContext.
Two things to note:
The context listener should probably also call initCtx.destroySubcontext("spring") in contextDestroy too.
The java:comp/env namespace is read-only (in Tomcat at least), so you can't put anything there.
Asker edit: Just a couple more points of clarity...
If you plan on referencing Spring beans via ApplicationContext, then you need a ContextLoaderListener defined in your web.xml. This must be defined before your custom listener class... like so:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>
org.example.sandbox.MyCustomServletContextListener
</listener-class>
</listener>
Also, you can get the ServletContext that getWebApplicationContext uses from the ServletContextEvent, like so:
#Override
public void contextInitialized(ServletContextEvent contextEvent) {
try {
ApplicationContext appContext = WebApplicationContextUtils.getWebApplicationContext(contextEvent.getServletContext());
// get a bean named "myCalendar" from the application context
Calendar cal = (Calendar)appContext.getBean("myCalendar");
// bind via JNDI
Context initialContext = new InitialContext();
Context subCtx = initialContext.createSubcontext("sample");
subCtx.bind("calendar", cal);
} catch (NamingException e) { // ommitted }
}
AngerClown is right, don't bother with JNDI unless you need to provide references to other modules that insist on it. If you are in a webapp container like Tomcat, it will have a JNDI registry. Use that. If not inside a webapp container, it doesn't make sense to have JNDI anyway, since it's for J2EE environments.
Assuming you are inside a webapp, a better way to launch your app is to have the main class be a Spring bean that implements lifecycle interfaces (like InitializingBean) to get a call when it's time to start your app. By that point, your main application class will have been injected with all it's dependencies. This avoids the need to call methods on the ApplicationContext directly.
Even so, if you must call methods on the ApplicationContext and you are launched by Spring, you can implement BeanContextAware and get injected with the context.
Yet another way to write your own JndiExporter
https://blog.konstantinpavlov.net/2008/12/31/how-to-export-spring-bean-to-jndi/

How do I force a spring container not to return a singleton instance of a bean?

When I call getBean(name) on a BeanFactory, I get back an instance of the bean defined in the application context. However, when I call getBean(name) again (with the same name,) I get the same instance of the bean back. I understand how this would be desirable in some (many?) cases, but how do I tell the BeanFactory to give me a new instance?
Example Spring configuration (tersely...I've left out some verbosity, but this should get the point across):
<beans>
<bean id="beanA" class="misc.BeanClass"/>
</beans>
Example Java:
for(int i = 0;i++;i<=1) {
ApplicationContext context = ClassPathXmlApplicationContext("context.xml");
Object o = context.getBean("beanA");
System.out.println(o.toString()); // Note: misc.BeanA does not implement
// toString(), so this will display the OOID
// so that we can tell if it's the same
// instance
}
When I run this, I get something like:
misc.BeanClass#139894
misc.BeanClass#139894
Note that both have the same OOID...so these are the same instances...but I wanted different instances.
You need to tell spring that you want a prototype bean rather than a singleton bean
<bean id="beanA" class="misc.BeanClass" scope="prototype"/>
This will get you a new instance with each request.
The default scope is singleton, but you can set it to prototype, request, session, or global session.

Categories