PK R¨N meta.xmlvþ è¿ä¸ªå è½½å¨ç±sun.misc.Launcher $ExtClassLoaderå®ç°ï¼å®è´è´£å è½½ï¼JAVA_HOMEï¼\lib\extç®å½ä¸çï¼æè
被java.ext.dirsç³»ç»åéææå®çè·¯å¾ä¸çææç±»åºï¼å¼åè
å¯ä»¥ç´æ¥ä½¿ç¨æ©å±ç±»å è½½å¨ã ç±äºè¿ä¸ªç±»å è½½å¨æ¯ClassLoaderä¸çgetSystemClassLoaderï¼ï¼æ¹æ³çè¿å å¼ï¼æä»¥ä¸è¬ä¹ç§°å®ä¸ºç³»ç»ç±»å è½½å¨ã å®è´è´£å è½½ç¨æ·ç±»è·¯å¾ï¼ClassPathï¼ä¸ææå®çç±» åºï¼å¼åè
å¯ä»¥ç´æ¥ä½¿ç¨è¿ä¸ªç±»å è½½å¨ï¼å¦æåºç¨ç¨åºä¸æ²¡æèªå®ä¹è¿èªå·±çç±»å è½½å¨ï¼ä¸ è¬æ
åµä¸è¿ä¸ªå°±æ¯ç¨åºä¸é»è®¤çç±»å è½½å¨ å¦æä¸ä¸ªç±»å è½½å¨æ¶å°äºç±»å è½½ç请æ±ï¼å®é¦å
ä¸ä¼èªå·±å»å°è¯å è½½è¿ä¸ªç±»ï¼èæ¯æè¿ä¸ªè¯·æ±å§æ´¾ç»ç¶ç±»å è½½å¨å»å®æï¼æ¯ä¸ä¸ªå±æ¬¡çç±»å è½½å¨é½æ¯å¦æ¤ï¼å æ¤ææçå è½½è¯·æ±æç»é½åºè¯¥ä¼ éå°é¡¶å±çå¯å¨ç±»å è½½å¨ä¸ï¼åªæå½ç¶å è½½å¨åé¦èªå·±æ æ³å®æè¿ä¸ªå 载请æ±ï¼å®çæç´¢èå´ä¸æ²¡ææ¾å°æéçç±»ï¼æ¶ï¼åå è½½å¨æä¼å°è¯èªå·±å»å è½½ 使ç¨åäº²å§æ´¾æ¨¡åæ¥ç»ç»ç±»å è½½å¨ä¹é´çå
³ç³»ï¼æä¸ä¸ªæ¾èæè§ç好å¤å°±æ¯Javaç±»éçå®çç±»å è½½å¨ä¸èµ·å
·å¤äºä¸ç§å¸¦æä¼å
级ç屿¬¡å
³ç³»ã ä¾å¦ç±»java.lang.Objectï¼å®åæ¾å¨rt.jarä¹ä¸ï¼æ 论åªä¸ä¸ªç±»å è½½å¨è¦å è½½è¿ä¸ªç±»ï¼æç»é½æ¯å§æ´¾ç»å¤äºæ¨¡åæé¡¶ç«¯çå¯å¨ç±»å è½½å¨è¿è¡å è½½ï¼å æ¤Objectç±»å¨ç¨åºçåç§ç±»å è½½å¨ç¯å¢ä¸é½æ¯åä¸ä¸ªç±»ã ç¸åï¼å¦ææ²¡æä½¿ç¨åäº²å§æ´¾æ¨¡åï¼ç±å个类å è½½å¨èªè¡å»å è½½çè¯ï¼å¦æç¨æ·èªå·±ç¼åäºä¸ä¸ªç§°ä¸ºjava.lang.Objectçç±»ï¼å¹¶æ¾å¨ç¨åºçClassPathä¸ï¼é£ç³»ç»ä¸å°ä¼åºç°å¤ä¸ªä¸åçObjectç±»ï¼Javaç±»åä½ç³»ä¸æåºç¡çè¡ä¸ºä¹å°±æ æ³ä¿è¯ï¼åºç¨ç¨åºä¹å°ä¼åå¾ä¸çæ··ä¹±ã å¦æè¯»è
æå
´è¶£çè¯ï¼å¯ä»¥å°è¯å»ç¼åä¸ä¸ªä¸rt.jarç±»åºä¸å·²æç±»éåçJavaç±»ï¼å°ä¼åç°å¯ä»¥æ£å¸¸ç¼ è¯ï¼ä½æ°¸è¿æ æ³è¢«å è½½è¿è¡ 设置æ¯ä¸ªçº¿ç¨çå æ 大å°ãJDK5.0ä»¥åæ¯ä¸ªçº¿ç¨å æ 大å°ä¸º1Mï¼ä»¥åæ¯ä¸ªçº¿ç¨å æ 大å°ä¸º256Kãæ ¹æ®åºç¨ççº¿ç¨æéå
å大å°è¿è¡è°æ´ãå¨ç¸åç©çå
åä¸ï¼åå°è¿ä¸ªå¼è½çææ´å¤ç线ç¨ã使¯æä½ç³»ç»å¯¹ä¸ä¸ªè¿ç¨å
ççº¿ç¨æ°è¿æ¯æéå¶çï¼ä¸è½æ éçæï¼ç»éªå¼å¨3000~5000å·¦å³ã 主è¦ç¨æ¥æ¥çJava线ç¨çè°ç¨å æ çï¼å¯ä»¥ç¨æ¥åæçº¿ç¨é®é¢(妿»é) ç¨äºçæ§èææºåç§è¿è¡ç¶æä¿¡æ¯çå½ä»¤è¡å·¥å
·ãä»å¯ä»¥æ¾ç¤ºæ¬å°æè¿ç¨èææºè¿ç¨ä¸çç±»è£
è½½ãå
åãå徿¶éãJITç¼è¯çè¿è¡æ°æ®ï¼å¨æ²¡æGUIå¾å½¢çæå¡å¨ä¸ï¼å®æ¯è¿è¡æå®ä½èææºæ§è½é®é¢çé¦éå·¥å
·ã Cglibä»£çæ¯åè½æä¸ºå¼ºå¤§çä¸ç§ä»£çæ¹å¼ï¼å 为å
¶ä¸ä»
è§£å³äºéæä»£çéè¦å建å¤ä¸ªä»£çç±»çé®é¢ï¼è¿è§£å³äºjdk代çéè¦è¢«ä»£ç对象å®ç°æä¸ªæ¥å£çé®é¢ã 对äºéè¦ä»£ççç±»ï¼å¦æè½ä¸ºå
¶å建ä¸ä¸ªåç±»ï¼å¹¶ä¸å¨åç±»ä¸ç¼åç¸å
³ç代çé»è¾ï¼å 为âåç±» instanceof ç¶ç±»âï¼å èå¨è¿è¡è°ç¨æ¶ç´æ¥è°ç¨å类对象çå®ä¾ï¼ä¹å¯ä»¥è¾¾å°ä»£ççææãCglib代ççåçå®é
䏿¯å¨æçæè¢«ä»£çç±»çåç±»åèç ï¼ç±äºå
¶åèç 齿¯æç
§jvmç¼è¯åçclassæä»¶çè§èç¼åçï¼å èå
¶å¯ä»¥è¢«jvmæ£å¸¸å 载并è¿è¡ãè¿ä¹å°±æ¯Cglib代ç为ä»ä¹ä¸éè¦ä¸ºæ¯ä¸ªè¢«ä»£çç±»ç¼å代çé»è¾çåå ãè¿ééè¦æ³¨æçæ¯ï¼æ ¹æ®Cglibå®ç°åçï¼ç±äºå
¶æ¯éè¿å建åç±»åèç ç形弿¥å®ç°ä»£ççï¼å¦æè¢«ä»£çç±»çæ¹æ³è¢«å£°æfinalç±»åï¼é£ä¹Cglibä»£çæ¯æ æ³æ£å¸¸å·¥ä½çï¼å 为finalç±»åæ¹æ³ä¸è½è¢«éåã /** * 被代çç±» */ public class Suject { public Suject(){} public void request() { System.out.println("update without implement any interface."); } } /** * 代çç±» */ public class SafetyCheckCallback implements MethodInterceptor { @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("before safety check."); Object result = methodProxy.invokeSuper(o, objects); System.out.println("after safety check."); return result; } } public class Client { @Test public void testCglibProxy() { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(Suject.class); enhancer.setCallback(new SafetyCheckCallback()); Suject proxy = (Suject) enhancer.create(); proxy.request(); } } jdk代çè§£å³äºéæä»£çéè¦ä¸ºæ¯ä¸ªä¸å¡æ¥å£å建ä¸ä¸ªä»£çç±»çé®é¢ï¼è½ç¶ä½¿ç¨åå°å建代ç对象æçæ¯éæä»£çç¨ä½ï¼ä½å
¶å¨ç°ä»£é«éjvmä¸ä¹æ¯å¯ä»¥æ¥åçï¼å¨SpringçAOP代çä¸é»è®¤å°±æ¯ä½¿ç¨çjdk代çå®ç°çã è¿éjdk代ççéå¶ä¹æ¯æ¯è¾ææ¾çï¼å³å
¶éè¦è¢«ä»£çç对象å¿
é¡»å®ç°ä¸ä¸ªæ¥å£ã public class SafetyInvocationHandler implements InvocationHandler { private Object target; public SafetyInvocationHandler(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before safety check."); Object result = method.invoke(target, args); System.out.println("after safety check."); return result; } } public class Client { @Test public void testDynamicProxy() { ISubject subject = new SubjectImpl(); ISubject proxySubject = (ISubject) Proxy.newProxyInstance(Client.class.getClassLoader(), new Class[]{ISubject.class}, new SafetyInvocationHandler(subject)); proxySubject.request(); } } è¦ä¸ºæ¯ä¸ªä¸å¡æ¥å£å建ä¸ä¸ªä»£çç±» public interface ISubject { void request(); } public class SubjectImpl implements ISubject { @Override public void request() { System.out.println("request SubjectImpl."); } } public class SubjectProxy implements ISubject { private ISubject target; public SubjectProxy(ISubject target) { this.target = target; } @Override public void request() { System.out.println("before safety check."); target.request(); System.out.println("after safety check."); } } public class Client { @Test public void testStaticProxy() { ISubject subject = new SubjectImpl(); ISubject proxy = new SubjectProxy(subject); proxy.request(); } } Coreå
æ¯æ¡æ¶çæåºç¡é¨åï¼å¹¶æä¾ä¾èµæ³¨å
¥ï¼Dependency Injectionï¼ç®¡çBean容å¨åè½ã <?xml version="1.0" encoding="UTF-8" ?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" default-autowire="byName"> <bean id="messageService" class="com.javadoop.example.MessageServiceImpl"/> </beans> public class App { public static void main(String[] args) { // ç¨æä»¬çé
ç½®æä»¶æ¥å¯å¨ä¸ä¸ª ApplicationContext ApplicationContext context = new ClassPathXmlApplicationContext("classpath:application.xml"); System.out.println("context å¯å¨æå"); // ä» context ä¸ååºæä»¬ç Beanï¼è䏿¯ç¨ new MessageServiceImpl() è¿ç§æ¹å¼ MessageService messageService = context.getBean(MessageService.class); // è¿å¥å°è¾åº: hello world System.out.println(messageService.getMessage()); } } é»è®¤çscopeï¼æ¯ä¸ªscope为singletonçbeané½ä¼è¢«å®ä¹ä¸ºä¸ä¸ªåä¾å¯¹è±¡ï¼è¯¥å¯¹è±¡ççå½å¨ææ¯ä¸Spring IOC容å¨ä¸è´çï¼ä½å¨ç¬¬ä¸æ¬¡è¢«æ³¨å
¥æ¶æä¼å建ï¼ã bean被å®ä¹ä¸ºå¨æ¯æ¬¡æ³¨å
¥æ¶é½ä¼å建ä¸ä¸ªæ°ç对象ã bean被å®ä¹ä¸ºå¨æ¯ä¸ªHTTP请æ±ä¸å建ä¸ä¸ªåä¾å¯¹è±¡ï¼ä¹å°±æ¯è¯´å¨å个请æ±ä¸é½ä¼å¤ç¨è¿ä¸ä¸ªåä¾å¯¹è±¡ã bean被å®ä¹ä¸ºå¨ä¸ä¸ªsessionççå½å¨æå
å建ä¸ä¸ªåä¾å¯¹è±¡ bean被å®ä¹ä¸ºå¨ServletContextççå½å¨æä¸å¤ç¨ä¸ä¸ªåä¾å¯¹è±¡ã bean被å®ä¹ä¸ºå¨websocketççå½å¨æä¸å¤ç¨ä¸ä¸ªåä¾å¯¹è±¡ã Spring没æå¯¹beançå¤çº¿ç¨å®å
¨é®é¢ååºä»»ä½ä¿è¯ä¸æªæ½ã å¯¹äºæ¯ä¸ªbeanç线ç¨å®å
¨é®é¢ï¼æ ¹æ¬åå æ¯æ¯ä¸ªbeanèªèº«ç设计ãä¸è¦å¨beanä¸å£°æä»»ä½æç¶æçå®ä¾åéæç±»åéï¼å¦æå¿
须妿¤ï¼é£ä¹å°±ä½¿ç¨ThreadLocalæåéå为线ç¨ç§æçï¼å¦æbeançå®ä¾åéæç±»åééè¦å¨å¤ä¸ªçº¿ç¨ä¹é´å
±äº«ï¼é£ä¹å°±åªè½ä½¿ç¨synchronizedãlockãCASçè¿äºå®ç°çº¿ç¨åæ¥çæ¹æ³äºã åå§åbeançæ¶åæ§è¡ï¼å¯ä»¥é对æä¸ªå
·ä½çbeanå¨xmlè¿è¡é
ç½® åå§åbeançæ¶åæ§è¡ï¼å¯ä»¥é对æä¸ªå
·ä½çbeanå¨xmlè¿è¡é
ç½® å¨SimpleDateFormatè½¬æ¢æ¥ææ¯éè¿Calendarå¯¹è±¡æ¥æä½çï¼SimpleDateFormatç»§æ¿DateFormatç±»ï¼DateFormatç±»ä¸ç»´æ¤ä¸ä¸ªCalendar对象. å¨parseæ¹æ³çæåï¼ä¼è°ç¨CalendarBuilderçestablishæ¹æ³ï¼å
¥åå°±æ¯SimpleDateFormatç»´æ¤çCalendarå®ä¾ï¼å¨establishæ¹æ³ä¸ä¼è°ç¨calendarçclearæ¹æ³ æä»¬è¦èèä¸ç§ä¼åçå
åæ³æ¼çæ
åµï¼å¦æThreadLocal被设置为nullåï¼è䏿²¡æä»»ä½å¼ºå¼ç¨æåå®ï¼æ ¹æ®åå¾åæ¶çå¯è¾¾æ§åæç®æ³ï¼ThreadLocalå°ä¼è¢«åæ¶ãè¿æ ·ä¸æ¥ï¼ThreadLocalMapä¸å°±ä¼å«ækey为nullçEntryï¼èä¸ThreadLocalMapæ¯å¨Threadä¸çï¼åªè¦çº¿ç¨è¿è¿ä¸ç»æï¼è¿äºæ æ³è®¿é®å°çvalueä¼å½¢æå
åæ³æ¼ã为äºè§£å³è¿ä¸ªé®é¢ï¼ThreadLocalMapä¸çgetEntry()ãset()åremove()彿°é½ä¼æ¸
çkey为nullçEntryï¼ä»¥ä¸é¢çgetEntry()彿°çæºç 为ä¾ã /** * Get the entry associated with key. This method * itself handles only the fast path: a direct hit of existing * key. It otherwise relays to getEntryAfterMiss. This is * designed to maximize performance for direct hits, in part * by making this method readily inlinable. * * @param key the thread local object * @return the entry associated with key, or null if no such */ private Entry getEntry(ThreadLocal<?> key) { int i = key.threadLocalHashCode & (table.length - 1); Entry e = table[i]; if (e != null && e.get() == key) return e; else return getEntryAfterMiss(key, i, e); } /** * Version of getEntry method for use when key is not found in * its direct hash slot. * * @param key the thread local object * @param i the table index for key's hash code * @param e the entry at table[i] * @return the entry associated with key, or null if no such */ private Entry getEntryAfterMiss(ThreadLocal<?> key, int i, Entry e) { Entry[] tab = table; int len = tab.length; // æ¸
çkey为nullçEntry while (e != null) { ThreadLocal<?> k = e.get(); if (k == key) return e; if (k == null) expungeStaleEntry(i); else i = nextIndex(i, len); e = tab[i]; } return null; }