Back
Will Ezell
Chief Technology Officer

Accessing Spring Beans from an OSGI Plugin

Feb 23, 2013

By: Will Ezell

In Spring you can create a bean, configure it and build declaratively by the Spring container.
In a dotCMS OSGI plugin, we provide a method to set and load a plugin specific context file from the plugin's Activator, but there is no built-in way to access the context once it's been loaded.

To obtain a reference to your custom created Spring Beans you would use the context like this:

context = new ClassPathXmlApplicationContext("/mycontext.xml");
MyBean mybean = (MyBean) context.getBean("MyBean");

In OSGI, each bundle has its own classpath, and when deployed to the OSGI container the code above will throw an exception because it can't find the file in the classpath.

To work around this issue we can create an ApplicationContextAware Bean, which we will call: SpringApplicationContext, and instantiate it in the Spring container by defining it in the spring configuration file that is loaded in the plugin's Activator. Because it is ApplicationContextAware, Spring will populate it with a reference to the ApplicationContext.

ds.setContextConfigLocation( "spring/example-servlet.xml" );

This is the bean definition we added to the example-servlet.xml file:

<bean id="springApplicationContext" class="com.dotmarketing.osgi.spring.SpringApplicationContext"></bean>

The class SpringApplicationContext implements: ApplicationContextAware and has a static variable CONTEXT that will hold a reference to the ApplicationContext.

public class SpringApplicationContext implements ApplicationContextAware {
  private static ApplicationContext CONTEXT;

This class provides a static method: getBean() that calls ApplicationContext.getBean() using it's static variable CONTEXT. This method will return the reference to the bean requested by name.

  public static Object getBean(String beanName) {
    return CONTEXT.getBean(beanName);
  }

Now all we have to do is create a bean, and add it to the spring/example-servlet.xml file.
In this example we created a bean named: HelloWorldBean with the following code:

public class HelloWorldBean {

  public String getHelloMessage(String userName) {
        // set the message
        String aMessage = (userName != null)
                ? "Hello EDIT " + userName + ", welcome to Spring  3.1 and dotCMS!  "
                : "Hello Total Stranger, welcome to Spring  3.1 and dotCMS!  ";
        return aMessage;
  }

  public String getHelloMessage() {
        // set the message
        String aMessage = "Hello World, Spring 3.1 and dotCMS!";
        return aMessage;
  }
}

We define the bean in the spring/example-servlet.xml file like this

  <bean id="helloWorldBean" class="com.dotmarketing.osgi.spring.HelloWorldBean"></bean>

To get a reference to our Bean to call its methods, we need to use the SpringApplicationContext class like this:

HelloWorldBean helloWorldBean = (HelloWorldBean) SpringApplicationContext.getBean("helloWorldBean");
String message = helloWorldBean.getHelloMessage();

In our example we call getHelloMessage() from our Spring Controller, allowing the Controller and any other classes included in your OSGI plugin to use your Spring Beans.

Click here to download the entire code used in this example.

Filed Under:

Recommended Reading

Submitting Content Securely

This post will give you a brief idea of how the basic submit process provided by the dotCMS Form Handler functionality has been modified to achieve a higher lever of security.

Developing a Forum in dotCMS

The forum plugin was developed as a way to easily deploy the common functionalities of a forum on your dotCMS website. Although a plugin needs to be deployed to take advantage of all of the features,...

Navigating OSGi - Extending Your Software to Embed an OSGi Framework

You have your software in place, but you need a better way of allowing your technical users to extend the platform. Most Java developers are aware of OSGi, but embedding an OSGi framework into your pr...