服務等級
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
@Service
public class StudentService{
@Cacheable(value = "student",key = "{#id,#name}")
public Student getStudentByID(String id,String name)
{
return new Student(id,name ,"V");
}
}
執行緒示例類
public class ThreadExample extends Thread{
@Autowired
StudentService studentService;
@Override
public void run() {
studentService.getStudentByID("3","f");
}
}
我有兩個類并將執行緒啟動為:
for (int i = 0; i < 24; i ) {
new ThreadExample().start();
}
問題是可快取注解在這里不起作用,因為它不是 Spring bean 類。但是我嘗試做的事情只是執行一次具有相同 ID 和名稱的getStudentByID(String id,String name)函式。我怎么能做到這一點?你有什么主意嗎。謝謝
uj5u.com熱心網友回復:
StudentServiceThreadExample上課是因為null;
Spring僅自動裝配它創建的組件。你在打電話
new ThreadExample(),Spring不知道這個物件,所以不會發生自動連接。見https://stackoverflow.com/a/42502608/2039546
根據您的用例,可能有兩種不同的方法;
第一個也是最快的選擇是使用建構式將服務發送到
ThreadExample類。你可以很容易地做到這一點。當您創建
ThreadExample詢問應用程式背景關系以進行自動裝配時的其他選項。讓我舉個例子。
偽代碼將是這樣的;
@Controller
public class TestController {
private final ApplicationContext applicationContext;
public TestController(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
@GetMapping(value = "/test")
public void test() {
ThreadExample threadExample = new ThreadExample();
applicationContext.getAutowireCapableBeanFactory()
.autowireBean(threadExample);
for (int i = 0; i < 24; i ) {
Thread thread = new Thread(threadExample);
thread.start();
}
}
}
public class ThreadExample implements Runnable {
@Autowired
private StudentService studentService;
@Override
public void run() {
long threadId = Thread.currentThread().getId();
String threadName = Thread.currentThread().getName();
System.out.println(String
.format("Thread has been called! [threadId=%s, threadName=%s]",
threadId, threadName));
Student student = studentService.getStudentByID("3", "f");
System.out.println(String
.format("Thread has been completed. [threadId=%s, threadName=%s, studentId=%s]",
threadId, threadName, student.getId()));
}
}
@Service
public class StudentService {
@Cacheable(value = "students", key = "{#id, #name}", sync = true)
public Student getStudentByID(String id, String name) {
System.out.println(String
.format("getStudentById() has been called! [id=%s, name=%s]", id, name));
return new Student(id, name , "V");
}
}
請注意該sync = true屬性告訴框架在計算值時阻止任何并發執行緒。這將確保在并發訪問的情況下僅呼叫一次此密集操作。
控制臺輸出為:
Thread has been called! [threadId=40, threadName=Thread-7]
Thread has been called! [threadId=41, threadName=Thread-8]
Thread has been called! [threadId=42, threadName=Thread-9]
Thread has been called! [threadId=43, threadName=Thread-10]
.
.
.
getStudentById() has been called! [id=3, name=f] <- ONLY WORKED ONCE!
Thread has been completed. [threadId=54, threadName=Thread-21, studentId=3]
Thread has been completed. [threadId=55, threadName=Thread-22, studentId=3]
Thread has been completed. [threadId=57, threadName=Thread-24, studentId=3]
Thread has been completed. [threadId=47, threadName=Thread-14, studentId=3]
Thread has been completed. [threadId=42, threadName=Thread-9, studentId=3]
.
.
.
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/490381.html
上一篇:在運行控制器測驗時包括安全過濾器
