开源:源码公开、免费试用;
简化:简化企业级开发。
解耦:耦合度降低、可插拔,便于后续维护更新升级拓展。
Spring 框架的这些模块可以满足一切企业级应用开发的需求,在开发过程中可以根据需求有选择性地使用所需要的模块。
官网:Spring | Home
Core 核心模块:提供了 Spring 框架的基本组成部分,包括 IoC 和 DI 功能。
Context 上下文模块:建立在核心和 Beans 模块的基础之上,它是访问定义和配置任何对象的媒介。ApplicationContext 接口是上下文模块的焦点。
容器:Spring 是一个容器,因为它包含并且管理应用对象的生命周期。
控制反转:IOC (Inversion of Control),指的是将对象的创建权交给 Spring 去创建。
使用 Spring 之前,对象的创建都是由我们自己在代码中 new 创建。而使用 Spring之后。对象的创建都是由给了 Spring 框架。
IOC (Inversion of Control) 是指在程序开发中,对象实例的创建不再由调用者管理,而是由 Spring 容器创建。Spring 容器会负责控制程序之间的关系,而不是由程序代码直接控制,因此,控制权由程序代码转移到了 Spring 容器中,控制权发生了反转,这就是 Spring 的 IOC 思想。
IOC容器的概念:IOC 容器就是具有依赖注入功能的容器,IOC 容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。应用程序无需直接在代码中 new 相关的对象,应用程序由 IOC 容器进行组装。在 Spring 中 BeanFactory 是 IOC 容器的实际代表者。
Bean的概念:在 Spring 中,被 Spring 容器所管理的对象称之为”Bean”对象。一个 Spring 的 Bean 对象可以是任何形式的 POJO。
依赖注入:DI (Dependency Injection),是指依赖的对象不需要手动调用 setXX 方法去设置,而是通过配置赋值。
SpringIOC容器类型:Spring 提供了两种 IoC 容器,分别为 BeanFactory 和 ApplicationContext。
BeanFactory 是基础类型的 IoC 容器。它由org.springframework.beans.facytory.BeanFactory 接口定义,并提供了完整的 IoC服务支持。简单来说, BeanFactory 就是一个管理 Bean 的工厂,它主要负责初始化各种Bean,并调用它们的生命周期方法。
ApplicationContext 是 BeanFactory 的子接口,也被称为应用上下文。
ClassPathXmlApplicationContext:该 类 从 类 路 径 ClassPath 中 寻 找 指 定 的 XML 配 置 文 件 , 找 到 并 装 载 完 成ApplicationContext 的实例化工作。
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(String configLocation);
使用Spring之前的痛点:对象自己创建,每次修改源码都需要重新编译,耦合度过高,不便于后续更新升级。
下面以找对象为例。
public interface GirlFriend {
void say();
}
实现类:
// 吴俊峰找女朋友的标准
public class GirlfriendImplWJF implements GirlFriend{
@Override
public void say() {
System.out.println("小峰峰");
}
}
实现类2:
// 杨涵找女朋友的标准
public class GirlfriendImplYh implements GirlFriend{
@Override
public void say() {
System.out.println("小涵涵");
}
}
测试:
public class TestGirlfriend {
public static void main(String[] args) {
/*GirlFriend gf = new GirlfriendImplWJF();
gf.say();*/
// 任玉涛要换成杨涵的标准,强耦合,每次都需要修改源码,重新编译
GirlFriend gf = new GirlfriendImplYh();
gf.say();
}
}
2.1 配置主配置文件application_context.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="girlFriendWJF" class="com.dyh.pojo.impl.GirlfriendImplWJF"
scope="singleton">
bean>
<bean id="girlFriendYh" class="com.dyh.pojo.impl.GirlfriendImplYh"
scope="prototype">
bean>
beans>
2.2 测试TestGirlfriendSpringIOC.java
package com.dyh.test;
import com.dyh.pojo.iter.GirlFriend;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestGirlfriendSpringIOC {
public static void main(String[] args) {
// ac 是一个Spring IoC 容器,需要的时候去容器中获取,不需要new
ApplicationContext ac = new ClassPathXmlApplicationContext("application_context.xml");
//GirlFriend girlFriend = (GirlFriend) ac.getBean("girlFriendWJF");
/*GirlFriend girlFriend = (GirlFriend) ac.getBean("girlFriendYh");
girlFriend.say();
System.out.println(girlFriend);
girlFriend = (GirlFriend) ac.getBean("girlFriendYh");
System.out.println(girlFriend);*/
GirlFriend girlFriend = (GirlFriend) ac.getBean("girlFriendWJF");
girlFriend.say();
System.out.println(girlFriend);
girlFriend = (GirlFriend) ac.getBean("girlFriendWJF");
System.out.println(girlFriend);
}
}
上面案例就是,也就是如下配置,会调用GirlfriendImplYh类默认的无参构造方法实实例化对象得到id为girlFriendYh的一个Bean。
<bean id="girlFriendYh" class="com.dyh.pojo.impl.GirlfriendImplYh"
scope="prototype">
bean>
2.1 静态工厂类
public class GirlFriendFactory {
public static Girlfriend getGirlFriendFJC(){
return new GirlfriendFJC();
}
public static Girlfriend getGirlFriendCWS(){
return new GirlfriendCWS();
}
}
2.2 application_context.xml配置
静态工厂内部的方法都为静态方法,静态方法可以通过对象名直接方法,故不需要配置工厂相关的bean,只需要配置class和factory-method,也就是告诉Spring容器创建对象的时候使用那个工厂的哪个静态方法,如下所示:
<bean id="gf_Factory_fjc" class="com.dyh.factory.GirlFriendFactory"
factory-method="getGirlFriendFJC">
bean>
<bean id="gf_Factory_cws" class="com.dyh.factory.GirlFriendFactory"
factory-method="getGirlFriendCWS">
bean>
2.3 测试
public class TestGirlfriendSpringIoC {
public static void main(String[] args) {
ApplicationContext ac =
new ClassPathXmlApplicationContext("application_context.xml");
// 从Spring IoC容器中获取对象
Girlfriend girlFriend = (Girlfriend) ac.getBean("gf_Factory_cws");
girlFriend.say();
System.out.println(girlFriend);
}
}
3.1 动态工厂
public class DynamicGirlFriendFactory {
public Girlfriend getGirlFriendFJC(){
return new GirlfriendFJC();
}
public Girlfriend getGirlFriendCWS(){
return new GirlfriendCWS();
}
}
3.2 application_context.xml配置
注意动态工厂内部是成员方法,调用成员方法之前,需要先实例化工厂,所以,需要配置工厂的bean。然后通过调用此工厂的方法,实例化得到对应的bean。
<bean id="dynamicGirlFriendFactory" class="com.dyh.factory.DynamicGirlFriendFactory">bean>
<bean id="gf_dynFactory_cws" factory-bean="dynamicGirlFriendFactory" factory-method="getGirlFriendCWS">
bean>
<bean id="gf_dynFactory_fjc" factory-bean="dynamicGirlFriendFactory" factory-method="getGirlFriendFJC">
bean>
3.3 测试TestGirlfriendDynamicFactory
public class TestGirlfriendDynamicFactory {
public static void main(String[] args) {
ApplicationContext ac =
new ClassPathXmlApplicationContext("application_context.xml");
// 从Spring IoC容器中获取对象
Girlfriend girlFriend = (Girlfriend) ac.getBean("gf_dynFactory_fjc");
girlFriend.say();
System.out.println(girlFriend);
}
}
Girlfriend girlFriend = (Girlfriend) ac.getBean("gf_dynFactory_fjc");
Girlfriend girlFriend = (Girlfriend) ac.getBean(Class clazz);
获取 Bean 对象
public class GirlfriendOYY implements Girlfriend {
@Override
public void say() {
System.out.println("OMG");
}
}
配置bean
测试
public class TestGirlfriendGetByClass {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("application_context.xml");
//GirlfriendFJC bean = ac.getBean(GirlfriendFJC.class);
GirlfriendOYY bean = ac.getBean(GirlfriendOYY.class);
bean.say();
}
}
运行结果
特别注意:通过类型去获取Bean,如果配置文件中配置了多个此类型的bean,容器不知道你要获取哪个,所以,还需要指定bean的id或name属性值。如下操作:
原因:
1、理解Spring框架的作用,理解IOC(面试题)。
2、代码实现:
ApplicationContext ac = new ClassPathXmlApplicationContext("application_context.xml");