[英]Cacheable Annotation in Spring Boot
Service Class服务等级
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");
}
}
ThreadExample Class线程示例类
public class ThreadExample extends Thread{
@Autowired
StudentService studentService;
@Override
public void run() {
studentService.getStudentByID("3","f");
}
}
I have both class and start the threads as :我有两个类并将线程启动为:
for (int i = 0; i < 24; i++) {
new ThreadExample().start();
}
The problem is cacheable annotation does not work here , because it is not a spring bean class.问题是可缓存注解在这里不起作用,因为它不是 Spring bean 类。 But the things I try to do just execute one time getStudentByID(String id,String name) function with same id and name.
但是我尝试做的事情只是执行一次具有相同 ID 和名称的getStudentByID(String id,String name)函数。 How I can do that ?
我怎么能做到这一点? Do you have any idea.
你有什么主意吗。 Thank you
谢谢
StudentService
in ThreadExample
class would be null
because; ThreadExample
类中的StudentService
将为null
,因为;
Spring only autowires components the components it creates.
Spring仅自动装配它创建的组件。 You are calling
new ThreadExample()
, Spring doesn't know about this object so no auto-wiring will take place.您正在调用
new ThreadExample()
, Spring不知道该对象,因此不会发生自动装配。 See https://stackoverflow.com/a/42502608/2039546见https://stackoverflow.com/a/42502608/2039546
There may be 2 different methods for this, depending on your use case;根据您的用例,可能有两种不同的方法;
The first and fastest option is to send the service to the ThreadExample
class with the constructor.第一个也是最快的选择是使用构造函数将服务发送到
ThreadExample
类。 You can do this easily.你可以很容易地做到这一点。
Other option when you create ThreadExample
ask app context to do your auto-wiring.创建
ThreadExample
时的其他选项要求应用程序上下文进行自动连接。 Let me give an example of this.让我举个例子。
The pseudocode will be something like this;伪代码将是这样的;
@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");
}
}
Notice the sync = true
attribute which tells the framework to block any concurrent threads while the value is being computed.注意
sync = true
属性,它告诉框架在计算值时阻塞任何并发线程。 This will make sure that this intensive operation is invoked only once in case of concurrent access.这将确保在并发访问的情况下仅调用一次此密集操作。
The console output is:控制台输出为:
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]
.
.
.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.