Thêm một lớp bên trong JAR của bạn với đoạn mã sau:
public class TomcatStartupListener implements org.apache.catalina.LifecycleListener {
public void lifecycleEvent(org.apache.catalina.LifecycleEvent event) {
if (event.getType().equals("after_start")) {
// call your main method here
}
}
}
Lưu ý: Để biên dịch này, bạn cần phải thêm <tomcat-dir>/lib/catalina.jar
vào classpath của bạn. Nếu không, khi biên dịch nó sẽ không thể tìm thấy các giao diện cần thiết (org.apache.catalina.LifecycleListener
và org.apache.catalina.LifecycleEvent
). Khi bạn đã hoàn tất việc biên dịch, hãy đặt JAR như bình thường dưới <tomcat-dir>/lib
.
Bây giờ mở <tomcat-dir>/conf/server.xml
và thêm dòng sau dưới phần <Server>
:
<Listener className="com.yourpackage.TomcatStartupListener" />
Bây giờ bất cứ khi nào máy chủ Tomcat của bạn bắt đầu, lớp này TomcatStartupListener
bên JAR của bạn sẽ được gọi, và bạn có thể gọi phương thức chính của bạn. Có rất nhiều loại sự kiện khác nữa!Bạn có thể sử dụng bất kỳ các loại sự kiện:
- before_init
- after_init
- before_start
- configure_start
- bắt đầu
- after_start
- before_stop
- dừng
- configure_stop
- after_stop
- before_destroy
- after_destroy
Cách tiếp cận này là cần thiết vì cách làm việc (JVM hoặc thậm chí hầu hết) classloaders work in Tomcat. Dưới đây là các điểm quan trọng từ liên kết đó:
There are three aspects of a class loader behavior
Lazy Loading
Class Caching
Separate Namespaces
JVM sẽ rất nặng nếu tất cả các lớp trong tất cả các JAR được tải bừa bãi. Vì vậy, các lớp bên trong các tệp JAR được chia sẻ chỉ được tải theo yêu cầu. Cách duy nhất để bạn gọi phương thức chính là thêm trình nghe vòng đời trên.
Tôi có một số mã khía cạnh trong thư viện của mình mà tôi muốn dệt tất cả các ứng dụng đang chạy trong jvm, khi tôi nhóm jar vào tệp chiến tranh, mã aspectj sẽ chỉ dệt vào các lớp trong tệp chiến tranh. – Sammy
Đoán phương thức này sẽ không hoạt động, vì nó không thực hiện các lớp hoặc lớp toàn cục trong các tệp WAR khác. Xin vui lòng xem giải pháp của tôi dưới đây nếu nó phù hợp. – Subhas