我从事Java已有4年以上,但对Spring还是陌生的。我在为每个单个List请求初始化空白PUT时遇到问题。

java - 在Spring中为每个HTTP请求清除/初始化List(Collection)-LMLPHP


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


问题:

对于每个HTTP List请求,不会清除类BaseX中使用的PUT。代码如下。

接口X.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
@ anatoly-shamov建议在@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)中添加的TestServiceImpl


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

解:


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

最佳答案

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

关于java - 在Spring中为每个HTTP请求清除/初始化List(Collection),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46419388/

10-10 12:28