Spring framework and source code (2)---Spring IoC advanced application and source code analysis

Spring IOC application

Section 1 Spring IoC Basics

IOC implementation under Spring framework, several ways to parse beans

Insert image description here

1.1 The difference between BeanFactory and ApplicationContext

BeanFactoryIt is Springthe top-level interface of the IoC container in the framework, it is only used to define some basic functions and define some basic specifications, but it ApplicationContextis a sub-interface of it, soApplicationContextIt has BeanFactoryall the functions provided . Usually, what we BeanFactorycall SpringIOCa basic container ApplicationContextis a high-level interface to the container, which BeanFactoryhas more functions, such as internationalization support and resource access ( xml,java配置类), etc.
Insert image description here

How to start the IoC container
  • Start the IoC container in Java environment

ClassPathXmlApplicationContext: Load the configuration file from the root path of the class (recommended)
FileSystemXmlApplicationContext : Load the configuration file from the disk path
AnnotationConfigApplicationContext : Start the Spring container in pure annotation mode

ClassPathXmlApplicationContext和FileSystemXmlApplicationContext演示

define applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<!--跟标签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
        https://www.springframework.org/schema/beans/spring-beans.xsd
">
    <!--bean
        作用:
            声明类交给spring容器
        属性:
            id: 唯一标识
            class:全路径限定名称
        细节:
            默认使用无参构造函数实例化-->
    <bean id="accountDao" class="com.lagou.edu.dao.impl.JdbcAccountDaoImpl">
        <property name="ConnectionUtils" ref="connectionUtils"/>
    </bean>
    <bean id="transferService" class="com.lagou.edu.service.impl.TransferServiceImpl">
        <!--set+ name 之后锁定到传值的set方法了,通过反射技术可以调用该方法传入对应的值-->
        <property name="AccountDao" ref="accountDao"></property>
    </bean>

    <!--配置新增的三个Bean-->
    <bean id="connectionUtils" class="com.lagou.edu.utils.ConnectionUtils"></bean>

    <!--事务管理器-->
    <bean id="transactionManager" class="com.lagou.edu.utils.TransactionManager">
        <property name="ConnectionUtils" ref="connectionUtils"/>
    </bean>

    <!--代理对象工厂-->
    <bean id="proxyFactory" class="com.lagou.edu.factory.ProxyFactory">
        <property name="TransactionManager" ref="transactionManager"/>
    </bean>
</beans>

    @Test
    public void testIoC() throws Exception {
    
    
        // 通过读取classpath下的xml文件来启动容器(xml模式SE应用下推荐)
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        // 不推荐使用
        //ApplicationContext applicationContext1 = new FileSystemXmlApplicationContext("文件系统的绝对路径");
//        ApplicationContext applicationContext = new FileSystemXmlApplicationContext("F:\\outWork\\00-kaiyuan\\06-spring\\spring\\lagou-transfer-ioc-xml\\src\\main\\resources\\applicationContext.xml");
        AccountDao accountDao = (AccountDao) applicationContext.getBean("accountDao");
        System.out.println("accountDao:" + accountDao);
        applicationContext.close();
    }

Insert image description here
summary

    1、工厂类:ApplicationContext
    2、工厂配置:
        文件类型:xml
        方式:
       <!--bean
        作用:
            声明类交给spring容器
        属性:
            id: 唯一标识
            class:全路径限定名称
        细节:
            默认使用无参构造函数实例化-->
    <bean id="accountDao" class="com.lagou.edu.dao.impl.JdbcAccountDaoImpl">
        <property name="ConnectionUtils" ref="connectionUtils"/>
    </bean>
    3、工厂加载配置:
        ApplicationContext通过ClassPathXmlApplicationContext加载applicationContext.xml配置;
        或者通过FileSystemXmlApplicationContext加载applicationContext.xml配置;
    4、工厂获得bean:
        ApplicationContext使用getBean()方法,用于根据bean的名称获取实例化对象

