框架源码学习笔记
1.@WebListener
Servlet3.0提供@WebListener注解將一個實現了特定監聽器接口的類定義為監聽器,這樣我們在web應用中使用監聽器時,也不再需要在web.xml文件中配置監聽器的相關描述信息了。
Web應用啟動時就會初始化這個監聽器
@WebListener
public class MyServletContextListener implements ServletContextListener {
?@Override
?public void contextDestroyed(ServletContextEvent sce) {
System.out.println("ServletContex銷毀");
?}
?@Override
?public void contextInitialized(ServletContextEvent sce) {
System.out.println("ServletContex初始化");
System.out.println(sce.getServletContext().getServerInfo());
?}
}
參考:Servlet3.0學習總結(四)——使用注解標注監聽器(Listener)
2.ServletRegistration
只能在webapp啟動在初始化時進行完成注冊,可能是為了安全考慮吧.
在Servlet3.0中可以動態注冊Servlet,Filter,Listener
servlet 3.0筆記之servlet的動態注冊
第十六章_動態注冊和Servlet容器初始化
3.setAccessible(true)
Method actionMethod
actionMethod.setAccessible(true); // 取消類型安全檢測(可提高反射性能)
4.instanceof?
instanceof 運算符是用來在運行時指出對象是否是特定類的一個實例。instanceof通過返回一個布爾值來指出,這個對象是否是這個特定類或者是它的子類的一個實例。
java中instanceof用法
下面是調用Spring的函數
public class LogBeforeAdvice implements MethodBeforeAdvice {private Logger logger=Logger.getLogger(this.getClass().getName());public void before(Method method,Object[] args,Object target) throws Throwable{
注意:getClass返回的是Class類型
這里也可以用if(args[0].getClass().getName().contains("com.xxx"))來判斷是否指定類,但是沒用instanceof直觀
5.判斷Map是否為空
public static boolean isEmpty(Map map) {return (map == null || map.isEmpty());}
6.Map.Entry
// 初始化請求屬性Map<String, Object> data = view.getData();if (MapUtil.isNotEmpty(data)) {for (Map.Entry<String, Object> entry : data.entrySet()) {request.setAttribute(entry.getKey(), entry.getValue());}}
視圖操作 :處理映像中鍵/值對組
Set keySet(): 返回映像中所有關鍵字的視圖集
“因為映射中鍵的集合必須是唯一的,您用Set支持。你還可以從視圖中刪除元素,同時,關鍵字和它相關的值將從源映像中被刪除,但是你不能添加任何元素。”
Collection values():返回映像中所有值的視圖集
“因為映射中值的集合不是唯一的,您用Collection支持。你還可以從視圖中刪除元素,同時,值和它的關鍵字將從源映像中被刪除,但是你不能添加任何元素。”
Set entrySet(): 返回Map.Entry對象的視圖集,即映像中的關鍵字/值對
“因為映射是唯一的,您用Set支持。你還可以從視圖中刪除元素,同時,這些元素將從源映像中被刪除,但是你不能添加任何元素。”
Map.Entry接口
Map的entrySet()方法返回一個實現Map.Entry接口的對象集合。集合中每個對象都是底層Map中一個特定的鍵/值對。
通過這個集合的迭代器,您可以獲得每一個條目(唯一獲取方式)的鍵或值并對值進行更改。當條目通過迭代器返回后,除非是迭代器自身的remove()方法或者迭代器返回的條目的setValue()方法,其余對源Map外部的修改都會導致此條目集變得無效,同時產生條目行為未定義。
(1) Object getKey(): 返回條目的關鍵字
(2) Object getValue(): 返回條目的值
(3) Object setValue(Object value): 將相關映像中的值改為value,并且返回舊值
7.getRequestDispatcher()與sendRedirect()的區別
1.request.getRequestDispatcher()是請求轉發,前后頁面共享一個request ;?
response.sendRedirect()是重新定向,前后頁面不是一個request。
request.getRequestDispather();返回的是一個RequestDispatcher對象。
2.RequestDispatcher.forward()是在服務器端運行;?
/*** 轉發請求*/public static void forwardRequest(String path, HttpServletRequest request, HttpServletResponse response) {try {request.getRequestDispatcher(path).forward(request, response);} catch (Exception e) {logger.error("轉發請求出錯!", e);throw new RuntimeException(e);}}
8.引用JSTL
The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the jar
http://blog.csdn.net/lzz313/article/details/7554736
http://blog.sina.com.cn/s/blog_7ffb8dd501013fvl.html
<!-- JSTL --><dependency><groupId>javax.servlet</groupId><artifactId>jstl</artifactId><version>1.2</version><scope>runtime</scope></dependency>
9.ThreadLocal
每個線程相互獨立了,同樣是 static 變量,對于不同的線程而言,它沒有被共享,而是每個線程各一份,這樣也就保證了線程安全。 也就是說,TheadLocal 為每一個線程提供了一個獨立的副本!
public class SequenceB implements Sequence {private static ThreadLocal<Integer> numberContainer = new ThreadLocal<Integer>() {@Overrideprotected Integer initialValue() {return 0;}};public int getNumber() {numberContainer.set(numberContainer.get() + 1);return numberContainer.get();}public static void main(String[] args) {Sequence sequence = new SequenceB();ClientThread thread1 = new ClientThread(sequence);ClientThread thread2 = new ClientThread(sequence);ClientThread thread3 = new ClientThread(sequence);thread1.start();thread2.start();thread3.start();}
}
ThreadLocal 的 API,其實很簡單
public void set(T value):將值放入線程局部變量中
public T get():從線程局部變量中獲取值
public void remove():從線程局部變量中移除值(有助于 JVM 垃圾回收)
protected T initialValue():返回線程局部變量中的初始值(默認為 null)?
為什么 initialValue() 方法是 protected 的呢?就是為了提醒程序員們,這個方法是要你們來實現的,請給這個線程局部變量一個初始值吧。
ThreadLocal 具體有哪些使用案例呢:通過 ThreadLocal 存放 JDBC Connection,以達到事務控制的能力。
當您在一個類中使用了 static 成員變量的時候,一定要多問問自己,這個 static 成員變量需要考慮“線程安全”嗎?
也就是說,多個線程需要獨享自己的 static 成員變量嗎?如果需要考慮,那就請用 ThreadLocal 吧!
參考:?ThreadLocal 那點事兒
10.return this
return this 返回的是當前方法所在的類的實例,例如 StringBuilder 中的 append,這樣做的好處就是可以 append("XXX").append("XXX").append("XXX")....
public class ReturnThis
{public int age;public ReturnThis grow(){age++;//return this,返回調用該方法的對象return this;}public static void main(String[] args) {ReturnThis rt = new ReturnThis();//可以連續調用同一個方法rt.grow().grow().grow();System.out.println("rt的age屬性值是:" + rt.age);}
}
這樣連續調用同一個方法。
參考:初學Java,方法中返回this,連續調用方法(六)
java中的return this什么時候用
11.@SuppressWarnings注解
java.lang.SuppressWarnings是J2SE 5.0中標準的Annotation之一。可以標注在類、字段、方法、參數、構造方法,以及局部變量上。
作用:告訴編譯器忽略指定的警告,不用在編譯完成后出現警告信息。
@SuppressWarnings("unchecked")
告訴編譯器忽略 unchecked 警告信息,如使用List,ArrayList等未進行參數化產生的警告信息。
參考:http://blog.sina.com.cn/s/blog_ad8b5870010166vt.html
Java魔法堂:注解用法詳解——@SuppressWarnings
例如:
@SuppressWarnings("unchecked")public static <T> T getInstance(String cacheKey, Class<T> defaultImplClass) {
12.屬性解析
/*** 獲取字符型屬性*/public static String getString(Properties props, String key) {String value = "";if (props.containsKey(key)) {value = props.getProperty(key);}return value;}
13.抽象方法
1 用abstract關鍵字來修飾一個類時,這個類叫做抽象類;用abstract來修飾一個方法時,該方法叫做抽象方法。例如 :
abstract class Animal { //用abstract來定義一個Animal為抽象類
}
public abstract void enjoy(); //用abstract來定義一個抽象方法"enjoy"
2 含有抽象方法的類必須被聲明為抽象類,抽象類必須被繼承,抽象方法必須被重寫。
3 抽象類不能被實例化。
4 抽象方法只需聲明,而不需實現某些功能。
public abstract class ClassTemplate {
...private void doAddClass(List<Class<?>> classList, String className) {// 加載類Class<?> cls = ClassUtil.loadClass(className, false);// 判斷是否可以添加類if (checkAddClass(cls)) {// 添加類classList.add(cls);}}/*** 驗證是否允許添加類*/public abstract boolean checkAddClass(Class<?> cls);
}
14.獲取包名路徑下的 class 文件或目錄
// 獲取包名路徑下的 class 文件或目錄File[] files = new File(packagePath).listFiles(new FileFilter() {@Overridepublic boolean accept(File file) {return (file.isFile() && file.getName().endsWith(".class")) || file.isDirectory();}});
15.內部類
參考:主題:【解惑】領略內部類的“內部”
內部類有兩種情況:
(1) 在類中定義一個類(私有內部類,靜態內部類)
(2) 在方法中定義一個類(局部內部類,匿名內部類)
對內部類進行編譯后發現有兩個class文件:Outer.class 和Outer$Inner.class 。
這說明內部類Inner仍然被編譯成一個獨立的類(Outer$Inner.class),而不是Outer類的某一個域。 虛擬機運行的時候,也是把Inner作為一種常規類來處理的。
編譯器對類中內部類做的手腳吧:
(1) ?在內部類中偷偷摸摸的創建了包可見構造器,從而使外部類獲得了創建權限。
(2) ?在外部類中偷偷摸摸的創建了訪問私有變量的靜態方法,從而 使 內部類獲得了訪問權限。
這樣,類中定義的內部類無論私有,公有,靜態都可以被包圍它的外部類所訪問。
方法內部類也有兩個特點
? ? ? (1) ?方法中的內部類沒有訪問修飾符, 即方法內部類對包圍它的方法之外的任何東西都不可見。
? ? ? (2) ?方法內部類只能夠訪問該方法中的局部變量,所以也叫局部內部類。而且這些局部變量一定要是final修飾的常量。
?
內部類的特點總結
(1) ?在方法間定義的非靜態內部類:?
? ? ? ?● 外圍類和內部類可互相訪問自己的私有成員。
? ? ? ?● 內部類中不能定義靜態成員變量。
(2) 在方法間定義的靜態內部類:
? ? ? ?● 只能訪問外部類的靜態成員。
(3) 在方法中定義的局部內部類:
? ? ? ?● 該內部類沒有任何的訪問控制權限
? ? ? ?● 外圍類看不見方法中的局部內部類的,但是局部內部類可以訪問外圍類的任何成員。
? ? ? ?● 方法體中可以訪問局部內部類,但是訪問語句必須在定義局部內部類之后。
? ? ? ?● 局部內部類只能訪問方法體中的常量,即用final修飾的成員。
(4) 在方法中定義的匿名內部類:
? ? ? ?● 沒有構造器,取而代之的是將構造器參數傳遞給超類構造器。
private void addClass(List<Class<?>> classList, String packagePath, String packageName) {try {// 獲取包名路徑下的 class 文件或目錄File[] files = new File(packagePath).listFiles(new FileFilter() {@Overridepublic boolean accept(File file) {return (file.isFile() && file.getName().endsWith(".class")) || file.isDirectory();}});
16.匿名內部類
抽象類
abstract class Person {public abstract void eat();
}實現類
public class Child extends Person{public void eat() {System.out.println("eat something");}
}
調用比較
//正常調用Person p = new Child();p.eat();//匿名內部類Person p2 = new Person(){public void eat() {System.out.println("eat something");}};
輸出都是一樣的
參考:java中的匿名內部類總結
java中匿名內部類的兩種實現方式
匿名內部類的兩種實現方式:
第一種,繼承一個類,重寫其方法;第二種,實現一個接口(可以是多個),實現其方法。
匿名內部類有了自己的實現。
使用匿名內部類是因為我這地方需要有點什么特殊的實現,所以我就在這地方把具體實現也給了出來了,然后我就在這地方獲取它的實例,調用它的方法。
?
匿名內部類就是重寫父類或接口的方法。
匿名內部類是沒有名字的,所以我們沒辦法獲得其類型,而只能把它當作超類或接口類型來使用。
17.final關鍵字
final這個關鍵字的含義是“這是無法改變的”或者“終態的”;
? ? 那么為什么要阻止改變呢?
? ? java語言的發明者可能由于兩個目的而阻止改變:
? ? 1).效率問題:
? ? ? ? jdk中的某些類的某些方法,是不允許被用戶覆蓋的,設計者可能認為,所用方法已經是最好的方法,
? ? ? ? 用戶私自覆蓋,或是由于疏忽而覆蓋,就會影響JVM或是系統的系能;
? ? 2). 設計所需:
? ? ? ? 眾所周知,有些情況必須使用final關鍵字,比如方法中的匿名內部類的參數傳遞;
?
【final關鍵字的使用方法】:
? ? 【修飾變量】:
? ? ? ? final成員變量表示常量,只能被賦值一次,賦值后值不再改變。
? ? 【修飾方法】:
? ? ? ? final方法不能被子類方法覆蓋,但可以被繼承。
? ? 【修飾類】:
? ? ? ? final類不能被繼承,沒有子類,final類中所有方法都是final的。
比如util類
public final class FileUtil {private static final Logger LOGGER = LoggerFactory.getLogger(FileUtil.class);/*** 獲取真實文件名(自動去掉文件路徑)*/public static String getRealFileName(String fileName) {return FilenameUtils.getName(fileName);}
總結
- 上一篇: Netbeans使用maven下载源码
- 下一篇: JAX-WS Web 服务开发调用和数据