<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.0modelVersion>
<groupId>com.bygroupId>
<artifactId>Spring_IOC_XmlartifactId>
<version>1.0-SNAPSHOTversion>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
<maven.compiler.source>8maven.compiler.source>
<maven.compiler.target>8maven.compiler.target>
properties>
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>5.1.8.RELEASEversion>
dependency>
dependencies>
project>
注意:Jar包彼此存在依赖,只需引入最外层Jar即可由Maven自动将相关依赖Jar引入到项目中。
Spring常用功能的Jar包依赖关系 |
---|
核心容器由 beans、core、context 和 expression(Spring Expression Language,SpEL)4个模块组成。
/**
* 持久层实现类
*/
public class UserDaoImpl implements UserDao {
@Override
public void addUser(){
System.out.println("insert into tb_user......");
}
}
/**
* 业务层实现类
*/
public class UserServiceImpl implements UserService {
//此处有依赖关系
private UserDao userDao = new UserDaoImpl();
public void addUser(){
userDao.addUser();
}
}
<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="userDao" class="com.by.dao.UserDaoImpl">bean>
<bean id="userService" class="com.by.service.UserServiceImpl">bean>
beans>
注意:命名无限制,约定俗成命名有:spring-context.xml、applicationContext.xml、beans.xml
/**
* 模拟表现层
*/
public class Client {
public static void main(String[] args) {
//1.使用ApplicationContext接口,就是在获取spring容器
ApplicationContext ac = new
ClassPathXmlApplicationContext("applicationContext.xml");
//2.根据bean的id获取对象
UserDao userDao = (UserDao) ac.getBean("userDao");
System.out.println(userDao);
UserService userService = (UserService) ac.getBean("userService");
System.out.println(userService);
userService.addUser();
}
}
概述:DI(Dependency Injection)依赖注入,在Spring创建对象的同时,为其属性赋值,称之为依赖注入。
顾名思义,就是使用类中的构造函数,给成员变量赋值。注意,赋值的操作不是我们自己做的,而是通过配置的方式,让spring框架来为我们注入。具体代码如下:
/**
* 业务层实现类
*/
public class UserServiceImpl implements UserService {
private UserDao userDao;
private String name;
private Integer age;
public UserServiceImpl(UserDao userDao, String name, Integer age) {
this.userDao = userDao;
this.name = name;
this.age = age;
}
public void addUser(){
System.out.println(name+","+age);
userDao.addUser();
}
}
<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="userDao" class="com.by.dao.UserDaoImpl">bean>
<bean id="userService" class="com.by.service.UserServiceImpl">
<constructor-arg name="userDao" ref="userDao">constructor-arg>
<constructor-arg name="name" value="张三">constructor-arg>
<constructor-arg name="age" value="18">constructor-arg>
bean>
beans>
顾名思义,就是在类中提供需要注入成员的set方法。具体代码如下:
/**
* 业务层实现类
*/
public class UserServiceImpl implements UserService {
private UserDao userDao;
private String name;
private Integer age;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void setName(String name) {
this.name = name;
}
public void setAge(Integer age) {
this.age = age;
}
public void addUser(){
System.out.println(name+","+age);
userDao.addUser();
}
}
<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="userDao" class="com.by.dao.UserDaoImpl">bean>
<bean id="userService" class="com.by.service.UserServiceImpl">
<property name="userDao" ref="userDao">property>
<property name="name" value="张三">property>
<property name="age" value="18">property>
bean>
beans>
不用在配置中 指定为哪个属性赋值,由spring自动根据某个 “原则” ,在工厂中查找一个bean并为属性注入值。具体代码如下:
/**
* 业务层实现类
*/
public class UserServiceImpl implements UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void addUser(){
userDao.addUser();
}
}
<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="userDao" class="com.by.dao.UserDaoImpl">bean>
<bean id="userService" class="com.by.service.UserServiceImpl" autowire="byType">
bean>
beans>
<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="userDao" class="com.by.dao.UserDaoImpl">bean>
<bean id="userService" class="com.by.service.UserServiceImpl" autowire="byName">
bean>
beans>
顾名思义,就是给类中的集合成员传值,它用的也是set方法注入的方式,只不过变量的数据类型都是集合。我们这里介绍注入数组,List,Set,Map。具体代码如下:
/**
* 业务层实现类
*/
public class UserServiceImpl implements UserService {
private UserDao userDao;
private String[] myStrs;
private List<String> myList;
private Set<String> mySet;
private Map<String,String> myMap;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void setMyStrs(String[] myStrs) {
this.myStrs = myStrs;
}
public void setMyList(List<String> myList) {
this.myList = myList;
}
public void setMySet(Set<String> mySet) {
this.mySet = mySet;
}
public void setMyMap(Map<String, String> myMap) {
this.myMap = myMap;
}
public void addUser(){
System.out.println(Arrays.toString(myStrs));
System.out.println(myList);
System.out.println(mySet);
System.out.println(myMap);
userDao.addUser();
}
}
<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="userDao" class="com.by.dao.UserDaoImpl">bean>
<bean id="userService" class="com.by.service.UserServiceImpl">
<property name="userDao" ref="userDao">property>
<property name="mySet">
<set>
<value>AAAvalue>
<value>BBBvalue>
<value>CCCvalue>
set>
property>
<property name="myArray">
<array>
<value>AAAvalue>
<value>BBBvalue>
<value>CCCvalue>
array>
property>
<property name="myList">
<list>
<value>AAAvalue>
<value>BBBvalue>
<value>CCCvalue>
list>
property>
<property name="myMap">
<map>
<entry key="testA" value="aaa">entry>
<entry key="testB" value="bbb">entry>
map>
property>
bean>
beans>
ApplicationContext的实现类,如下图:
spring中工厂的类结构图
区别:
ApplicationContext:只要一读取配置文件,默认情况下就会创建对象。
/**
* 业务层实现类
*/
public class UserServiceImpl implements UserService {
private UserDao userDao;
public UserServiceImpl() {
System.out.println("UserServiceImpl对象创建了...");
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void addUser(){
userDao.addUser();
}
}
/**
* 模拟表现层
*/
public class Client {
public static void main(String[] args) {
new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println("Spring IOC容器创建好了");
}
}
BeanFactory:是在 getBean 的时候才会创建对象。
/**
* 业务层实现类
*/
public class UserServiceImpl implements UserService {
private UserDao userDao;
public UserServiceImpl() {
System.out.println("UserServiceImpl对象创建了...");
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void addUser(){
userDao.addUser();
}
}
/**
* 模拟表现层
*/
public class Client {
public static void main(String[] args) {
new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
System.out.println("Spring IOC容器创建好了");
}
}
目前Spring Bean的作用域或者说范围主要有五种:
作用域 | 说明 |
---|---|
singleton | 默认值,Bean以单例方式存在spring IoC容器 |
prototype | 每次从容器中调用Bean时都返回一个新的实例,相当于执行newInstance() |
request | WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 request 域中 |
session | WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 session 域中 |
application | WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 ServletContext 域中 |
可以通过
标签的scope
属性控制bean的作用范围,其配置方式如下所示:
<bean id="..." class="..." scope="singleton"/>
需要根据场景决定对象的单例、多例模式
单例:Service、DAO、SqlSessionFactory(或者是所有的工厂)
多例:Connection、SqlSession
案例
<bean id="userService" class="com.by.service.UserServiceImpl"
scope="singleton" init-method="init" destroy-method="destroy">
/**
* 业务层实现类
*/
public class UserServiceImpl implements UserService {
private UserDao userDao;
public UserServiceImpl() {
System.out.println("调用构造方法创建bean...");
}
public void setUserDao(UserDao userDao) {
System.out.println("调用set方法注入值...");
this.userDao = userDao;
}
public void init(){
System.out.println("调用init方法初始化bean...");
}
public void destroy(){
System.out.println("调用destroy方法销毁bean...");
}
public void addUser(){
userDao.addUser();
}
}
/**
* 模拟表现层
*/
public class Client {
public static void main(String[] args) {
ClassPathXmlApplicationContext ac =
new ClassPathXmlApplicationContext("applicationContext.xml");
//关闭容器
ac.close();
}
}
生命周期:
[容器启动]—>构造方法(实例化)—>set方法(注入)—>init方法(初始化)—>[容器关闭]—>destroy方法(销毁)
案例
<bean id="userService" class="com.by.service.UserServiceImpl"
scope="prototype" init-method="init" destroy-method="destroy">
/**
* 业务层实现类
*/
public class UserServiceImpl implements UserService {
private UserDao userDao;
public UserServiceImpl() {
System.out.println("调用构造方法创建bean...");
}
public void setUserDao(UserDao userDao) {
System.out.println("调用set方法注入值...");
this.userDao = userDao;
}
public void init(){
System.out.println("调用init方法初始化bean...");
}
public void destroy(){
System.out.println("调用destroy方法销毁bean...");
}
public void addUser(){
userDao.addUser();
}
}
/**
* 模拟表现层
*/
public class Client {
public static void main(String[] args) {
ClassPathXmlApplicationContext ac =
new ClassPathXmlApplicationContext("applicationContext.xml");
//使用对象
ac.getBean("userService");
}
}
生命周期:
[使用对象]---->构造方法(实例化)—>set方法(注入)—>init方法(初始化)—>[JVM垃圾回收]—>destroy方法(销毁)