mercredi 25 octobre 2017

Use builder pattern in Spring for rest api

I'm creating rest api in spring boot and I need suggestions on whats the best approach to use builder pattern in Spring because I'm new to Spring.

Product.java (Database entity)

public class Product{
    private String name;
    private String sku;

    //getter-setter
}

ProductBuilder.java

public interface ProductBuilder {
    public ProductBuilder setBasicDetails(String name, String sku)
}

ProductBuilderImpl.java

public class ProductBuilderImpl implements ProductBuilder{

    // issue is with creating new object of `Product`

    @Override
    public ProductBuilder setBasicDetails(String name, String sku) {
        product.setName(name);
        product.setSku(sku);
        return this;
    }
}

Suggestions for creating new object of Product for multiple HTTPRequest in following approaches.


Approach 1: @Autowired ProductBuilder.

@Service
public class xyzServiceImpl implements xyzService{

    @Autowired
    private ProductBuilder productBuilder;

    // business logic
}

xyzServiceImpl is singleton so ProductBuilder will create only one object of Product and its shared between Thread/Request

HTTP Request 1: Product is initialized with id = null > Perform save > id = 123

HTTP Request 2: Got the object[Product.id = 123] updated in HTTP Request 1 but I want new object every time.

So I tried following solution but not working

@Configuration
public class ModelBuilderConfiguration {

    @Bean
    @Scope(value = "prototype")
    public ProductBuilder productBuilder(){
        return new ProductBuilderImpl();
    }
}

and creating initMethod in ProductBuilderImpl to create new object.

@Configuration
public class ModelBuilderConfiguration {

    @Bean(initMethod = "initMethod")
    @Scope(value = "prototype")
    public ProductBuilder productBuilder(){
        return new ProductBuilderImpl();
    }
}

and I used @Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS) but this is also not working.

And using ThreadLocal works with @Autowired but is it recommended?

public class ProductBuilderImpl implements ProductBuilder{

    private ThreadLocal<Product> product = new ThreadLocal<Product>(){
        @Override
        protected Product initialValue() {
            return new Product();
        }
    };

    @Override
    public ProductBuilder setBasicDetails(String name, String sku) {
        product.get().setName(name);
        product.get().setSku(sku);
        return this;
    }
}

Approach 2: Create new object in constructor.

public class ProductBuilderImpl implements ProductBuilder{

    private Product product;

    public ProductBuilderImpl() {
        product = new Product();
    }

    @Override
    public ProductBuilder setBasicDetails(String name, String sku) {
        product.setName(name);
        product.setSku(sku);
        return this;
    }
}

And use it in xyzServiceImpl like ProductBuilder productBuilder = new ProductBuilderImpl(); so I'll get the new object every time.

So which is best approach considering spring? Or suggest better way for initializing Product object.

Aucun commentaire:

Enregistrer un commentaire