Start the IoC container in the Web environment (load xml through the listener)

1. Start the container from xml

  • Add dependency
    ContextLoaderListener under spring-web so you need to add dependencies
<!--引入spring web功能-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>5.1.12.RELEASE</version>
    </dependency>
  • Configure web.xml
<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <!--配置Spring ioc容器的配置⽂件-->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
  </context-param>
  <!--使⽤监听器启动Spring的IOC容器-->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
</web-app>

  • Get object
    private TransferService transferService = null;
    //通过webApplicationContext来获取对象实例
    @Override
    public void init() throws ServletException {
    
    
        WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
         transferService = (TransferService) .getBean("transferService");

    }
  • analyze

Insert image description here

2. Start the container from the configuration class

Section 2 Detailed explanation of bean tags [Key points]

1. Function of bean tag

bean作用:  
	用于配置对象让spring 来创建的。 
    【细节】
	默认情况下调用类的无参构造函数。

2. Basic attributes of bean tags

Attributes illustrate
id The unique identifying name of the bean
class The fully qualified name of the implementation class
name Bean name
* Use "," to separate multiple aliases
* Bean and bean alias cannot be repeated
<?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="accountDao" name="accountDao2,accountDao3" class="com.spring.dao.impl.AccountDaoImpl"></bean>

    <bean id="accountService"  class="com.spring.service.impl.AccountServiceImpl"></bean>

</beans>

3. Scope of bean tag

Attributes illustrate
scope Specifies the scope of the object.
* singleton[Default]: Single instance, all requests are processed with one object
* prototype: Multiple instances, each request is processed with a new object
* request: In WEB project, the object is stored in the request field.
* session: WEB In the project, the object is stored in the session domain.
* global session: In the WEB project, it is applied in a cluster environment. If there is no cluster environment, it is equivalent to session

global session diagram

Insert image description here

【1】Thinking
单例、多例他们分别在什么场景中使用?他们有什么区别?
spring默认单例,不需要修改,不要随意定义成员变量。
多例:资源共用
【2】Goal
1、掌握scope的单例、多例的配置
2、掌握单例和多例的区别
【3】Bean scope instance (6)
步骤:
	1、改造ClientController多次获得对象
	2、装配bean到spring的IOC容器中,修改bean标签中scope的作用域
	3、观察不同作用域下获得的对象内存地址是否一致
【3.1】Create project

ClientController


/**
 * @Description:测试
 */
public class ClientController {
    
    
	

    @Test
    public void saveAccount() {
    
    

        /**
         * Spring-IOC容器:ApplicationContext
         * 构建方式:通过ClassPathXmlApplicationContext加载配置文件
         * 使用bean:getBean
         */
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
        AccountDao accountDaoA = (AccountDao) applicationContext.getBean("accountDao");
        AccountDao accountDaoB = (AccountDao) applicationContext.getBean("accountDao");

        System.out.println("accountDaoA的内存地址:"+accountDaoA.hashCode());
        System.out.println("accountDaoB的内存地址:"+accountDaoB.hashCode());

    }

}


【3.2】Bean【Default: singleton】

Use bean tags to assemble accountDao's scope="singleton" in bean.xml

<?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="accountDao" class="com.spring.dao.impl.AccountDaoImpl" scope="singleton"></bean>

    <!--创建accountServic-->
    <bean id="accountServic" class="com.spring.service.impl.AccountServicImpl"></bean>
</beans>
【3.3】singleton operation results

Insert image description here

[3.4] bean [multiple examples: prototype]

Use the bean tag to assemble accountDao's scope="prototype" in bean.xml

<?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="accountDao" class="com.spring.dao.impl.AccountDaoImpl" scope="prototype"></bean>

    <!--创建accountServic-->
    <bean id="accountServic" class="com.spring.service.impl.AccountServicImpl"></bean>
</beans>
【3.5】Prototype running results

Insert image description here

