Blogs
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.

Filed Under:

Recommended Reading

Exploring TimeMachine: How dotCMS Handles Content Versioning

With dotCMS, tools like TimeMachine and Workflow Management help enterprises control content versioning, content edits, user permissions, workflows and more.

Digital Ambition Requires Ambitious Technology

When it comes to the content foundation of a digital experience platform, critical capabilities are reasonably straightforward. There are only four, really - since security, scalability and containeri...

Optimizing On-page SEO in dotCMS

In this blog, I will show you how to use dotCMS to make your SEO life easier. We'll take a look at code examples of how to programmatically ensure best practices for some of your SEO tasks.

Scripting as a Service: A Look at dotCMS’s Scriptable API Builder

For years, developers have had to build custom REST endpoints to enable brands to deliver experiences to mobile devices, social channels and IoT devices. While this practice is perfectly valid, we hav...