1.1Spring框架的概述 1.1.1什麼是Spring Spring是分層的JavaSE和JavaEES一站式輕量級開源框架。 分層: SUN提供的EE的三層結構:web層、業務層、數據訪問層(持久層、集成層)。 Struts2是web層基於MVC設計模式框架。 Hibernate是持久層的一個 ...
1.1 Spring框架的概述
1.1.1什麼是Spring
- Spring是分層的JavaSE和JavaEES一站式輕量級開源框架。
- 分層:
- SUN提供的EE的三層結構:web層、業務層、數據訪問層(持久層、集成層)。
- Struts2是web層基於MVC設計模式框架。
- Hibernate是持久層的一個ORM框架。
- 一站式:
- Spring框架有對三層的每層解決方案:
- web層:Spring MVC。
- 持久層:JDBC Template。
- 業務層:Spring的Bean管理。
- 分層:
1.1.2Spring的核心
- IOC(Inverse of control):控制反轉。
- 控制反轉:將對象的創建權,交由Spring管理。
- IOC原理:
- AOP(Aspect Oriented Programming):面向切麵編程。
- 面向切麵編程:是面向對象的功能延伸,不是替換面向對象,是用來解決面向對象的一些問題。
1.1.3Spring的版本
- Spring3.x版本和Spring4.x版本。Spring4.x版本需要整合Hibernate4.x版本。
1.1.4EJB:企業級的JavaBean
- EJB:SUN公司提出的EE解決方案。
1.1.5Spring的優點
- 方便解耦,簡化開發
- Spring就是一個大工廠,可以將所有對象創建和依賴關係維護,交由Spring管理。
- AOP編程的支持
- Spring提供面向切麵編程,可以方便的實現對程式進行許可權攔截、運行監控等功能。
- 聲明式事務的支持
- 只需要通過配置就可以完成對事務的管理,無需手動編程。
- 方便程式的測試
- Spring對Junit4支持,可以通過註解方便的測試Spring程式。
- 方便集成各種優秀框架
- Spring不排斥各種優秀的開源框架,其內部提供了對各種優秀框架(如:Struts2、Hibernate、MyBatis、Quartz等)的直接支持。
- 降低JavaEE API的使用難度
- Spring對JavaEE開發中非常難用的一些API(JDBC、JavaMail、遠程調用等),都提供了封裝,使得這些API應用難度大大降低。
1.2 Spring的入門
1.2.1Spring的體繫結構
- Spring框架是一個分層架構,它包含了一系列的功能要素並被分為大約20個模塊。這些模塊分為Core Container、Data Access/Integration、Web、AOP(Aspect Oriented Programming)、Instrumentation和測試部分。
1.2.2下載Spring的開發包
- spring-framework-3.2.0.RELEASE-dist.zip --Spring開發包
- docs:Spring框架的API和規範。
- libs:Spring開發的jar包。
- schema:XML的約束文檔。
- spring-framework-3.0.2.RELEASE-dependencies.zip --Spring開發中的依賴包
1.2.3創建web工程並引入相應的jar包。
- Core Container:
- spring-beans-3.2.0.RELEASE.jar
- spring-core-3.2.0.RELEASE.jar
- spring-context-3.2.0.RELEASE.jar
- spring-expression-3.2.0.RELEASE.jar
- 開發的日誌記錄的jar包:
- com.springsource.org.apache.commons.logging-1.1.1.jar 用於整合其他的日誌的jar包(類似於Hibernate中的slf4j)
- com.springsource.org.apache.log4j-1.2.15.jar
1.2.4創建Spring的配置文件
- 在src下新建一個applicationContext.xml文件
- 引入XML的約束:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> </beans>
1.2.5引入log4j.properties
### direct log messages to stdout ### log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.err log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n ### direct messages to file mylog.log ### log4j.appender.file=org.apache.log4j.FileAppender log4j.appender.file.File=c\:mylog.log log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n ### set log levels - for more verbose logging change 'info' to 'debug' ### log4j.rootLogger=info, stdout
1.2.6體驗傳統開發和Spring開發
- 創建一個介面:HelloService.java。
package cn.spring3.demo1; /** * 入門的案例 */ public interface HelloService { public void sayHello(); }
- 創建一個實現類:HelloServiceImpl.java。
package cn.spring3.demo1; public class HelloServiceImpl implements HelloService { @Override public void sayHello() { System.out.println("Hello Spring"); } }
- 傳統方式開發--多態
@Test //傳統方式 public void demo1(){ HelloService helloService = new HelloServiceImpl(); helloService.sayHello(); }
- Spring開發
- 要在applicationContext.xml文件中配置<bean>標簽
-
<!--
通過<bean>標簽設置類的信息,通過id屬性為類起個標識
-->
<bean id="helloServiceImpl" class="cn.spring3.demo1.HelloServiceImpl"/>
-
- 要在applicationContext.xml文件中配置<bean>標簽
-
- applicationContext.xml文件中內容如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 通過<bean>標簽設置類的信息,通過id屬性為類起個標識 --> <bean id="helloServiceImpl" class="cn.spring3.demo1.HelloServiceImpl"/> </beans>
-
- 測試代碼
@Test //Spring開發 public void demo2(){ //創建一個工廠類 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); HelloService helloService = (HelloService) applicationContext.getBean("helloServiceImpl"); helloService.sayHello(); }
1.2.7IOC和DI的區別?
- IOC:控制反轉,將對象的創建權,交由Spring管理。
- DI:依賴註入,在Spring創建對象的過程之中,把對象的屬性註入到類中。
- 面向對象中對象之間的關係
- 依賴:
- 面向對象中對象之間的關係
public class A{ private B b; }
-
-
- 繼承:is a。
- 聚合:
- 聚集
- 組合
- 示例:
- HelloService.java類
-
package cn.spring3.demo1; /** * 入門的案例 */ public interface HelloService { public void sayHello(); }
-
-
- HelloServiceImpl.java類
-
package cn.spring3.demo1; public class HelloServiceImpl implements HelloService { private String info; public String getInfo() { return info; } public void setInfo(String info) { this.info = info; } @Override public void sayHello() { System.out.println("Hello"+info); } }
-
-
- applicationContext.xml
-
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 通過<bean>標簽設置類的信息,通過id屬性為類起個標識 --> <bean id="helloServiceImpl" class="cn.spring3.demo1.HelloServiceImpl"> <!-- 使用 <property>標簽註入屬性--> <property name="info" value="Spring"></property> </bean> </beans>
-
-
- 測試代碼
-
@Test //Spring開發 public void demo2(){ //創建一個工廠類 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); HelloService helloService = (HelloService) applicationContext.getBean("helloServiceImpl"); helloService.sayHello(); }
1.2.8Spring框架載入配置文件
- ApplicationContext(應用上下文),載入Spring框架配置文件。
- 載入classpath:
- new ClassPathXmlApplicationContext("applicationContext.xml"); :載入classpath下麵配置文件。
- 載入磁碟路徑:
-
new FileSystemXmlApplicationContext("applicationContext.xml"); :載入磁碟下配置文件。
-
- 載入classpath:
1.2.9BeanFactory和ApplicationContext區別?
- ApplicationContext類繼承了BeanFactory。
- BeanFactory在使用到這個類的時候,getBean()方法才會載入到這個類。(延遲載入)。
- ApplicationContext類載入配置文件的時候,創建所有的類。
- ApplicationContext對BeanFactory提供了擴展的功能。
- 國際化處理。
- 事件傳遞。
- Bean自動裝配。
- 各種不同應用層的Context實現。
- ****早期開發使用BeanFactory。
1.2.10MyEclipse配置XML提示
- 複製Schema的Location。
- windows--preferences--XML Catalog
1.3 IOC裝配Bean
1.3.1Spring框架Bean實例的方式:
- 提供了三種方式實例化Bean。
- 構造方法實例化:(預設無參數)--反射
- <bean id="helloServiceImpl" class="cn.spring3.demo1.HelloServiceImpl"/>
- 構造方法實例化:(預設無參數)--反射
package cn.spring3.demo2; /** * 使用無參數的方法實例化 */ public class Bean1 { }
<bean id="bean1" class="cn.spring3.demo2.Bean1"></bean>
@Test //無參數的構造方法實例化 public void demo1(){ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); Bean1 bean1= (Bean1) applicationContext.getBean("bean1"); System.out.println(bean1); }
-
- 靜態工廠方法實例化(簡單工廠模式)--反射+簡單工廠
package cn.spring3.demo2; /** * 使用靜態工廠實例化 */ public class Bean2 { }
package cn.spring3.demo2; /** * Bean2的靜態工廠 */ public class Bean2Factory { public static Bean2 getBean2Instance(){ return new Bean2(); } }
<bean id="bean2Factory" class="cn.spring3.demo2.Bean2Factory" factory-method="getBean2Instance" ></bean>
@Test //使用靜態工廠實例化 public void demo2(){ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); Bean2 bean2= (Bean2) applicationContext.getBean("bean2Factory"); System.out.println(bean2); }
-
- 實例工廠實例化(工廠方法模式) ---反射+實例工廠
package cn.spring3.demo2; /** * 使用實例工廠 */ public class Bean3Factory { public Bean3 getBean3Instance(){ return new Bean3(); } }
package cn.spring3.demo2; /** * 使用實例工廠實例化 */ public class Bean3 { }
<!-- 用來初始化Bean3Factory --> <bean id="bean3Factory" class="cn.spring3.demo2.Bean3Factory"></bean> <bean id="bean3" factory-bean="bean3Factory" factory-method="getBean3Instance" ></bean>
@Test //使用實例工廠實例化 public void demo3(){ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); Bean3 bean3= (Bean3) applicationContext.getBean("bean3"); System.out.println(bean3); }
- 分析:
- 構造方法實例化:(預設無參數)--反射
- 直接給Spring一個完整的類名,Spring就會幫助我們實例化對象。
- 靜態工廠方法實例化(簡單工廠模式)
- 要給一個factory-method,因為靜態方法可以直接通過類名.方法()的形式來調用方法,而class="",當然是靜態工廠的類名了,因為只有這樣Spring才能幫助我們初始化工廠,返回需要的實例化對象。
- 實例工廠實例化(工廠方法模式)
- 之所以要實例化工廠,因為實例工廠不是靜態工廠,不可以通過類名.方法()的形式調用方法,所以必須先讓Spring來實例化實例工廠,然後再告訴Spring實例工廠的對象名是什麼以及什麼方法來實例化對象的。
- 構造方法實例化:(預設無參數)--反射
1.3.2Bean的其他配置
- id和name的區別
- id遵守XML約束的id的約束。id約束保證這個屬性的值是唯一的,而且必須以字母開始,可以使用字母、數字、連字元、下劃線、句號、冒號。
- name沒有這些要求
- 如果bean標簽上沒有配置id,那麼name可以作為id。
- 早期開發的時候,Spring整合Struts1,"/login"是特殊字元,只能使用name。
- <bean name="/login"/>
- 現在的開發中都使用id屬性即可。
- 類的作用範圍:
- scope屬性:
- singleton:單例的。(預設值)
- prototype:多例的。
- request:web開發中使用。創建一個對象,將這個對象存入request範圍,request.setAttribute()。
- session:web開發中使用。創建一個對象,將這個對象存入session範圍,session.setAttribute()。
- globalSession:一般用於Porlet應用環境,指的是分散式開發。不是Porlet環境,globalSession等同於session。
- 實際開發中主要使用的是singleton和prototype。
- scope屬性:
- Bean的生命周期
- 配置Bean的初始化的銷毀的方法
- init-method="setUp"。
- destory-method="teardown" 。
- 執行銷毀的時候,必須手動關係工廠,而且支隊scope="singleton"有效。
- 配置Bean的初始化的銷毀的方法
-
- 示例:
- Product.java
- 示例:
package cn.spring3.demo3; public class Product { //初始化的方法 public void setup(){ System.out.println("初始化的方法"); } //銷毀的方法 public void teardown(){ System.out.println("銷毀的方法"); } }
-
-
- applicationContext.xml
-
<bean id="product" class="cn.spring3.demo3.Product" init-method="setup" destroy-method="teardown"/>
-
-
- 測試代碼:
-
@Test //測試初始化和銷毀的方法 public void demo1(){ ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); Product product = (Product) applicationContext.getBean("product"); applicationContext.close(); }
-
- Bean的生命周期的11個步驟:
- instantiate bean對象示例化。
- populate properties 封裝屬性。
- 如果Bean實現BeanNameAware 執行setBeanName。
- 如果Bean實現BeanFactoryAware或者ApplicationContextAware設置工廠setBeanFactory或者上下文對象setApplicationContext。
- 如果存在類實現BeanPostProcessor(後處理Bean),執行postProcessBeforeInitialization。
- 如果Bean實現initializingBean,執行afterPropertiesSet。
- 調用<bean init-method="init"> 指定初始化方法init。
- 如果存在類實現BeanPostProcessor(處理Bean),執行postProcessAfterInitialization。
- 執行業務處理。
- 如果Bean實現DisposableBean,執行destory。
- 調用<bean destory-method="destory">,指定銷毀方法destory。
1.3.3Bean中屬性的註入
- Spring支持構造器註入和setter()方法註入。
- 構造器註入
package cn.spring3.demo4; public class Car { private String name; private Double price; public Car(){} public Car(String name, Double price) { super(); this.name = name; this.price = price; } @Override public String toString() { return "Car [name=" + name + ", price=" + price + "]"; } }
<!-- bean的屬性註入 --> <bean id="car" class="cn.spring3.demo4.Car" > <constructor-arg index="0" value="寶馬" /> <constructor-arg index="1" value="300000.0"/> </bean>
@Test public void demo1(){ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); Car car = (Car) applicationContext.getBean("car"); System.out.println(car);; }
-
- setter()方法註入
- 普通屬性
- setter()方法註入
package cn.spring3.demo4; public class Car2 { private String name; private Double price; public String getName() { return name; } public void setName(String name) { this.name = name; } public Double getPrice() { return price; } public void setPrice(Double price) { this.price = price; } @Override public String toString() { return "Car2 [name=" + name + ", price=" + price + "]"; } }
<bean id="car2" class="cn.spring3.demo4.Car2"> <property name="name" value="寶馬"/> <property name="price" value="300000.0"/> </bean>
@Test public void demo2(){ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); Car2 car2 = (Car2) applicationContext.getBean("car2"); System.out.println(car2);; }
-
-
- 對象屬性
-
package cn.spring3.demo4; public class Car2 { private String name; private Double price; public String getName() { return name; } public void setName(String name) { this.name = name; } public Double getPrice() { return price; } public void setPrice(Double price) { this.price = price; } @Override public String toString() { return "Car2 [name=" + name + ", price=" + price + "]"; } }
package cn.spring3.demo4; public class Person { private String name; private Car2 car; public String getName() { return name; } public void setName(String name) { this.name = name; } public Car2 getCar() { return car; } public void setCar(Car2 car) { this.car = car; } @Override public String toString() { return "Person [name=" + name + ", car=" + car + "]"; } }
<bean id="car2" class="cn.spring3.demo4.Car2"> <property name="name" value="寶馬"/> <property name="price" value="300000.0"/> </bean> <bean id="person" class="cn.spring3.demo4.Person"> <property name="name" value="神經病"/> <property name="car" ref="car2"/> </bean>
@Test public void demo3(){ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); Person person = (Person) applicationContext.getBean("person"); System.out.println(person);; }
-
- 命名空間p註入屬性
- 為了簡化XML的文件配置,Spring從2.5開始引入了一個新的p名稱空間。
- p:屬性名="xxx" 引入常量值。
- p:屬性名-ref="xxx" 引入其他bean對象
- 命名空間p註入屬性
package cn.spring3.demo4; public class Car2 { private String name; private Double price; public String getName() { return name; } public void setName(String name) { this.name = name; } public Double getPrice() { return price; } public void setPrice(Double price) { this.price = price; } @Override public String toString() { return "Car2 [name=" + name + ", price=" + price + "]"; } }
package cn.spring3.demo4; public class Person { private String name; private Car2 car; public String getName() { return name; } public void setName(String name) { this.name = name; } public Car2 getCar() { return car; } public void setCar(Car2 car) { this.car = car; } @Override public String toString() { return "Person [name=" + name + ", car=" + car + "]"; } }
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="car2" class="cn.spring3.demo4.Car2" p:name="寶馬" p:price="200000.0"/> <bean id="person" class="cn.spring3.demo4.Person" p:name="神精病" p:car-ref="car2"/> </beans>
@Test public void demo3(){ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); Person person = (Person) applicationContext.getBean("person"); System.out.println(person);; }
-
- SPEL: Spring Expression Language,Spring表達式語言,對依賴註入進行簡化。
- 語法:#{表示式}
- <bean id="" value="#{}"/>
- SPEL: Spring Expression Language,Spring表達式語言,對依賴註入進行簡化。
package cn.spring3.demo5; public class Product { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="product" class="cn.spring3.demo5.Product" > <property name="name" value="#{'哇哈哈'}"></property> </bean> </beans>
@Test public void demo1(){ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); Product product = (Product) applicationContext.getBean("product"); System.out.println(product.getName()); }
1.3.4集合屬性的註入
package cn.spring3.demo6; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; public class CollectionDemo { private List<String> list; private Set<String> set; private Map<String, Integer> map; private Properties properties; public List<String> getList() { return list; } public void setList(List<String> list) { this.list = list; } public Set<String> getSet() { return set; } public void setSet(Set<String> set) { this.set = set; } public Map<String, Integer> getMap() { return map; } public void setMap(Map<String, Integer> map) { this.map = map; } public Properties getProperties() { return properties; } public void setProperties(Properties properties) { this.properties = properties; } }
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="collectionDemo" class="cn.spring3.demo6.CollectionDemo"> <property name="list"> <list > <value>哈哈</value> <value>呵呵</value> </list> </property> <property name="set"> <set> <value>嘻嘻</value> <value>笨笨</value> </set> </property> <property name="map"> <map> <e