【4】Summary of bean scope
1、单例和多里创建方式、内存地址
	【singleton单例】:所有请求只创建一个对象,内存地址相同
	【prototype多例】:每次请求都创建新的对象,内存地址不同
2、为什么使用单例?
	节省内存、CPU的开销,加快对象访问速度
3、为什么使用多例?
	如果你给controller中定义很多的属性,那么单例肯定会出现竞争访问,不要在controller层中定义成员变量(dao、service注入的bean)
	当web层的对象是有状态的时候 使用多例,防止并发情况下的互相干扰
4、单例、多例的场景
	单例===》spring中的Dao,Service,controller都是单例的
	多例====》struts2的Action是多实例

4. Bean tag life cycle

sevlet life cycle review

1.被创建:执行init方法,只执行一次

  --默认情况下,第一次被访问时,Servlet被创建,然后执行init方法;

  --可以配置执行Servlet的创建时机;

2.提供服务:执行service的doGet、doPost方法,执行多次

3.被销毁:当Servlet服务器正常关闭时,执行destroy方法,只执行一次

The life cycle of beans in different scopes in spring-IOC

Scope life cycle
Singleton scope="singleton" The object is only created once for all requests Birth: The application loads, the container is created, and the object is created
. Alive: As long as the container exists, the object remains alive.
Death: The application is uninstalled, the container is destroyed, and the object is destroyed.
Multiple scope=“prototype” Create object on every request Birth: The application is loaded, the container is created, and the object is created using it.
Alive: As long as the container is there, the object is always alive.
Death: The object has not been used for a long time and is collected by the garbage collector.

Life cycle methods related

name illustrate
init-method Specify the name of the initialization method in the class
destroy-method Specify the name of the destruction method in the class
【1】Goal
1、掌握bean的生命周期配置方式
2、单例和多例下bean的生命周期的区别。
【2】Bean life cycle instance
步骤:
	1、创建LifecycBeanServic类
	2、装配LifecycBeanServic
	3、创建测试类
	4、观察默认单例下生命周期
	5、观察多例下生命周期
【2.1】Create project

/**
 * @Description:生命周期测试服务
 */
public class LifecycleService {
    
    

    public LifecycleService() {
    
    
        System.out.println("LifecycleService构造");
    }

    public void init(){
    
    
        System.out.println("LifecycleService初始化");
    }

    public void doJob(){
    
    
        System.out.println("LifecycleService工作中");
    }

    public void destroy(){
    
    
        System.out.println("LifecycleService销毁");
    }
}

【2.3】Assembling LifecycleBean

Wire the bean and set up the singleton:

<?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="lifecycBeanServic" class="com.spring.service.LifecycBeanServic"
          scope="singleton" init-method="init" destroy-method="destory"></bean>
</beans>
【2.4】Create ClientController

/**
 * @Description:客户端
 */
public class ClientContrller {
    
    

    /**
     * ApplicationContext:spring-IOC容器
     * ClassPathXmlApplicationContext:容器实现类,加载配置文件
     * applicationContext.getBean:获得容器中的bean对象
     */
    @Test
    public void createAccount(){
    
    
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
        System.out.println("applicationContext初始化完成");
        LifecycleService lifecycleService = applicationContext.getBean("lifecycleService", LifecycleService.class);
        lifecycleService.doJob();
        System.out.println("applicationContext容器关闭");
        ((ClassPathXmlApplicationContext) applicationContext).close();

    }
}

【2.5】Life cycle in singleton mode:
【2.6】Life cycle in multiple instance mode

Modify the single instance in the configuration file to multiple instances

<?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="lifecycBeanServic" class="com.spring.service.LifecycBeanServic"
          scope="prototype"  init-method="init" destroy-method="destory"></bean>
</beans>

Executing the method again found that LifecycleBean was lazily loaded, and only the initialization method -init was executed, and the destruction method, destroy, was not executed.

