spring源码分析之spring-core总结篇
1.spring-core概覽
spring-core是spring框架的基石,它為spring框架提供了基礎(chǔ)的支持。
spring-core從源碼上看,分為6個(gè)package,分別是asm,cglib,core,lang,objenesis和util。
1.1 asm
關(guān)于asm的內(nèi)幕參見(jiàn)博客:
spring源碼分析之spring-core asm概述
1.2 cglib
關(guān)于cglib的內(nèi)幕參見(jiàn)博客
cglib源碼分析--轉(zhuǎn)
1.3 core
?
?
1.4 lang
四個(gè)注解接口
/*** 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
官網(wǎng):http://objenesis.org/
Objenesis is a small Java library that serves one purpose:
- To instantiate a new object of a particular class.
Objenesis是專(zhuān)門(mén)用于實(shí)例化一些特殊java對(duì)象的一個(gè)工具,如私有構(gòu)造方法,帶參數(shù)的構(gòu)造等不能通過(guò)class.newInstance()實(shí)例化的,通過(guò)它可以輕松完成。
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,涉及了一個(gè)spring封裝的數(shù)據(jù)結(jié)構(gòu)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工具類(lèi),ObjectUtil和classUtil是最基本的兩個(gè)類(lèi):
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?說(shuō)明
Java程序在運(yùn)行時(shí),Java運(yùn)行時(shí)系統(tǒng)一直對(duì)所有的對(duì)象進(jìn)行所謂的運(yùn)行時(shí)類(lèi)型標(biāo)識(shí)。這項(xiàng)信息紀(jì)錄了每個(gè)對(duì)象所屬的類(lèi)。虛擬機(jī)通常使用運(yùn)行時(shí)類(lèi)型信息選準(zhǔn)正確方法去執(zhí)行,用來(lái)保存這些類(lèi)型信息的類(lèi)是Class類(lèi)。Class類(lèi)封裝一個(gè)對(duì)象和接口運(yùn)行時(shí)的狀態(tài),當(dāng)裝載類(lèi)時(shí),Class類(lèi)型的對(duì)象自動(dòng)創(chuàng)建。
Class 沒(méi)有公共構(gòu)造方法。Class 對(duì)象是在加載類(lèi)時(shí)由 Java 虛擬機(jī)以及通過(guò)調(diào)用類(lèi)加載器中的 defineClass 方法自動(dòng)構(gòu)造的,因此不能顯式地聲明一個(gè)Class對(duì)象。
虛擬機(jī)為每種類(lèi)型管理一個(gè)獨(dú)一無(wú)二的Class對(duì)象。也就是說(shuō),每個(gè)類(lèi)(型)都有一個(gè)Class對(duì)象。運(yùn)行程序時(shí),Java虛擬機(jī)(JVM)首先檢查是否所要加載的類(lèi)對(duì)應(yīng)的Class對(duì)象是否已經(jīng)加載。如果沒(méi)有加載,JVM就會(huì)根據(jù)類(lèi)名查找.class文件,并將其Class對(duì)象載入。
基本的 Java 類(lèi)型(boolean、byte、char、short、int、long、float 和 double)和關(guān)鍵字 void 也都對(duì)應(yīng)一個(gè) Class 對(duì)象。
每個(gè)數(shù)組屬于被映射為 Class 對(duì)象的一個(gè)類(lèi),所有具有相同元素類(lèi)型和維數(shù)的數(shù)組都共享該 Class 對(duì)象。
一般某個(gè)類(lèi)的Class對(duì)象被載入內(nèi)存,它就用來(lái)創(chuàng)建這個(gè)類(lèi)的所有對(duì)象。
一、如何得到Class的對(duì)象呢?有三種方法可以的獲取:
1、調(diào)用Object類(lèi)的getClass()方法來(lái)得到Class對(duì)象,這也是最常見(jiàn)的產(chǎn)生Class對(duì)象的方法。例如:
MyObject x;
Class c1 = x.getClass();
2、使用Class類(lèi)的中靜態(tài)forName()方法獲得與字符串對(duì)應(yīng)的Class對(duì)象。例如:
Class c2=Class.forName("MyObject"),Employee必須是接口或者類(lèi)的名字。
3、獲取Class類(lèi)型對(duì)象的第三個(gè)方法非常簡(jiǎn)單。如果T是一個(gè)Java類(lèi)型,那么T.class就代表了匹配的類(lèi)對(duì)象。例如
Class cl1 = Manager.class;
Class cl2 = int.class;
Class cl3 = Double[].class;
注意:Class對(duì)象實(shí)際上描述的只是類(lèi)型,而這類(lèi)型未必是類(lèi)或者接口。例如上面的int.class是一個(gè)Class類(lèi)型的對(duì)象。由于歷史原因,數(shù)組類(lèi)型的getName方法會(huì)返回奇怪的名字。
二、Class類(lèi)的常用方法
1、getName()
一個(gè)Class對(duì)象描述了一個(gè)特定類(lèi)的屬性,Class類(lèi)中最常用的方法getName以 String 的形式返回此 Class 對(duì)象所表示的實(shí)體(類(lèi)、接口、數(shù)組類(lèi)、基本類(lèi)型或 void)名稱(chēng)。
2、newInstance()
Class還有一個(gè)有用的方法可以為類(lèi)創(chuàng)建一個(gè)實(shí)例,這個(gè)方法叫做newInstance()。例如:
x.getClass.newInstance(),創(chuàng)建了一個(gè)同x一樣類(lèi)型的新實(shí)例。newInstance()方法調(diào)用默認(rèn)構(gòu)造器(無(wú)參數(shù)構(gòu)造器)初始化新建對(duì)象。
3、getClassLoader()
返回該類(lèi)的類(lèi)加載器。
4、getComponentType()
返回表示數(shù)組組件類(lèi)型的 Class。
5、getSuperclass()
返回表示此 Class 所表示的實(shí)體(類(lèi)、接口、基本類(lèi)型或 void)的超類(lèi)的 Class。
6、isArray()
判定此 Class 對(duì)象是否表示一個(gè)數(shù)組類(lèi)。
三、Class的一些使用技巧
1、forName和newInstance結(jié)合起來(lái)使用,可以根據(jù)存儲(chǔ)在字符串中的類(lèi)名創(chuàng)建對(duì)象。例如
Object obj = Class.forName(s).newInstance();
2、虛擬機(jī)為每種類(lèi)型管理一個(gè)獨(dú)一無(wú)二的Class對(duì)象。因此可以使用==操作符來(lái)比較類(lèi)對(duì)象。例如:
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?
參考文獻(xiàn):
【1】http://lavasoft.blog.51cto.com/62575/15433
轉(zhuǎn)載于:https://www.cnblogs.com/davidwang456/p/5997448.html
總結(jié)
以上是生活随笔為你收集整理的spring源码分析之spring-core总结篇的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Google和Baidu常用的搜索技巧-
- 下一篇: java.util.concurrent