Announcement Announcement Module
Collapse
No announcement yet.
Using PropertyPlaceHolderConfigurer question Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Using PropertyPlaceHolderConfigurer question

    In section 3.8 of the docs they give some examples on how to use this with a BeanFactory, then say,

    An ApplicationContext will detect any beans which are deployed into it which implement the BeanFactoryPostProcessor interface, and automatically use them as bean factory post-processors, at the appropriate time. Nothing else needs to be done other than deploying these post-processor in a similar fashion to any other bean.


    I'm not sure what that means, exactly. Can someone give a concrete example of how this might be used with an ApplicationContext?

  • #2
    Any bean that implements the BeanPostProcessor interface will automatically be notified when other beans are instantiated and configured. It has the opportunity to take additional steps in that case, or even wrap the object in a proxy.

    This is an important extension point of Spring. BeanPostProcessors are very easy to write: I suggest that you write a simple logging BeanPostProcessor and add that definition to your context to see what happens. Simply the return the object (the bean instance) passed in to each method, and log the name of the object.

    Comment


    • #3
      Hi mcampbell

      Find below some configuration and code to get you started with the workings of the BeanFactoryPostProcessor (BFPP) functionality. I apologise somewhat for the twee example class (Foo), but the intent is that you focus on the BFPP bits.

      Here is the bean that is going to be instantiated, configured and otherwise assembled by the Spring IoC container.

      Code:
      package x.y;
      
      public class Foo {
      
      	private String message;
      
      	public void setMessage(String message) {
      		this.message = message;
      	}
      
      	public void bing() {
      		System.out.println(this.message);
      	}
      }
      And here is the attendant configuration. Notice how the value of the 'message' property is actually a placeholder (in the Ant style). Notice also the other bean definition for a PropertyPlaceHolderConfigurer. The job of this BFPP implementation is to replace any ${xxx} placeholders that it finds in bean definitions with values read from system/environment variables or indeed from a list of properties supplied to it (in this case, the properties in the 'message.properties' file at the root of the classpath).

      Code:
      <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="foo" class="x.y.Foo">
      		<property name="message" value="${replace.me}"/>
      	</bean>
      	
      	<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
      		<property name="location" value="classpath:message.properties"/>
      	</bean>
      
      </beans>
      Notice how the PPHC doesnlt even have a name; it is automatically recognised as a BFPP and instantiated by the Spring IoC container.

      Find below the contents of the 'messages.properties' file.

      Code:
      replace.me=Fiona Apple really needs some UK tour dates
      Here is a driver script.

      Code:
      import org.springframework.context.support.ClassPathXmlApplicationContext;
      import org.springframework.context.ApplicationContext;
      import x.y.Foo;
      
      public final class Boot {
      
      	public static void main(final String[] args) throws Exception {
      		ApplicationContext ctx = new ClassPathXmlApplicationContext("x/y/plain.xml");
      		Foo foo = (Foo) ctx.getBean("foo");
      		foo.bing();
      	}
      }
      And here is the attendant output (somewhat cleaned up); notice how the PPHC is never explicitly referred to by the user code - simply defining it is enough.

      Code:
      INFO: Pre-instantiating singletons in factory [org.springframework.beans.factory.support.DefaultListableBeanFactory defining beans [foo,org.springframework.beans.factory.config.PropertyPlaceholderConfigurer]; root of BeanFactory hierarchy]
      Fiona Apple really needs some UK tour dates
      
      Process finished with exit code 0
      Hope this helps, cheers
      Rick

      Comment


      • #4
        Thanks guys; this helped immensely.

        If I may, a "best practice" question.

        I have a (web app) product that will be deployed to a "production" site, in which I have rather strict requirements in what I can and cannot do. In a nutshell, I'm required to have the configuration of the application outside the war, so that our operations staff can change the configuration w/o having to explode the war, re-archive it, etc.

        My plan was to have a WEB-INF/appcontext.xml file for the things that they won't need to touch, then use some combination of the PPHC, properties files, and a programatic loading of another appcontext.xml outside the war. The operations staff would then only have to deal with the properties file.

        I'd be curious if this sort of pattern is common, and what's the common way to solve it.

        Thanks,

        michael

        Comment


        • #5
          see this thread: http://forum.springframework.org/showthread.php?t=29300

          HTH

          Comment

          Working...
          X