Unit01: Spring简介 、 Spring容器 、 Spring IOC
Spring
(1)Spring是什么?
Spring是一个开源的用来简化应用开发的框架。
(2)Spring的特点?
简化开发
Spring对很多常用的api做了简化(比如,Spring对jdbc就做了很好的 封装,我们利用Springjdbc访问数据库,就不用考虑如何获取连接和关闭 连接)。
解耦
Spring帮我们管理对象之间的依赖关系,这样,便于代码的维护。
集成
Spring可以集成其它的一些框架。集成之后,这些框架的使用会变得 更加的简单。
(3)Spring容器
Spring容器是什么?
Spring框架当中的一个核心模块,用来管理对象。
如何启动Spring容器?
step1. 导包。
step2. 添加配置文件。
step3. 编写启动Spring容器的代码。
如何创建对象?
方式一 无参构造器
step1. 类应用提供无参构造器(或者缺省构造器)。
step2. 在配置文件当中,添加一个bean元素。
step3. 启动Spring容器,调用容器提供的getBean方法获得要创建的
对象。
方式二 静态工厂方法 (了解)
方式三 实例工厂方法 (了解)
生命周期的管理
初始化方法 :
(用于获取资源,只执行一次)。
销毁方法:
(用于释放资源,只执行一次)。
注意,销毁方法只有在作用域为singleton才起作用。
作用域
默认情况下,对于一个bean元素,容器只会创建一个对应的实例。
可以设置作用域为prototype(原型,多个实例)。
延迟加载 (了解)
默认情况下,当容器启动之后,会将所有作用域为单例的bean创建好。
lazy-init属性:如果值为true,表示延迟加载,即容器启动之后,不会立即创建该实例。
(4)IOC (Inversion Of Controll 控制反转)
什么是IOC?
对象之间的依赖关系由容器来建立。
什么是DI? (Dependency Injection 依赖注入)
容器通过调用set方法或者构造器来建立对象之间的依赖关系。
注: IOC是目标,而DI是手段。
依赖注入的两种方式
方式一 set方法。
step1. 添加set方法。
step2. 配置set方法注入。
代码演示:
依赖的Jar包:
<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>com.tarena.spring</groupId> <artifactId>spring-day01</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>3.2.8.RELEASE</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> </dependencies> </project>
src/main/java/
basic
package basic; public class MessageBean { public MessageBean() { System.out.println("MessageBean()"); } public void init(){ System.out.println("init()"); } public void sendMsg(){ System.out.println("sendMsg()"); } public void destroy(){ System.out.println("destroy()"); } }
package basic; public class ScopeBean { public ScopeBean() { System.out.println("ScopeBean()"); } }
first
package first; import java.util.Calendar; import java.util.Date; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class FirstSpring { public static void main(String[] args) { //step1. 启动Spring容器 /* * ClassPathXmlApplicationContext * 会依据类路径查找配置文件。 */ ApplicationContext ac = new ClassPathXmlApplicationContext( "applicationContext.xml"); //System.out.println(ac); //step2. 通过容器,获得对象。 Student stu1 = ac.getBean("stu1",Student.class); System.out.println(stu1); Date date1 = ac.getBean("date1",Date.class); System.out.println(date1); Calendar cal1 = ac.getBean("cal1",Calendar.class); System.out.println("cal1:" + cal1); Date time1 = ac.getBean("time1",Date.class); System.out.println("time1:" + time1); } }
package first; public class Student { public Student() { System.out.println("Student()"); } }
ioc
package ioc; public class A { private B b; public void setB(B b) { System.out.println("A's setB()"); this.b = b; } public A() { System.out.println("A()"); } public void service(){ System.out.println("A's service()"); //调用B的f1()方法 b.f1(); } }
package ioc; public class B { public B() { System.out.println("B()"); } public void f1(){ System.out.println("B's f1()"); } }
src/main/resource
<?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:context="http://www.springframework.org/schema/context" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:util="http://www.springframework.org/schema/util" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd"> <!-- 利用无参构造器创建对象。 id属性:bean的名称,要求唯一。 class属性:类的全限定名。 --> <bean id="stu1" class="first.Student"> </bean> <bean id="date1" class="java.util.Date"> </bean> <!-- 使用静态工厂方法创建对象。 factory-method属性:指定一个静态方法, Spring容器会调用这个方法来创建对象。 --> <bean id="cal1" class="java.util.Calendar" factory-method="getInstance"> </bean> <!-- 使用实例工厂方法创建对象 factory-bean属性:指定一个bean的id , Spring容器会调用该对象对应的方法 来创建对象。 --> <bean id="time1" factory-bean="cal1" factory-method="getTime"> </bean> </beans>
<?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:context="http://www.springframework.org/schema/context" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:util="http://www.springframework.org/schema/util" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd"> <!-- init-method属性:指定初始化方法。 destroy-method属性:指定销毁方法。 lazy-init属性:如果值为true,表示延迟加载, 即容器启动之后,不会立即创建该实例。 --> <bean id="mb1" class="basic.MessageBean" init-method="init" destroy-method="destroy" lazy-init="true"> </bean> <!-- scope属性:指定作用域,缺省值是 singleton(单例,即单个实例); 可以设置作用域为prototype(原型,多个实例)。 --> <bean id="sb1" class="basic.ScopeBean" scope="prototype"> </bean> </beans>
<?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:context="http://www.springframework.org/schema/context" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:util="http://www.springframework.org/schema/util" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd"> <bean id="b1" class="ioc.B"/> <!-- set方法注入。 容器会调用setB方法来建立依赖关系。 --> <bean id="a1" class="ioc.A"> <property name="b" ref="b1"/> </bean> </beans>
src/test/java
test
package test; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import basic.MessageBean; import basic.ScopeBean; import ioc.A; public class TestCase { @Test //测试 初始化方法和销毁方法 public void test1(){ //启动spring容器 String config = "basic.xml"; /* * ApplicationContext接口没有提供 * 关闭容器的方法。 */ AbstractApplicationContext ac = new ClassPathXmlApplicationContext( config); //通过容器获得对象 MessageBean mb1 = ac.getBean("mb1",MessageBean.class); mb1.sendMsg(); //关闭容器 ac.close(); } @Test //测试 作用域 public void test2(){ //启动spring容器 String config = "basic.xml"; ApplicationContext ac = new ClassPathXmlApplicationContext( config); ScopeBean sb1 = ac.getBean("sb1",ScopeBean.class); ScopeBean sb2 = ac.getBean("sb1",ScopeBean.class); System.out.println(sb1 == sb2); } @Test //测试 延迟加载 public void test3(){ //启动spring容器 String config = "basic.xml"; ApplicationContext ac = new ClassPathXmlApplicationContext( config); } @Test //测试 依赖注入 public void test4(){ //启动spring容器 String config = "ioc.xml"; ApplicationContext ac = new ClassPathXmlApplicationContext( config); A a1 = ac.getBean("a1",A.class); a1.service(); } }
下面是上面这个案例:ioc包下的方法升级版:
增加一个IB接口,B.java , C.java实现IB.java接口,实现f1()方法,能让A.java灵活调用B和C下的f1方法。
ioc
接口:
package ioc; public interface IB { public void f1(); }
package ioc; public class A { private IB b; public void setB(IB b) { System.out.println("A's setB()"); this.b = b; } public A() { System.out.println("A()"); } public void service(){ System.out.println("A's service()"); //调用B的f1()方法 b.f1(); } }
package ioc; public class B implements IB{ public B() { System.out.println("B()"); } public void f1(){ System.out.println("B's f1()"); } }
package ioc; public class C implements IB{ public C() { System.out.println("C()"); } public void f1(){ System.out.println("C's f1()"); } }