jar包結構
閒來無事,看了一下jar包的結構,今天來學習一下
就用這個spring-aop的jar包來舉例子:
首先是META-INF資料夾下的檔案:INDEX.LIST
INDEX.LIST:顧名思義,索引列表。這個應該就是描述了當前jar包下所有的資原始檔的路徑,類似一個索引,可能是為了方便查詢各個類檔案
網上是這樣解釋INDEX.LIST的: 這個檔案由 jar 工具的新選項 -i 生成,它包含在應用程式或者擴充套件中定義的包的位置資訊。它是 JarIndex 實現的一部分,並由類裝載器用於加速類裝載過程。
MANIFEST.MF:這個 manifest 檔案定義了與擴充套件和包相關的資料。
其實,INDEX.LIST和MANIFEST.MF應該是jar包生成工具在壓縮jar包時自動生成的2個檔案
spring.handlers:spring.handlers是aopNamespaceHandler和XSD檔案的聯結器(aopNamespaceHandler通過spring.handlers配置檔案找到XSD檔案)。指明名稱空間需要哪個類來處理,這裡是aopNamespaceHandler這個類來處理名稱空間
spring.schemas:指明瞭schema檔案的位置,spring會使用這裡制定的xsd檔案來驗證配置的正確性。
spring容器在啟動的時候會根據spring.handlers和spring.schemas的配置載入檔案內容,然後去解析檔案中的配置資訊。
AopNamespaceHandler類:
上面例項主要說明config這個自定義標籤通過new ConfigBeanDefinitionParser()通過這個parser進行解析。public class AopNamespaceHandler extends NamespaceHandlerSupport { public AopNamespaceHandler() { } public void init() { this.registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser()); this.registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser()); this.registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator()); this.registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser()); } }
spring.schemas中的配置:
http\://www.springframework.org/schema/aop/spring-aop-2.0.xsd=org/springframework/aop/config/spring-aop-2.0.xsd
http\://www.springframework.org/schema/aop/spring-aop-2.5.xsd=org/springframework/aop/config/spring-aop-2.5.xsd
http\://www.springframework.org/schema/aop/spring-aop-3.0.xsd=org/springframework/aop/config/spring-aop-3.0.xsd
http\://www.springframework.org/schema/aop/spring-aop.xsd=org/springframework/aop/config/spring-aop-3.0.xsd
既然是通過xsd檔案來做到擴充套件的,那麼我們看一下spring-aop.xsd檔案,隨便看一下
<xsd:element name="aspectj-autoproxy">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator"><![CDATA[
Enables the use of the @AspectJ style of Spring AOP.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element name="include" type="includeType" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicates that only @AspectJ beans with names matched by the (regex)
pattern will be considered as defining aspects to use for Spring autoproxying.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="proxy-target-class" type="xsd:boolean" default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[
Are class-based (CGLIB) proxies to be created? By default, standard
Java interface-based proxies are created.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="expose-proxy" type="xsd:boolean" default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicate that the proxy should be exposed by the AOP framework as a
ThreadLocal for retrieval via the AopContext class. Off by default,
i.e. no guarantees that AopContext access will work.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
我們看到了一個名叫:org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator的類
這個類就是spring-aop的主要類,jar包中的其他類也是通過這樣的方式被載入的。
因為主題本來是想介紹jar包的結構,但是覺得只說jar包的結構可能沒多少東西
那麼就來說一下伺服器啟動到java專案的載入的過程吧:
伺服器啟動的時候,會在服務端釋出3個資料夾:libs,classes,web.xml
libs裡面就是我們的jar包,web.xml會通過配置監聽來將spring容器的資訊載入,這些資訊一般放在一個叫:applicationContext.xml的檔案裡,最後,在這個檔案中通過bean的方式來使用aop或者spring的其他技術。
web.xml配置:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
applicationContext.xml:
<bean id="LogAopFormat" class="com.assa.asas.log.tool.LogAopFormat"/>
<aop:config>
<aop:advisor advice-ref="txAdvice"
pointcut="execution(* com.aaa.bbb.service.impl.sssServiceImpl.*(..))"/>
<aop:advisor advice-ref="txAdvice"
pointcut="execution(* com.aaa.bbb.service.impl.sassServiceImpl.*(..))"/>
<aop:advisor advice-ref="txAdvice"
pointcut="execution(* com.aaa.bbb.service.impl.EndorseServiceImpl.*(..))"/>
<aop:advisor advice-ref="txAdvice"
pointcut="execution(* com.aaa.bbb.service.impl.ascasServiceImpl.*(..))"/>
<aop:advisor advice-ref="txAdvice"
pointcut="execution(* com.aaa.bbb.service.impl.ascsaServiceImpl.*(..))"/>
<aop:advisor advice-ref="txAdvice"
pointcut="execution(* com.aaa.bbb.service.impl.ascsaServiceImpl.*(..))"/>
<aop:advisor advice-ref="txAdvice"
pointcut="execution(* com.aaa.bbb.service.impl.ascasServiceImpl.*(..))"/>
<aop:advisor advice-ref="txAdvice"
pointcut="execution(* com.aaa.bbb.service.impl.ascasServiceImpl.*(..))"/>
<aop:advisor advice-ref="txAdvice"
pointcut="execution(* com.aaa.bbb.service.impl.acascServiceImpl.*(..))"/>
<aop:advisor advice-ref="txAdvice"
pointcut="execution(* com.ccsee.ecargo.service.impl.QuotaInsureServiceImpl.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut="execution(* com.ccsee.ecargo.service.impl.BillServiceImpl.*(..))"/>
<aop:aspect id="LogAopFormatAspect" ref="LogAopFormat">
<aop:pointcut id="log"
expression="execution(* com.ccsee.ecargo..service..*Service*Impl.*(..))||execution(* com.ccsee.ecargo..web.*.*(..))"/>
<aop:before method="beforeMethod" pointcut-ref="log" />
<aop:after method="afterMethod" pointcut-ref="log"/>
</aop:aspect>
</aop:config>
這裡是用aop來做日誌。