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='珠海'}