1. 程式人生 > >jar包結構

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類:
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());
    }
}
上面例項主要說明config這個自定義標籤通過new ConfigBeanDefinitionParser()通過這個parser進行解析。

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來做日誌。