Spring是分層的輕量級框架
以IoC(Inverse of Control 反轉控制)和AOP(Aspect Oriented Programming 面向切面編程)為核心
應用Spring的好處:
方便解耦,簡化開發
Spring就是一個大工廠,可以將所有對象創建和依賴關系維護,交給Spring管理
AOP編程的支持
Spring提供面向切面編程,可以方便的實現對程序進行權限攔截、運行監控等功能
聲明式事務的支持
只需要通過配置就可以完成對事務的管理,而無需手動編程
方便集成各種優秀框架
Spring不排斥各種優秀的開源框架,其內部提供了對各種優秀框架(如:Struts、Hibernate、MyBatis等)的直接支持
降低JavaEE API的使用難度
Spring 對JavaEE開發中非常難用的一些API(JDBC、JavaMail、遠程調用等),都提供了封裝,使這些API應用難度大大降低
Spring的實例化Bean有三種方式:
使用類構造器直接實例化(常用)
<bean id="userBean1" class="com.szy.spring.implbean.UserBean" />
使用靜態工廠的方法實例化
<bean id="userBean2" class="com.szy.spring.factory.BeanFactory" factory-method="UserBeanService" />
使用實例工廠方法實例化
<bean id="factory" class="com.szy.spring.factory.BeanFactory" />
<bean id="userBean3" factory-bean="factory" factory-method="getUserBeanService" />
aop面向切面編程
可以應用於分布在多個方法中的應用
可以作日志、可以做事務、可以做審計
可以用動態代理實現
在項目中怎么應用的?項目中主要應用於聲明式事務
//讀取配置文件
ApplicationContext =new ClassPathXmlApplicationContext("applicationContext.xml");
//獲取UserBean的實例
PersonBean bean=(PersonBean)ctx.getBean("userBean");
//調用方法
bean.show();
Spring管理Bean的原理
Spring的配置文件中記錄了類的包路徑,因此我們首先是要讀入配置文件。在配置文件中Bean有id和class兩個屬性。
Spring底層會去解析xml文件,並將里面的bean獲取出來,封裝到一個Map中,同時還提供了getBean這個方法。
解析XML的幾種方式
(1)DOM解析
(2)SAX(Simple API for XML)解析
(3)JDOM(Java-based Document Object Model)
(4)DOM4J(Document Object Model for Java)
(5)StAX(Streaming API for XML)
Dom
Dom是將整個xml文檔以樹型結構加載到內存中,可以進行crud操作
Sax
sax它是讀取一行,解析一行,只能做查詢操作
默認情況下,Spring的Ioc容器啟動時會初始化bean,但是我們可以指定Bean節點的lazy-init="true",來延遲初始化bean。這時候,只有第一次獲取bean才會初始化bean。
依賴注入的簡單實現 ----------------------------------------- Spring的核心機制是依賴注入。依賴注入讓bean與bean之間以配置文件組織在一起,而不是以硬編碼的方式耦合在一起。依賴注入(Dependency Injection)和控制反轉(Inversion of Control)是同一個概念。具體含義是:當某個角色(可能是一個Java實例,調用者)需要另一個角色(另一個Java實例,被調用者)的協助時,在傳統的程序設計過程中,通常由調用者來創建被調用者的實例。但在Spring里,創建被調用者的工作不再由調用者來完成,因此稱為控制反轉;創建被調用者實例的工作通常由Spring容器來完成,然后注入調用者,因此也稱為依賴注入。不管是依賴注入,還是控制反轉,都說明Spring采用動態、靈活的方式來管理各種對象。對象與對象之間的具體實現互相透明。
注解注入 如果使用前面的兩種方法,配置文件將會顯得很臃腫,因此我們可以使用注解的方式注入,使用注解方式注入有兩種方法,
第一種使用javax.annotation.Resource中提供的注解方式方法如下: @Resource默認是按照名稱裝配,找不到與名稱匹配的bean時按類型裝配 第二中方式就是使用spring提供的注解方式 org.springframework.beans.factory.annotation.Autowired; @Autowired默認使用類型進行裝配,
在使用時建議使用@Resource,因為@Resource不依賴於spring框架。
Spring自動掃描和管理Bean -------------------------------------------------
在前面的例子中,都是使用XML的bean定義來使用組件,在大的項目中,通常會有上百個組件,如果這些組件采用xml的bean定義來配置,顯然會使配置文件顯得很臃腫,查找和維護起來不方便。 Spring2.5為我們引入了組件自動掃描機制,它可以在類路徑下尋找標記了@Component、@Service、@Controller、@Repository注解的類,並把這些類納入到spring容器中管理,它的作用和在xml中使用bean節點配置組件一樣。要使用自動掃描機制,我們需要把配置文件如下配置:
<context:component-scan base-package="com.szy.spring"></context:component-scan>
其中base-package為需要掃描的包(包括子包)
@Service用於標注業務層的組件,@Controller用於標注控制層組件(如struts中的action),@Repository用於標注數據訪問組件,即DAO組件,而@Component泛指組件,當組件不好歸類的時候,我們可以使用這個注解進行標注。但是在目前的spring版本中,這幾個注解的作用是一樣的,但是在以后可能會進行區分。
靜態代理和動態代理模式 代理模式分為靜態代理和動態代理。 靜態代理就是我們自己定義的代理類,動態代理是程序在運行時生成的代理類。
實現原理:代理類和目標對象實現同一個接口,代理類持有目標對象的引用。 代理對象其實就是隔在目標對象和調用者中間的一扇門。
動態代理 動態代理它可以直接給某一個目標對象生成一個代理對象,而不需要代理類存在。 動態代理與代理模式原理是一樣的,只是它沒有具體的代理類,直接通過反射生成了一個代理對象。 動態代理生成技術: 1.jdk提供一個Proxy類可以直接給實現接口類的對象直接生成代理對象。實現接口。 2.cglib (spring學習)繼承父類。 反射原理:
在理解反射的時候,不得不說一下內存。 先理解一下JVM的三個區:堆區,棧區,和方法去(靜態區)。 堆區:存放所有的對象,每個對象都有一個與其對應的class信息。在JVM中只有一個堆區,堆區被所有的線程共享。 棧區:存放所有基礎數據類型的對象和所有自定義對象的引用,每個線程包含一個棧區。每個棧區中的數據都是私有的,其他棧不能訪問。 棧分為三部分: 基本類型變量區、執行環境上下文、操作指令區(存放操作指令)。 方法區:即靜態區,被所有的線程共享。方法區包含所有的class和static變量。它們都是唯一的。 在啟動一個java虛擬機時,虛擬機要加載你程序里所用到的類 ,這個進程會首先跑到jdk中(在jdk的jre/lib/ext文件夾里找那些jar文件),如果沒有找到,會去classpath里設置的路徑去找。 在找到要執行的類時: 1.首先將找到的類的信息加載到運行時數據區的方法區。這個過程叫做類的加載。所以一下static類型的在類的加載過程中就已經放到了方法區。所以不用實例化就能用一個static類型的方法。 2.加載完成后,在new一個類時,首先就是去方法區看看有沒有這個類的信息。如果沒有這個類的信息,先裝載這個類。then,加載完成后,會在堆區為 new的這個類分配內存,有了內存就有了實例,而這個實例指向的是方法區的該類信息。其實就是存放了在方法區的地址。而反射就是利用了這一點。
|