Spring系统架构
Spring Framework是Spring生态圈中最基础的项目,是其他项目的根基。
Spring Framework系统架构

学习线路

核心概念
IoC( Inversion of Control )控制反转
使用对象时,由主动new产生对象转换为由外部提供对象,此过程中对象创建控制权由程序转移到外部,此思想称为控制反转。
Spring技术对Ioc思想进行了实现。
Spring提供了一个容器,称为IoC容器,用来充当IoC思想中的外部。
IoC容器负责对象的创建、初始化等一系列工作,被创建或被管理的对象在IoC容器中统称为Bean
DI ( Dependency Injection )依赖注入
在容器中建立bean与bean之间的依赖关系的整个过程,称为依赖注入
目标:充分解耦
使用IoC容器管理bean (IoC)
 在IoC容器内将有依赖关系的bean进行关系绑定(DI)
最终效果
使用对象时不仅可以直接从Ioc容器中获取,并且获取到的bean已经绑定了所有的依赖关系
IoC
导入Spring坐标
在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>org.example</groupId>
    <artifactId>SpringTest</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <dependency>//这里
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.23</version>
        </dependency>
    </dependencies>
</project>
定义Spring管理的类(接口)
package org.example.service.impl;
import org.example.dao.BookDao;
import org.example.dao.impl.BookDaoImpl;
import org.example.service.BookService;
public class BookServiceImpl implements BookService {
    private BookDao bookDao = new BookDaoImpl();
    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }
}
package org.example.service;
public interface BookService {
    public void save();
}
创建Spring配置文件,配置对应类作为Spring管理的bean
在resources下新建applicationContext.xml文件。
New->XML Configuration File->Spring Config
<?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="bookDao" class="org.example.dao.impl.BookDaoImpl"/>
    <bean id="bookService" class="org.example.service.impl.BookServiceImpl"/>
</beans>
bean定义时id属性在同一个上下文中不能重复
初始化IoC容器( Spring核心容器/Spring容器),通过容器获取bean
package org.example;
import org.example.dao.BookDao;
import org.example.service.BookService;
import org.example.service.impl.BookServiceImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
    public static void main(String[] args) {
		//加载配置文件得到上下文对象,也就是容器对象
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
	    //获取资源
        BookService bookService = (BookService) ctx.getBean("bookService");
        bookService.save();
    }
}
DI
删除使用new的形式创建对象的代码
public class BookServiceImpl implements BookService {
    //private BookDao bookDao = new BookDaoImpl();
    private BookDao bookDao;
    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }
}
提供依赖对象对应的setter方法
public class BookServiceImpl implements BookService {
    //private BookDao bookDao = new BookDaoImpl();
    private BookDao bookDao;
    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }
    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }
}
set方法是容器在执行。
配置service与dao之间的关系
<?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="bookDao" class="org.example.dao.impl.BookDaoImpl"/>
    <!--<bean id="bookService" class="org.example.service.impl.BookServiceImpl"/>-->
    <bean id="bookService" class="org.example.service.impl.BookServiceImpl">
        <!--property标签表示配置当前bean的属性
        name属性表示配置哪一个具体的属性
        ref属性表示参照哪一个bean-->
        <property name="bookDao" ref="bookDao"/>
    </bean>
</beans>
bean
bean基础配置
<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="bookDao" class="org.example.dao.impl.BookDaoImpl"/>
    <bean id="bookService" class="org.example.service.impl.BookServiceImpl"/>
</beans>
bean别名配置
    <bean id="bookDao" name="dao1 bookDaoImpl1" class="org.example.dao.impl.BookDaoImpl" />
    <bean name="service, bookServiceImpl" class="org.example.service.impl.BookServiceImpl" />
获取bean无论是通过id还是name获取,如果无法获取到,将抛出异常NoSuchBeanDefinitionExceptionNoSuchBeanDefinitionException: No bean named ‘bookServiceImpl’ available
bean作用范围
<bean id="bookDao" class="org.example.dao.impl.BookDaoImpl" scope="prototype"/>
通过scope定义bean的作用范围,可选范围如下
 singleton:单例(默认)
 prototype :非单例
bean的实例化
bean的实例化有3种方式。
构造方法(常用)
提供可访问的构造方法
public class BookDaoImpl implements BookDao {
    public BookDaoImpl() {
        System.out.println("book constructor is running ...");
    }
    public void save() {
        System.out.println("book dao save ...");
    }
}
配置
<bean id="bookDao" class="org.example.dao.impl.BookDaoImpl" />
无参构造方法如果不存在,将抛出异常BeanCreationException
静态工厂(了解)
静态工厂
public class OrderDaoFactory {
    public static OrderDao getOrderDao() {
        return new OrderDaoImpl();
    }
}
配置
<bean
      id="orderDao"
      factory-method="getOrderDao"
      class="com.itheima.factory.OrderDaoFactory"
      />
实例工厂(了解)
实例工厂
public class UserDaoFactory {
    public UserDao getUserDao() {
        return new UserDaoImpl();
    }
}
配置
<bean id="userDaoFactory" class="com.itheima.factory.UserDaoFactory" />
<bean
      id="userDao"
      factory-method="getUserDao"
      factory-bean="userDaoFactory"
      />
FactoryBean(实用)
FactoryBean
public class UserDaoFactoryBean implements FactoryBean<UserDao> {
    public UserDao get0bject() throws Exception {
        return new UserDaoImpl();
    }
    public class<?> getobjectType() {
        return UserDao.class;
    }
}
配置
<bean
            id="userDao"
            class="com.itheima.factory.UserDaoFactoryBean"/>
bean生命周期控制
提供生命周期控制方法
public class BookDaoImpl implements BookDao {
    public void save() {
        System.out.println( "book dao save ..." );
    }
    public void init(){
        System.out.println("book init ...");
    }
    public void destory(){
        System.out.println( "book destory ...");
    }
}
配置生命周期控制方法
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl" init-method="init" destroy-method=destory" />
实现InitializingBean,DisposableBean接口(了解)
public class BookServiceImpl implements BookService , InitializingBean, DisposableBean {
    public void save() {
        System.out.println("book service save ...");
    }
    public void afterPropertiesSet() throws Exception {
        System.out.println("afterPropertiesSet");
    }
    public void destroy() throws Exception {
        System.out.println("destroy");
    }
}
生命周期
初始化容器
1.创建对象(内存分配)
2.执行构造方法
3.执行属性注入( set操作)
4.执行bean初始化方法
使用bean
1.执行业务操作
关闭/销毁容器
1.执行bean销毁方法
容器关闭前触发bean的销毁
关闭容器方式
 手工关闭容器
 ConfigurableApplicationContext接口close()操作注册关闭钩子,在虚拟机退出前先关闭容器再退出虚拟机
 ConfigurableApplicationContext接口registerShutdownHook()操作


















