VOOZH about

URL: https://www.javacodegeeks.com/2015/03/using-spring-managed-bean-in-non-managed-object.html

⇱ Using Spring managed Bean in non-managed object - Java Code Geeks


We have to deal with legacy code, even when we would like to use the best and newest technologies available. Imagine the new code is written with the newest technologies of the Spring Framework and the legacy code is not written in Spring at all. Then using Spring managed Beans in non-managed Spring objects is one of the patterns we have to deal with. The legacy code has non-managed Spring objects, while the code we want to reference to is a Spring managed Bean. How do we solve this problem?

Create a Spring Bean

Let’s assume we have a managed Spring Bean called TaxService and an object called LegacyObject. The LegacyObject is the legacy code from where we would make a reference to the method calculateTax on the managed Spring Bean.

TaxService

package com.jdriven;

import org.springframework.stereotype.Service;

@Service
public class TaxServiceImpl
 implements TaxService {

 @Override
 public Double calculateTax(Double price) {
 return new Double(price * 0.21);
 }
}

Interface with bridged service methods

We define an interface which contains a list of methods. Each of these methods return a Spring managed Bean. We create a method called getTaxService to return our just created TaxService Bean.

SpringContextBridgedServices

package com.jdriven;

/**
 * This interface represents a list of Spring Beans (services) which need to be referenced from a non Spring class.
 */
public interface SpringContextBridgedServices {
 TaxService getTaxService();
}

Implement the Spring Context Bridge

Next, we create an implementation for the SpringContextBridgedServices interface. Let’s call this class SpringContextBridge and make it a Spring Bean and add the following functionality in the class.

  1. This class should also implement the ApplicationContextAware interface from Spring. The only argument in the method we need to implement from the interface is the argument ApplicationContext. We hold this argument in a static member variable.
  2. Create a static method to return the SpringContextBridgedServices and let this method return the Bean which is managed by Spring. Use applicationContext.getBean(SpringContextBridgedServices.class) to return it.
  3. Autowire the TaxService and return it in the method we need to implement from the SpringContextBridgedServices method.

SpringContextBridge

package com.jdriven;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**
* Register this SpringContextBridge as a Spring Component.
*/
@Component 
public class SpringContextBridge 
 implements SpringContextBridgedServices, ApplicationContextAware {

 private static ApplicationContext applicationContext;

 @Autowired
 private TaxService taxService; //Autowire the TaxService

 @Override
 public void setApplicationContext(ApplicationContext applicationContext) 
 throws BeansException {
 this.applicationContext = applicationContext;
 }

 /**
 * A static method to lookup the SpringContextBridgedServices Bean in 
 * the applicationContext. It is basically an instance of itself, which 
 * was registered by the @Component annotation.
 *
 * @return the SpringContextBridgedServices, which exposes all the 
 * Spring services that are bridged from the Spring context.
 */
 public static SpringContextBridgedServices services() {
 return applicationContext.getBean(SpringContextBridgedServices.class);
 }

 @Override
 public TaxService getTaxService() {
 return taxService; //Return the Autowired taxService
 }
}
  • Note 1: It is a possibility to return a Spring managed bean in a static method itself. I choose not to do this, so I have less static methods and can later Mock some of the references Services.
  • Note 2: Eventually you would like to split up the two functionalities. One holding the ApplicationContext and returning the SpringContextBridgedServices Bean. The other being the SpringContextBridgedServices Bean itself. In this short demo I just put them in the same Bean.

Take me to the Bridge

Now it’s time to call the bridge. This is as simple as demonstrated in the code below.

LegacyObject

package com.jdriven;

public class LegacyObject {

 private Double price;

 public Double doTheCalculation() {
 //Get the Service from the Bridge
 TaxService taxService = SpringContextBridge.services().getTaxService();
 return taxService.calculateTax(this.price);
 }
}

Flexible but non-restricted alternative

This is a way in which the list of bridged services is restricted. Only the services mentioned in the SpringContextBridgedServices interface will be bridged. If you want a more flexible but less controlled way, you can rewrite the SpringContextBridgedServices.

SpringContextBridgedServicesAlternative

package com.jdriven;

public interface SpringContextBridgedServicesAlternative {

 <T> T getService(Class<T> serviceType);
}

Now we can get a service by calling SpringContextBridge.services().getService(TaxService.class). In this alternative we have no control over which Spring managed Bean may be bridged.

Reference: Using Spring managed Bean in non-managed object from our JCG partner Willem Cheizoo at the JDriven blog.
Do you want to know how to develop your skillset to become a Java Rockstar?
Subscribe to our newsletter to start Rocking right now!
To get you started we give you our best selling eBooks for FREE!
1. JPA Mini Book
2. JVM Troubleshooting Guide
3. JUnit Tutorial for Unit Testing
4. Java Annotations Tutorial
5. Java Interview Questions
6. Spring Interview Questions
7. Android UI Design
and many more ....
I agree to the Terms and Privacy Policy

Thank you!

We will contact you soon.

Tags
Spring
πŸ‘ Photo of Willem Cheizoo
Willem Cheizoo
March 12th, 2015Last Updated: March 11th, 2015
4 355 3 minutes read
Subscribe

This site uses Akismet to reduce spam. Learn how your comment data is processed.

4 Comments
Oldest
Newest Most Voted
Daniel
9 years ago

Hello,
I have another solution for this https://danjee.github.io/hedgehog/

0
Reply
7 years ago

This throws a null pointer exception

0
Reply
khang
7 years ago

Code very good, run fasst

0
Reply
6 years ago

thanks a lot, you save my half day.

0
Reply
Back to top button
Close
wpDiscuz