【3】Summary of bean life cycle
单例对象:scope="singleton"
	一个应用只有一个对象的实例。它的作用范围就是整个应用。
	生命周期:
		对象出生:当应用加载,创建容器时,对象就被创建了。
		对象活着:只要容器在,对象一直活着。
		对象死亡:当应用卸载,销毁容器时,对象就被销毁了。

多例对象:scope="prototype"
	每次访问对象时,都会重新创建对象实例。
	生命周期:
		对象出生:当使用对象时,创建新的对象实例(getBean)。
		对象活着:只要对象在使用中,就一直活着。
		对象死亡:当对象长时间不用时,被垃圾回收器回收。
生命周期方法:
init-method:指定类中的初始化方法名称 
destroy-method:指定类中销毁方法名称

5.Bean instantiation method

There are three ways to instantiate beans:

  • bean default constructor creation
  • Static factory method creation
  • Instantiate factory method creation

Default constructor mode [Key points]

Configuration method
    <!--bean
        作用:
            声明类交给spring容器
        属性:
            id: 唯一标识
            class:全路径限定名称
        细节:
            默认使用无参构造函数实例化-->
    <bean id="connectionUtils" class="com.lagou.edu.utils.ConnectionUtils"></bean>
Precautions
缺省构造函数实例化Bean的方式是Spring中默认的实例化方式;
被实例化的Bean中必须有无参构造;
Static factory method approach
Configuration method
  <!--另外两种方式是为了我们自己new的对象加入到SpringIOC容器管理-->
    <!--方式二:静态方法-->
    <bean id="connectionUtils" class="com.lagou.edu.factory.CreateBeanFactory" factory-method="getInstanceStatic"/>
Create a static factory
public class CreateBeanFactory {
    
    
    public static ConnectionUtils getInstanceStatic() {
    
    
        return new ConnectionUtils();
    }
}
Instance factory method
Configuration method
<!--实例化工厂实例化-->
<bean id="instanceFactory" class="com.spring.factory.InstanceFactory"></bean>
<bean id="accountInstance" factory-bean="instanceFactory" factory-method="createAccount"></bean>
Create instance factory
/**
 * @Description:实例化工厂
 */
public class InstanceFactory {
    
    

    public Account createAccount(){
    
    
        System.out.println("实例工厂构建!");
        return  new Account();
    }
    
    public User createUser(){
    
    
        System.out.println("实例工厂构建!");
        return  new User();
    }
}

Summary of bean instantiation
【缺省构造函数方式】
	说明:
		在默认情况下会根据默认缺省构造函数来创建类对象。如果bean中没有默认无参构造函数,将会创建失败。
	场景:
		当各个bean的业务逻辑相互比较独立时,或者与外界关联较少时可以使用

【静态工厂方法方式】
	说明:
        使用工厂中的静态方法创建对象,并装配到 spring的IOC 容器中。
        id 属性:指定 bean 的 id,用于从容器中获取   
        class 属性:指定静态工厂的全限定类名   
        factory-method 属性:指定生产对象的静态方法
	场景:
		统一管理各个bean的创建
		各个bean在创建之前需要相同的初始化处理,则可用静态factory方法进行统一的处理

【实例工厂方法方式】
	说明
        使用工厂中的实例方法创建对象,并装配到容器中。
            1、先把实例工厂做为一个bean装配到 spring容器中。   
            2、然后再引用工厂bean 来调用里面的非静态方法来获取bean并装配到spring的IOC容器中。   
            factory-bean 属性:用于指定实例工厂 bean 的 id。   
            factory-method 属性:用于指定实例工厂中创建对象的方法
	场景:
		1.实例factory方法也作为业务bean控制,可以用于集成其他框架的bean创建管理方法,
		2.能够使bean和factory的角色互换

Section 2 Spring IOC Advanced Features

In-depth analysis of Spring IOC source code

Guess you like

Origin blog.csdn.net/weixin_43811057/article/details/129649199