1 在使用jpa的復雜查詢時,聲明了specification時聲明為靜態方法,導致注入的service無法使用,故想到倆種方式,一種手動注入,一種注解注入,此文使用的時注解注入;
解決靜態方法調用注入的service
1 // 先說一下解決方法 2 @Autowired 3 private AService aService; 4 5 // 聲明靜態變量,為了之后調用service 6 public static ClassA classA; 7 8 // 關鍵:通過注解實現注入 9 @PostConstruct 10 public void init() { 11 classA = this; 12 veesimpl.aService = aService;9 } 13 14 // 使用 15 veesimpl.aService.方法;
java開發之@PostConstruct執行順序
1 構造函數==》postConstruct==>init==destory==>predestory==卸載servlet;; 2 3 從Java EE5規范開始,Servlet增加了兩個影響Servlet生命周期的注解(Annotation):@PostConstruct和@PreConstruct。這兩個注解被用來修飾一個非靜態的void()方法.而且這個方法不能有拋出異常聲明。 4 5 使用方式,例如: 6 7 8 1 @PostConstruct //方式1 9 2 public void someMethod(){ 10 3 ... 11 4 } 12 5 13 6 public @PostConstruct void someMethod(){ //方式2 14 7 ... 15 8 } 16 17 1.@PostConstruct說明 18 19 被@PostConstruct修飾的方法會在服務器加載Servlet的時候運行,並且只會被服務器調用一次,類似於Serclet的inti()方法。被@PostConstruct修飾的方法會在構造函數之后,init()方法之前運行。 20 21 2.@PreDestroy說明 22 23 被@PreDestroy修飾的方法會在服務器卸載Servlet的時候運行,並且只會被服務器調用一次,類似於Servlet的destroy()方法。被@PreDestroy修飾的方法會在destroy()方法之后運行,在Servlet被徹底卸載之前。(詳見下面的程序實踐) 24 25 3.程序實踐 26 27 web.xml 28 29 30 1 <!-- @PostConstruct和@PreDestroy注解 --> 31 2 <servlet> 32 3 <servlet-name>AnnotationServlet</servlet-name> 33 4 <servlet-class>com.servlet.AnnotationServlet</servlet-class> 34 5 </servlet> 35 6 <servlet-mapping> 36 7 <servlet-name>AnnotationServlet</servlet-name> 37 8 <url-pattern>/servlet/AnnotationServlet</url-pattern> 38 9 </servlet-mapping> 39 40 AnnotationServlet 41 42 1 package com.servlet; 43 2 44 3 import java.io.IOException; 45 4 import java.io.PrintWriter; 46 5 import java.sql.Time; 47 6 import java.text.SimpleDateFormat; 48 7 import java.util.Date; 49 8 50 9 import javax.annotation.PostConstruct; 51 10 import javax.annotation.PreDestroy; 52 11 import javax.servlet.ServletException; 53 12 import javax.servlet.http.HttpServlet; 54 13 import javax.servlet.http.HttpServletRequest; 55 14 import javax.servlet.http.HttpServletResponse; 56 15 57 16 public class AnnotationServlet extends HttpServlet { 58 17 SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss.SSS");//設置日期格式,精確到毫秒 59 18 60 19 public AnnotationServlet(){ 61 20 System.out.println("時間:"+df.format(new Date())+"執行構造函數..."); 62 21 } 63 22 64 23 public void destroy() { 65 24 this.log("時間:"+df.format(new Date())+"執行destroy()方法..."); 66 25 //super.destroy(); // Just puts "destroy" string in log 67 26 // Put your code here 68 27 } 69 28 70 29 @PostConstruct 71 30 public void someMethod(){ 72 31 //this.log("執行@PostConstruct修飾的someMethod()方法...");//注意:這樣會出錯 73 32 System.out.println("時間:"+df.format(new Date())+"執行@PostConstruct修飾的someMethod()方法..."); 74 33 } 75 34 76 35 @PreDestroy 77 36 public void otherMethod(){ 78 37 System.out.println("時間:"+df.format(new Date())+"執行@PreDestroy修飾的otherMethod()方法..."); 79 38 } 80 39 81 40 public void doGet(HttpServletRequest request, HttpServletResponse response) 82 41 throws ServletException, IOException { 83 42 this.log("時間:"+df.format(new Date())+"執行doGet()方法..."); 84 43 } 85 44 86 45 public void init() throws ServletException { 87 46 // Put your code here 88 47 this.log("時間:"+df.format(new Date())+"執行init()方法..."); 89 48 } 90 49 91 50 protected void service(HttpServletRequest request, HttpServletResponse response) 92 51 throws ServletException, IOException{ 93 52 this.log("時間:"+df.format(new Date())+"執行service()方法..."); 94 53 super.service(request, response); 95 54 } 96 55 97 56 } 98 99 運行結果: 100 101 102 103 4.注意事項 104 105 注解多少會影響服務器的啟動速度。服務器在啟動的時候,會遍歷Web應用的WEB-INF/classes下的所有class文件與WEB-INF/lib下的所有jar文件,以檢查哪些類使用了注解。如果程序中沒有使用任何注解,可以在web.xml中設置<web-app>的metadatacomplete屬性為true來關掉服務器啟動時的例行檢查。 106 107 108 109 支持注解的服務器需要支持到Servlet2.5及以上規范,所以Tomcat要6.0.X及以上版本才行。
具體的使用方法
1 @PostConstruct注解好多人以為是Spring提供的。其實是Java自己的注解。 2 3 Java中該注解的說明:@PostConstruct該注解被用來修飾一個非靜態的void()方法。被@PostConstruct修飾的方法會在服務器加載Servlet的時候運行,並且只會被服務器執行一次。PostConstruct在構造函數之后執行,init()方法之前執行。 4 5 通常我們會是在Spring框架中使用到@PostConstruct注解 該注解的方法在整個Bean初始化中的執行順序: 6 7 Constructor(構造方法) -> @Autowired(依賴注入) -> @PostConstruct(注釋的方法) 8 9 實戰:在靜態方法中調用依賴注入的Bean中的方法。 10 11 package com.example.studySpringBoot.util; 12 13 import com.example.studySpringBoot.service.MyMethorClassService; 14 import org.springframework.beans.factory.annotation.Autowired; 15 import org.springframework.stereotype.Component; 16 17 import javax.annotation.PostConstruct; 18 19 @Component 20 public class MyUtils { 21 22 private static MyUtils staticInstance; 23 24 @Autowired 25 private MyMethorClassService myService; 26 27 @PostConstruct 28 public void init(){ 29 staticInstance.myService = myService; 30 } 31 32 public static Integer invokeBean(){ 33 return staticInstance.myService.add(10,20); 34 } 35 }
這是關於@PostConstruct的一些解釋,諸如執行過程之類的
從Java EE 5規范開始,Servlet中增加了兩個影響Servlet生命周期的注解(Annotion);@PostConstruct和@PreDestroy。這兩個注解被用來修飾一個非靜態的void()方法 。寫法有如下兩種方式: @PostConstruct Public void someMethod() {} 或者 public @PostConstruct void someMethod(){} 被@PostConstruct修飾的方法會在服務器加載Servle的時候運行,並且只會被服務器執行一次。PostConstruct在構造函數之后執行,init()方法之前執行。PreDestroy()方法在destroy()方法執行執行之后執行
被注解的Servlet生命周期
需要注意的是,注解會多多少少地影響到服務器的啟動速度。服務器在啟動時候會遍歷Web 應用的WEB-INF/classes下的所有class文件與WEB-INF/lib下的所有jar文件,以檢查哪些類使用了注解。如果應用程序中沒有 使用任何注解,可以在Web.xml中設置的metadata-complete屬性為true.(支持@PostConstruct和 @PreDestroy的服務器需要支持Servlet2.5規范。Tomcat5.x僅支持Servlet2.4規范。) 我現在要說的是用實例說明它有什么作用。 比如說我有一種情況,在我的servlet初始化加載之前我想處理一些東西,像加載緩存等等。 怎么做。@PostConstruct就派上用場了。那為什么這玩意用的不多呢,這是因為如果初始化之前我們要加載或處理某些玩意完全可以在構造器初始化時就處理了,但這種方法需要自己重寫構造器。好吧。直接上代碼看看具體用它的時候怎么做的。