【问题标题】:Use builder pattern in Spring for rest api在 Spring 中使用构建器模式进行休息 api
【发布时间】:2017-10-25 06:05:36
【问题描述】:

我正在 Spring Boot 中创建 rest api,我需要有关在 Spring 中使用构建器模式的最佳方法的建议,因为我是 Spring 新手。

Product.java(数据库实体)

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;
    }
}

以下方法为多个HTTPRequest创建Product的新对象的建议。


方法 1@AutowiredProductBuilder。

@Service
public class xyzServiceImpl implements xyzService{

    @Autowired
    private ProductBuilder productBuilder;

    // business logic
}

xyzServiceImpl 是单例的,所以ProductBuilder 将只创建一个Product 对象,并在Thread/Request 之间共享

HTTP 请求 1Product 初始化为 id = null > 执行保存 > id = 123

HTTP 请求 2:在HTTP Request 1 中更新了对象[Product.id = 123],但我每次都想要新对象

所以我尝试了以下解决方案但没有工作

@Configuration
public class ModelBuilderConfiguration {

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

并在ProductBuilderImpl 中创建initMethod 以创建新对象。

@Configuration
public class ModelBuilderConfiguration {

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

我使用了@Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS),但这也不起作用。

并且使用ThreadLocal 可以与@Autowired 一起使用,但是否推荐使用?

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;
    }
}

方法二:在构造函数中创建新对象。

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;
    }
}

并在xyzServiceImpl 中使用它,就像ProductBuilder productBuilder = new ProductBuilderImpl(); 这样我每次都会得到新对象。

那么考虑到春天,哪种方法最好?或者建议初始化Product对象的更好方法。

【问题讨论】:

  • 您应该自动装配所有您希望 spring 容器为您管理的对象。就像您自己创建它一样,它的生命周期不会由 Spring Container 管理

标签: java spring design-patterns builder-pattern


【解决方案1】:

如果您每次发出请求时都想要一个新的 Product 对象,那么您可以依赖 Spring 进行初始化而忘记构建器。只需将其设为托管 bean 并将其范围设置为请求即可。你可以这样做:

@ManagedBean // or @Component
@RequestScope // or @Scope("request")
public class Product {
    ...
}

并将其注入您的服务。

@Service
public class XyzServiceImpl implements XyzService{

    private final Product product;

    // A proxy is injected, not the actual object.
    @Inject // or @Autowired or none
    public XyzServiceImpl(Product product) {
        this.product = product;
    }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-08
    • 2011-03-15
    • 1970-01-01
    • 2021-10-28
    • 1970-01-01
    • 2019-01-11
    • 1970-01-01
    • 2018-01-01
    相关资源
    最近更新 更多