重点
Spring容器的初始化;
实例对象的获取;
Spring的核心容器
依赖注入中setter方法注入的实现
1.1Spring是什么
Spring是一个分层的Java SE/EE full-stack 轻量级框架,它以IoC和AOP为内核。
表现层(Web) | Spring MVC 以及与Struts的整合 |
业务逻辑层(Service) | 管理事务、记录日志 |
持久层(Dao) | 整合MyBatis、Hibernate、JdbcTemplate等技术 |
1.2 Spring的体系结构
1.Core Container(核心容器)
Spring的核心容器是其他模块建立的基础。
- Beans 模块:Spring的顶层接口,提供了BeanFactory,Spring将管理对象称为Bean;
- Core核心模块:提供了Spring框架的基本组成部分,包括IoC和DI功能;
- Context上下文模块:访问定义和配置的任何对象的媒介。ApplicationContext接口是上下文模块的焦点;
- SpEL模块:提供了强大的表达式语言。
2.Data Access/Integration(数据访问/集成)
- JDBC模块:JDBC的抽象封装,减少了在开发过程中对数据库操作的编码;
- ORM模块:对流行的对象关系映射API,集成了JPA、JDO、Hibernate;
- OXM模块
- JMS模块
- Transactions事务模块:实现特殊接口
3.Web
- WebSocket
- Servlet模块:模型-视图-控制器(MVC)
- Web模块:提供了基本的Web开发集成特性,eg:多文件上传功能,使用Servlet监听器来初始化IoC容器以及Web应用上下文
- Portlet模块
4.其他模块
- AOP模块:面向切面编程;
- Aspects模块:提供了与AspectJ的集成功能,AspectJ是一个功能强大且成熟的面向切面编程框架;
- Instrumentation
- Messaging
- Test模块
1.3Spring的核心容器
两种核心容器:BeanFactory和ApplicationContext
1.3.1BeanFactory(不常用)
管理Bean的工厂,主要负责初始化各种Bean,并调用他们的周期方法。
BeanFactory接口提供了几个实现类,最常用的是org.springframework.beans.factory.xml.XmlBeanFactory,该类会根据XML配置文件中的定义来装配Bean.
1.3.2ApplicationContext
BeanFactory的子接口,由org.springframework.context.ApplicationContext接口定义,不仅包含了BeanFactory的所有功能,还添加了对国际化、资源访问、事件传播等方面的支持。
创建ApplicationContext接口实例,方法如下:
1.通过ClassPathXmlApplicationContext创建
从类路径classPath中寻找指定的XML配置文件,找到并装载完成ApplicationContext的实例化工作
ApplicationContext applicationContext =
new ClassPathXmlApplicationContext(String configLocation);
2.通过FileSystemXmlApplicationContext创建
从指定的文件系统路径(绝对路径)中寻找指定的XML配置文件,会导致程序的灵活性变差,不推荐使用。
- 在使用Spring框架时,可以通过实例化其中任何一个类来创建ApplicationContext容器。
- Java项目:通过ClassPathXmlApplicationContext来实例化ApplicationContext容器
- Web项目:Web容器基于ContextLoaderListener实现方式来实例化ApplicationContext容器
1.4Spring获取Bean实例的方法
1.Object getBean(String name):根据容器中Bean的id或name来获取指定的Bean,获取之后需要进行强制类型转换。(返回的是Object类型)
2.<T>T getBean(Class<T> requiredType):根据类的类型来获取Bean的实例。泛型方法,在获取Bean之后不需要进行强制类型转化。
1.5Spring的入门程序
(1)创建名为Chapter01的项目后,创建com.itheima.ioc包,在包中创建接口UserQi,定义say()方法
package com.itheima.ioc;
public interface UserQi {
public void say();
}
(2)在包下创建UserQi接口的实现类UserQiImpl,该类需要实现接口中的say()方法
package com.itheima.ioc;
public class UserQiImpl implements UserQi {
public void say(){
System.out.println("UserQi say hello world");
}
}
(3)在src目录下创建Spring的配置文件applicationContext.xml,并在配置文件中创建一个id为userQi的bean
<?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-4.3.xsd">
<!-- 将指定类配置给spring,让spring创建其对象的实例 -->
<bean id="userQi" class="com.itheima.ioc.UserQiImpl"></bean>
</beans>
(4) 创建测试类TestIoC
package com.itheima.ioc;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestIoC {
public static void main(String[] args) {
//1.初始化spring容器,加载配置文件
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//2.通过容器获取userQi实例
UserQi userQi = (UserQi) applicationContext.getBean("userQi");
//3.调用实例中的say()方法
userQi.say();
}
}
执行结束后,控制台输出的结果:
1.6 依赖注入
1.6.1依赖注入概念
当某个Java对象(调用者)需要调用另一个Java对象(被调用者,即被依赖对象)时,
- 传统模式下,调用者会采用“new被调用者”的代码方式来创建对象,这种方式会导致调用者与被调用者之间的耦合性增加,不利于后期项目的升级和维护。
- 在使用Spring框架后,对象的实例不再由调用者来创建,而是由Spring容器来创建,Spring容器会控制程序之间的关系,而不是由调用者的程序代码直接控制。这样控制权就发生了反转。
从SPring容器的角度来看,Spring容器负责将被依赖对象赋值给调用者的成员变量,这相当于为调用者注入了它依赖的对象,这就是Spring的依赖注入
1.6.2依赖注入的实现方式
- 属性setter方法注入:指Spring容器使用setter方法注入被依赖的实例。通过调用无参构造器或无参静态工厂方法实例化Bean后,调用该Bean的setter方法。
- 构造方法注入:指Spring容器使用构造方法注入被依赖的实例。基于构造方法的依赖注入通过调用带参数的构造方法来实现。
setter方法注入例子:
(1)创建接口UserService,在接口中编写一个say()方法
package com.itheima.ioc;
public interface UserService {
public void say();
}
(2)创建UserService接口的实现类UserServiceImpl
- 想调用userQi中的方法,得依赖它,所以先声明属性。
- userQi是空的,想依赖它得先为userQi添加一个setter方法。Alt+Shift+s
package com.itheima.ioc;
public class UserServiceImpl implements UserService {
//3、声明UserQi属性
private UserQi userQi;
//4、添加UserQi属性的setter方法,用于实现依赖注入
public void setUserQi(UserQi userQi) {
this.userQi = userQi;
}
//实现接口中的方法
public void say() {
// TODO Auto-generated method stub
//2、调用userQi中的say()方法,并执行输出语句
this.userQi.say();
//1、
System.out.println("userService say hello World!");
}
}
(3)在配置文件applicationContext.xml中,创建一个id为userService的Bean,用来实例化UserServiceImpl类的信息;并将userQi的实例注入到userService中
<bean id="userService" class="com.itheima.ioc.UserServiceImpl">
<!-- 将id为userQi的Bean实例注入到userService实例中-->
<property name="userQi" ref="userQi"/>
</bean>
<property>是<bean>元素的子元素,用于调用Bean示例中的setUserQi()方法完成属性赋值,从而实现依赖注入。name属性表示Bean实例中的相应属性名,ref属性用于指定其属性值。
(4)创建测试类TestDI
package com.itheima.ioc;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestDI {
public static void (String[] args){
//1.初始化spring容器,加载配置文件
ApplicationContext applicationContext=
new ClassPathXmlApplicationContext("applicationContext.xml");
//2.通过容器获取UserService实例
UserService userService=(UserService) applicationContext.getBean("userService");
//3.调用实例中的say()方法
userService.say();
}
}
执行结果: