我从事Java已有4年以上,但对Spring还是陌生的。我在为每个单个List
请求初始化空白PUT
时遇到问题。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
最佳答案
BaseX
是singleton 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/