Spring是一個輕量級的控制反轉(IoC)和麪向切面(AOP)的容器(框架)。git
官網: http://spring.iogithub
文檔: https://docs.spring.io/spring/docs/current/spring-framework-reference/、 https://github.com/waylau/spring-framework-4-referencespring
中文幫助: http://spring.cndocs.ml/apache
框架下載地址: http://repo.springsource.org/libs-release-local/org/springframework/spring/編程
教程: http://www.yiibai.com/springapp
Git: https://github.com/spring-projects框架
源碼: https://github.com/spring-projects/spring-frameworkyii
Jar包: https://github.com/spring-projects/spring-framework/releasesmaven
輕量:從大小與開銷兩方面而言Spring都是輕量的。完整的Spring框架能夠在一個大小隻有1MB多的JAR文件裏發佈。而且Spring所需的處理開銷也是微不足道的。此外,Spring是非侵入式的:典型地,Spring應用中的對象不依賴於Spring的特定類。ide
控制反轉Ioc:Spring經過一種稱做控制反轉(IoC)的技術促進了低耦合。當應用了IoC,一個對象依賴的其它對象會經過被動的方式傳遞進來,而不是這個對象本身建立或者查找依賴對象。你能夠認爲IoC與JNDI相反——不是對象從容器中查找依賴,而是容器在對象初始化時不等對象請求就主動將依賴傳遞給它。
控制反轉是一種經過描述(XML或註解)並經過第三方去生產或獲取特定對象的方式。在Spring中實現控制反轉的是IoC容器,其實現方法是依賴注入(Dependency Injection,DI)。
面向切面Aop:Spring提供了面向切面編程的豐富支持,容許經過分離應用的業務邏輯與系統級服務(例如審計(auditing)和事務(transaction)管理)進行內聚性的開發。應用對象只實現它們應該作的——完成業務邏輯——僅此而已。它們並不負責(甚至是意識)其它的系統級關注點,例如日誌或事務支持。
容器:Spring包含並管理應用對象的配置和生命週期,在這個意義上它是一種容器,你能夠配置你的每一個bean如何被建立——基於一個可配置原型(prototype),你的bean能夠建立一個單獨的實例或者每次須要時都生成一個新的實例——以及它們是如何相互關聯的。然而,Spring不該該被混同於傳統的重量級的EJB容器,它們常常是龐大與笨重的,難以使用。
框架:Spring能夠將簡單的組件配置、組合成爲複雜的應用。在Spring中,應用對象被聲明式地組合,典型地是在一個XML文件裏。Spring也提供了不少基礎功能(事務管理、持久化框架集成等等),將應用邏輯的開發留給了你。
MVC:Spring的做用是整合,但不單單限於整合,Spring 框架能夠被看作是一個企業解決方案級別的框架,Spring MVC是一個很是受歡迎的輕量級Web框架。
全部Spring的這些特徵使你可以編寫更乾淨、更可管理、而且更易於測試的代碼。它們也爲Spring中的各類模塊提供了基礎支持。
假設項目中須要完成對動物的數據訪問服務。
建立maven項目:
咱們定義好了Animal接口與Cat、Dog實現類、和Service業務類。
Animal接口:
package Animal; /** * 動物接口 */ public interface Animal { // 叫的方法 public String cry(); // 跑的方法 public String run(); }
Cat、Dog實現類:
package Animal; public class Cat implements Animal { public String cry() { return "貓在叫"; } public String run() { return "貓在跑"; } }
package Animal; public class Dog implements Animal { public String cry() { return "狗在叫"; } public String run() { return "狗在跑"; } }
Maven項目的pom.xml以下:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>spring</groupId> <artifactId>Spring</artifactId> <version>1.0-SNAPSHOT</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <spring.version>4.3.0.RELEASE</spring.version> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> <version>4.10</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.9</version> </dependency> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.2.4</version> </dependency> </dependencies> </project>
容器的配置文件spring.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"> <!--指定惟一id和要聲明的對象class--> <bean id="animal" class="Animal.Dog"></bean> <bean id="animal2" class="Animal.Cat"></bean> </beans>
Service業務類:
package Animal; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Service { Animal animal; Animal anima2; public void operation(){
/**
* 不用編碼對Animal實例化,又第三方(Spring)對指定的編碼進行實例化
*/ //獲取容器 ApplicationContext applicationContext=new ClassPathXmlApplicationContext("spring.xml"); //從容器中獲取id爲animal的bean animal=applicationContext.getBean("animal",Animal.class); System.out.println(animal.cry()); System.out.println(animal.run()); //從容器中獲取id爲animal2的bean anima2=applicationContext.getBean("animal2",Animal.class); System.out.println(anima2.cry()); System.out.println(anima2.run()); } }
測試類Test以下:
package test.Animal; import Animal.Service; import org.junit.Test; import org.junit.Before; import org.junit.After; /** * Service Tester. */ public class ServiceTest { @Before public void before() throws Exception { } @After public void after() throws Exception { } /** * * Method: operation() * */ @Test public void testOperation() throws Exception { Service service=new Service(); service.operation(); } }
運行結果:
Person.class
package com.dinghuoqin.spring02; public abstract class Person { // 姓名 public String name;public String getName() { return name; } public void setName(String name) { this.name = name; } }
Student.class
package com.dinghuoqin.spring02; //學生 public class Student extends Person { // 身高 public int height; // 有參構造 public Student(String name,int height){ this.name=name; this.height=height; } @Override public String toString() { return "Student{" + "height=" + height + ", name='" + name + '\'' + '}'; } }
package com.dinghuoqin.spring02; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class School { public static void main(String[] args) { // loC容器 ApplicationContext ctx=new ClassPathXmlApplicationContext("beans02.xml"); // 從容器中獲取對象 Person tom=ctx.getBean("tom",Person.class); Address zhuhai=ctx.getBean("zhuhai",Address.class); System.out.println(tom); System.out.println(zhuhai); Person tom1=ctx.getBean("tom",Person.class); Person tom2=ctx.getBean("tom",Person.class); System.out.println(tom1==tom2); Person rose1=ctx.getBean("rose",Person.class); Person rose2=ctx.getBean("rose",Person.class); System.out.println(rose1==rose2); } }
School.class
package com.dinghuoqin.spring02; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class School { public static void main(String[] args) { // loC容器 ApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml"); // 從容器中獲取對象 Person tom=ctx.getBean("tom",Person.class); System.out.println(tom); } }
beans.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="tom" class="com.spring02.Student"> <constructor-arg index="name" value="張三"></constructor-arg> <constructor-arg index="height" value="175"></constructor-arg> </bean> </beans>
結果:
Student{height=175, 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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="tom" class="com.spring02.Student"> <constructor-arg index="0" value="張三"></constructor-arg> <constructor-arg index="1" value="175"></constructor-arg> </bean> </beans>
結果:
Student{height=175, name='張三'}
新加Address.class
package com.dinghuoqin.spring02; public class Address { // 國家 private String country; // 城市 private String city; public Address(){}; public Address(String country, String city) { this.country = country; this.city = city; } @Override public String toString() { return "Address{" + "country='" + country + '\'' + ", city='" + city + '\'' + '}'; } public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } }
修改Person.class
package com.dinghuoqin.spring02; public abstract class Person { // 姓名 public String name; // 地址 public Address address; public String getName() { return name; } public void setName(String name) { this.name = name; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } }
修改Student.class
package com.dinghuoqin.spring02; //學生 public class Student extends Person { // 身高 public int height;// 有參構造 public Student(String name,int height,Address address){ this.name=name; this.height=height; this.address=address; } @Override public String toString() { return "Student{" + "height=" + height + ", name='" + name + '\'' + ", address=" + address + '}'; } }
School.class
package com.dinghuoqin.spring02; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class School { public static void main(String[] args) { // loC容器 ApplicationContext ctx=new ClassPathXmlApplicationContext("beans02.xml"); // 從容器中獲取對象 Person tom=ctx.getBean("tom",Person.class);
Person zhuhai=ctx.getBean("zhuhai",Address.class)
System.out.println(tom);
System.out.println(zhuhai);
} }
beans02.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="tom" class="com.spring02.Student"> <constructor-arg index="0" value="張三"></constructor-arg> <constructor-arg index="1" value="175"></constructor-arg> <constructor-arg name="address" ref="zhuhai"></constructor-arg> </bean> <bean name="zhuhai" class="com.spring02.Address"> <property name="country" value="中國"></property> <property name="city" value="珠海"></property> </bean> </beans>
結果:
Student{height=175, name='張三', address=Address{country='中國', city='珠海'}}
Address{country='中國', city='珠海'}
便捷方式:
<?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="zhuhai2" class="com.spring02.Address" p:country="中國" p:city="珠海"></bean> </beans>
package com.dinghuoqin.spring02; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class School { public static void main(String[] args) { // loC容器 ApplicationContext ctx=new ClassPathXmlApplicationContext("beans02.xml"); // 從容器中獲取對象 Person zhuhai=ctx.getBean("zhuhai2",Address.class) System.out.println(zhuhai); } }
結果:
Address{country='中國', city='珠海'}
從容器中取回的對象默認是單例的:
package com.dinghuoqin.spring02; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class School { public static void main(String[] args) { // loC容器 ApplicationContext ctx=new ClassPathXmlApplicationContext("beans02.xml"); // 從容器中獲取對象 Person tom1=ctx.getBean("tom",Person.class); Person tom2=ctx.getBean("tom",Person.class); System.out.println(tom1==tom2); } }
結果:
使用scope屬性能夠指定做用域
<bean id="rose" class="com.spring02.Student" scope="prototype"> <constructor-arg name="name" value="張柏川"></constructor-arg> <constructor-arg name="height" value="195"></constructor-arg> <constructor-arg name="address" ref="zhuhai"></constructor-arg> </bean>
測試代碼:
package com.dinghuoqin.spring02; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class School { public static void main(String[] args) { // loC容器 ApplicationContext ctx=new ClassPathXmlApplicationContext("beans02.xml"); // 從容器中獲取對象 Person rose1=ctx.getBean("rose",Person.class); Person rose2=ctx.getBean("rose",Person.class); System.out.println(rose1==rose2); } }
結果:
Student{height=175, name='張三', address=Address{country='中國', city='珠海'}}
Address{country='中國', city='珠海'}