清除/初始化Spring中每个HTTP请求的列表(集合)

时间:2017-09-26 06:37:32

标签: java spring list collections

我在Java上工作超过4年,但是刚接触Spring。我在为每个List请求初始化空白PUT时遇到问题。

enter image description here

  • public abstract class BaseX implements InterfaceX
  • public class DefaultX extends BaseX
  • public class DefaultXAndY extends DefaultX

问题:

List中使用的

BaseX未针对每个HTTP PUT请求进行清除。代码如下。

InterfaceX.java

public interface InterfaceX {
    public void process(Long id);
    public void publish();
}

BaseX.java

import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Component;

@Component
public abstract class BaseX implements InterfaceX{
    private List<Long> listLong = new ArrayList<Long>();

    public void addToList(Long id){
        System.out.println("Here in BaseX");
        listLong.add(id);
    }

    @Override
    public void publish() {
        System.out.println("Print list values");
        listLong.stream().forEach(System.out::println);
    }
}

DefaultX.java

import javax.annotation.Resource;

import org.springframework.stereotype.Component;

@Component
@Resource(name = "defaultX")
public class DefaultX extends BaseX{

    @Override
    public void process(Long id) {
        //business logic
        System.out.println("Here in DefaultX");
        addToList(id);
    }
}

DefaultXAndY.java

import javax.annotation.Resource;
import org.springframework.stereotype.Component;

@Component
@Resource(name = "defaultXAndY")
public class DefaultXAndY extends DefaultX{
    @Override
    public void process(Long id) {
        //Business logic different than X
        System.out.println("Here in DefaultXAndY");
        id = id + 10;
        super.process(id);
    }
}

TestService.java

public interface TestService {
    public void testServiceMethod(Long id);
}

TestServiceImpl

import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.orderhive.inventory.service.TestService;
import com.orderhive.inventory.stock.InterfaceX;

@Service
public class TestServiceImpl implements TestService{

    @Autowired
    @Resource(name = "defaultXAndY")
    private InterfaceX interfaceX; 

    @Override
    public void testServiceMethod(Long id) {
        interfaceX.process(id);
        interfaceX.publish();
        System.out.println("API call finished for id: " + id);
        System.out.println("--------------------------------");
    }
}

TestRestController

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.orderhive.inventory.service.TestService;

@RestController
@RequestMapping("/test")
public class TestRestController {

    @Autowired
    private TestService testService; 

    @RequestMapping(method = RequestMethod.PUT, value = "/number/{id}")
    void stockUpdate(@PathVariable Long id){
        testService.testServiceMethod(id);
    }
}

输出

**PUT: localhost:8080/test/number/1**

Here in DefaultXAndY
Here in DefaultX
Here in BaseX
Print list values
11
API call finished for id: 1
--------------------------------
**PUT: localhost:8080/test/number/2**

Here in DefaultXAndY
Here in DefaultX
Here in BaseX
Print list values
11
12
API call finished for id: 2
--------------------------------

List保留了之前请求的值。

=============================================== ============

更新

以下更改对我有用,但这是最佳做法吗?

  • @Component
  • 中删除BaseX@Scope("request")DefaultX 中添加了
  • DefaultXAndY
  • @Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)添加在{anatoly-shamov
  • 建议的TestServiceImpl

=============================================== ============

解决方案:

  • @Component
  • 中删除BaseX@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)DefaultX 中添加了
  • DefaultXAndY

1 个答案:

答案 0 :(得分:1)

BaseXsingleton scope的bean(默认情况下)。这意味着Spring IoC容器中只有一个BaseX实例。该bean的所有请求和引用都返回相同的对象。 您应该使用request scope的单独bean抽象listLong状态。将为每个HTTP请求创建此bean的新实例。

@Component
@Scope(value = "request", proxyMode= ScopedProxyMode.TARGET_CLASS)
public class ListX {
    private List<Long> listLong = new ArrayList<Long>();

    public List<Long> getListLong() {
        return listLong;
    }

    public void setListLong(List<Long> listLong) {
        this.listLong = listLong;
    }
}

在其他组件的listLong值持有者中使用它:

@Component
public abstract class BaseX implements InterfaceX{

    @Autowired
    ListX listHolder;

    public void addToList(Long id){
        System.out.println("Here in BaseX");
        listHolder.getListLong().add(id);
    }

    @Override
    public void publish() {
        System.out.println("Print list values");
        listHolder.getListLong().stream().forEach(System.out::println);
    }
}