1.spring-core概覽
spring-core是spring框架的基石,它為spring框架提供了基礎的支持。
spring-core從源碼上看,分為6個package,分別是asm,cglib,core,lang,objenesis和util。
1.1 asm
關于asm的內幕參見博客:
spring源碼分析之spring-core asm概述
1.2 cglib
關于cglib的內幕參見博客
cglib源碼分析–轉
1.3 core
1.4 lang
四個注解接口
/*** Indicates that the annotated element uses the Http Server available in* {@code com.sun.*} classes, which is only available on a Sun/Oracle JVM.** @author Stephane Nicoll* @since 4.1*/
@Retention(RetentionPolicy.CLASS)
@Target({ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.TYPE})
@Documented
public @interface UsesSunHttpServer {
}
/*** Indicates that the annotated element uses Java 7 specific API constructs,* without implying that it strictly requires Java 7.** @author Stephane Nicoll* @since 4.1*/
@Retention(RetentionPolicy.CLASS)
@Target({ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.TYPE})
@Documented
@Deprecated
public @interface UsesJava7 {
}
/*** Indicates that the annotated element uses Java 8 specific API constructs,* without implying that it strictly requires Java 8.** @author Stephane Nicoll* @since 4.1*/
@Retention(RetentionPolicy.CLASS)
@Target({ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.TYPE})
@Documented
@Deprecated
public @interface UsesJava8 {
}
/*** Indicates that the annotated element uses an API from the {@code sun.misc}* package.** @author Stephane Nicoll* @since 4.3*/
@Retention(RetentionPolicy.CLASS)
@Target({ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.TYPE})
@Documented
public @interface UsesSunMisc {
}
1.5 Objenesis
官網:http://objenesis.org/
Objenesis is a small Java library that serves one purpose:
To instantiate a new object of a particular class.
Objenesis是專門用于實例化一些特殊java對象的一個工具,如私有構造方法,帶參數的構造等不能通過class.newInstance()實例化的,通過它可以輕松完成。
When would you want this?
Java already supports this dynamic instantiation of classes using Class.newInstance(). However, this only works if the class has an appropriate constructor. There are many times when a class cannot be instantiated this way, such as when the class contains:
Constructors that require arguments.
Constructors that have side effects.
Constructors that throw exceptions.
As a result, it is common to see restrictions in libraries stating that classes must require a default constructor. Objenesis aims to overcome these restrictions by bypassing the constructor on object instantiation.
Typical uses
Needing to instantiate an object without calling the constructor is a fairly specialized task, however there are certain cases when this is useful:
Serialization, Remoting and Persistence - Objects need to be instantiated and restored to a specific state, without invoking code.
Proxies, AOP Libraries and Mock Objects - Classes can be subclassed without needing to worry about the super() constructor.
Container Frameworks - Objects can be dynamically instantatiated in non-standard ways.
示例:
Objenesis objenesis = new ObjenesisStd(); // or ObjenesisSerializer
MyThingy thingy1 = (MyThingy) objenesis.newInstance(MyThingy.class);// or (a little bit more efficient if you need to create many objects)Objenesis objenesis = new ObjenesisStd(); // or ObjenesisSerializer
ObjectInstantiator thingyInstantiator = objenesis.getInstantiatorOf(MyThingy.class);MyThingy thingy2 = (MyThingy)thingyInstantiator.newInstance();
MyThingy thingy3 = (MyThingy)thingyInstantiator.newInstance();
MyThingy thingy4 = (MyThingy)thingyInstantiator.newInstance();
SpringObjenesis封裝了Objenesis,涉及了一個spring封裝的數據結構org.springframework.util.ConcurrentReferenceHashMap
A ConcurrentHashMap that uses soft or weak references for both keys and values.
This class can be used as an alternative to Collections.synchronizedMap(new WeakHashMap<K, Reference<V>>()) in order to support better performance when accessed concurrently. This implementation follows the same design constraints as ConcurrentHashMap with the exception that null values and null keys are supported.NOTE: The use of references means that there is no guarantee that items placed into the map will be subsequently available. The garbage collector may discard references at any time, so it may appear that an unknown thread is silently removing entries.If not explicitly specified, this implementation will use soft entry references.Since:
3.2
可以做緩存使用,不保證命中率。
1.6 util包
spring提供了豐富的util工具類,ObjectUtil和classUtil是最基本的兩個類:
Class的定義:
/*** Instances of the class {@code Class} represent classes and* interfaces in a running Java application. An enum is a kind of* class and an annotation is a kind of interface. Every array also* belongs to a class that is reflected as a {@code Class} object* that is shared by all arrays with the same element type and number* of dimensions. The primitive Java types ({@code boolean},* {@code byte}, {@code char}, {@code short},* {@code int}, {@code long}, {@code float}, and* {@code double}), and the keyword {@code void} are also* represented as {@code Class} objects.** <p> {@code Class} has no public constructor. Instead {@code Class}* objects are constructed automatically by the Java Virtual Machine as classes* are loaded and by calls to the {@code defineClass} method in the class* loader.** <p> The following example uses a {@code Class} object to print the* class name of an object:** <blockquote><pre>* void printClassName(Object obj) {* System.out.println("The class of " + obj +* " is " + obj.getClass().getName());* }* </pre></blockquote>** <p> It is also possible to get the {@code Class} object for a named* type (or for void) using a class literal. See Section 15.8.2 of* <cite>The Java™ Language Specification</cite>.* For example:** <blockquote>* {@code System.out.println("The name of class Foo is: "+Foo.class.getName());}* </blockquote>** @param <T> the type of the class modeled by this {@code Class}* object. For example, the type of {@code String.class} is {@code* Class<String>}. Use {@code Class<?>} if the class being modeled is* unknown.** @author unascribed* @see java.lang.ClassLoader#defineClass(byte[], int, int)* @since JDK1.0*/
public final class Class<T> implements java.io.Serializable,GenericDeclaration,Type,AnnotatedElement
說明
Java程序在運行時,Java運行時系統一直對所有的對象進行所謂的運行時類型標識。這項信息紀錄了每個對象所屬的類。虛擬機通常使用運行時類型信息選準正確方法去執行,用來保存這些類型信息的類是Class類。Class類封裝一個對象和接口運行時的狀態,當裝載類時,Class類型的對象自動創建。
Class 沒有公共構造方法。Class 對象是在加載類時由 Java 虛擬機以及通過調用類加載器中的 defineClass 方法自動構造的,因此不能顯式地聲明一個Class對象。
虛擬機為每種類型管理一個獨一無二的Class對象。也就是說,每個類(型)都有一個Class對象。運行程序時,Java虛擬機(JVM)首先檢查是否所要加載的類對應的Class對象是否已經加載。如果沒有加載,JVM就會根據類名查找.class文件,并將其Class對象載入。
基本的 Java 類型(boolean、byte、char、short、int、long、float 和 double)和關鍵字 void 也都對應一個 Class 對象。
每個數組屬于被映射為 Class 對象的一個類,所有具有相同元素類型和維數的數組都共享該 Class 對象。
一般某個類的Class對象被載入內存,它就用來創建這個類的所有對象。
一、如何得到Class的對象呢?有三種方法可以的獲取:
1、調用Object類的getClass()方法來得到Class對象,這也是最常見的產生Class對象的方法。例如:
MyObject x;
Class c1 = x.getClass();
2、使用Class類的中靜態forName()方法獲得與字符串對應的Class對象。例如:
Class c2=Class.forName(“MyObject”),Employee必須是接口或者類的名字。
3、獲取Class類型對象的第三個方法非常簡單。如果T是一個Java類型,那么T.class就代表了匹配的類對象。例如
Class cl1 = Manager.class;
Class cl2 = int.class;
Class cl3 = Double[].class;
注意:Class對象實際上描述的只是類型,而這類型未必是類或者接口。例如上面的int.class是一個Class類型的對象。由于歷史原因,數組類型的getName方法會返回奇怪的名字。
二、Class類的常用方法
1、getName()
一個Class對象描述了一個特定類的屬性,Class類中最常用的方法getName以 String 的形式返回此 Class 對象所表示的實體(類、接口、數組類、基本類型或 void)名稱。
2、newInstance()
Class還有一個有用的方法可以為類創建一個實例,這個方法叫做newInstance()。例如:
x.getClass.newInstance(),創建了一個同x一樣類型的新實例。newInstance()方法調用默認構造器(無參數構造器)初始化新建對象。
3、getClassLoader()
返回該類的類加載器。
4、getComponentType()
返回表示數組組件類型的 Class。
5、getSuperclass()
返回表示此 Class 所表示的實體(類、接口、基本類型或 void)的超類的 Class。
6、isArray()
判定此 Class 對象是否表示一個數組類。
三、Class的一些使用技巧
1、forName和newInstance結合起來使用,可以根據存儲在字符串中的類名創建對象。例如
Object obj = Class.forName(s).newInstance();
2、虛擬機為每種類型管理一個獨一無二的Class對象。因此可以使用==操作符來比較類對象。例如:
if(e.getClass() == Employee.class)…
Object定義:
/*** Class {@code Object} is the root of the class hierarchy.* Every class has {@code Object} as a superclass. All objects,* including arrays, implement the methods of this class.** @author unascribed* @see java.lang.Class* @since JDK1.0*/
public class Object