我在Java上工作超过4年,但是刚接触Spring。我在为每个List
请求初始化空白PUT
时遇到问题。
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
答案 0 :(得分:1)
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);
}
}