IOC学习笔记

Spring框架课程安排:

是非常重要的一个框架,开发中几乎是百分之百会用到的

第一天:Spring的IOC(xml方式)

第二天:Spring注解开发+JdbcTemplate+单元测试和动态代理回顾

第三天:Spring中的AOP(xml方式和注解方式实现)

框架学习要求

按照使用步骤实现功能: 将框架跑通
在实现功能的基础上
    描述执行流程: 口述
    描述加载和执行原理: 口述

1.Spring的概述

1.1 Spring是什么?

Spring是分层的JavaSE/EE应用full-stack(全栈)轻量级开源框架;

1590631495077

①Spring框架是J2EE企业级应用的轻量级开源框架,提供了表现层springmvc和持久springJDBC(JDBCTemplate),以及业务层的事务管理等企业级应用解决方案;

②Spring还能将开源世界中众多优秀的第三方框架进行集成(比如mybatis,junit,aspectj等),成为了越来越受欢迎的J2EE企业级应用框架;

③Spring是以IOC(Inversion Of Control)控制反转AOP(Aspect Oriented Programming)面向切面编程为核心;

1.2 Spring体系

1590631552693

源码下载地址: https://repo.springsource.org/libs-release-local/org/springframework/spring/

2.优质程序代码的书写原则

2.1 耦合与内聚

  • 耦合(Coupling):代码书写过程中所使用技术的结合紧密度(程序之间的依赖程度),用于衡量软件中各个模块之间的互联程度;
  • 内聚(Cohesion):代码书写过程中单个模块内部各组成部分间的联系,用于衡量软件中各个功能模块内部的功能联系;
  • 程序书写的目标:高内聚,低耦合
    • 就是同一个模块内的各个元素之间要高度紧密,但是各个模块之间的相互依存度却不要那么紧密

2.2 耦合和内聚代码示例

//内聚:一个方法只做一件事情(一个类只聚合一个业务属性集)
  	//反例: 此方法不符合高内聚思想
  	public int compute(int i,int j,String label){
  		if("+".equals(label)){
           return i+j;
        }else if("-".equals(label)){
           return i-j;
        }else{
            //do something....
        }  
	}

	//例子:
	public int add(int i,int j){
      return i+j;
    }
	public int sub(int i,int j){
      return i-j;
    }

//耦合:程序代码之间的依赖关系
   public class UserService(){
       public List<User> getAllUser(){
          /**
           * getAllUser方法的执行需要依赖UserDao类,
           * 我们称,getAllUser方法与UserDao类之间有耦合
           **/
            UserDao userDao=new UserDao();
            return userDao.findAll();
       }
    } 
   public class UserDao(){
      	 public List<User> findAll(){ 
             //do something and return list
       }
    } 

​ 耦合: 程序代码之间的依赖关系
​ 低耦合: 降低程序代码之间的依赖关系,从而方便维护扩展和重用
​ 解耦合: 在java程序代码中,耦合是不可能完全解开的,我们所说的"解耦合"指的是解开程序编译期的耦合

2.3 耦合的弊端

​ 维护成本高

​ 独立性差

​ 可重用性不高

2.4 如何实现解耦?

①原始方案:服务层与持久层存在紧耦合;

1590636616069

②加入工厂模式后,服务层与持久层完成解耦,但是工厂类与持久层存在紧耦合;

1590636644096

③通过工厂模式和静态资源配置将代码的耦合降到最低;

1590636661026

最终方案:工厂+配置文件解耦

示例代码:
#### bean多实例-工厂类代码
package com.itheima.factory;

import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.ResourceBundle;

/**
 * bean工厂: 专门用于创建Bean对象(java对象)
 */
public class BeanFactory {

    // 用于存放解析到的全限定名
    private static Map<String,String> urlMap = new HashMap<>();
    static {
        // 1.解析配置文件,获取配置文件中配置的全限定名
        // ResourceBundle: jdk提供的工具,专门用于解析properties配置文件
        ResourceBundle bundle = ResourceBundle.getBundle("beans");
        // 获取properties配置文件中所有的key
        Enumeration<String> keys = bundle.getKeys();
        while (keys.hasMoreElements()){
            // 获取下一个key
            String key = keys.nextElement();
            // 根据key获取对应的全限定名
            String value = bundle.getString(key);
            // 存放到map集合中
            urlMap.put(key,value);
        }
        // 测试是否解析到了数据
        for (String key:urlMap.keySet()){
            System.out.println(key+" : "+urlMap.get(key));
        }
    }

    // 反射创建类对象
    public static Object getBean(String id) {
        try {
            // 根据id获取对应的类的全限定名
            String className = urlMap.get(id);
            // 反射创建类对象
            Object obj = Class.forName(className).newInstance();
            return obj;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

bean单实例-工厂代码

package com.itheima.factory;

import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.ResourceBundle;

/**
 * bean工厂: 专门用于创建Bean对象(java对象)
 */
public class BeanFactory1 {

    // 用于存放创建的bean对象(容器)
    private static Map<String,Object> beansMap = new HashMap<>();
    // 用于存放解析到的全限定名
    private static Map<String,String> urlMap = new HashMap<>();
    static {
        // 1.解析配置文件,获取配置文件中配置的全限定名
        // ResourceBundle: jdk提供的工具,专门用于解析properties配置文件
        ResourceBundle bundle = ResourceBundle.getBundle("beans");
        // 获取properties配置文件中所有的key
        Enumeration<String> keys = bundle.getKeys();
        while (keys.hasMoreElements()){
            // 获取下一个key
            String key = keys.nextElement();
            // 根据key获取对应的全限定名
            String value = bundle.getString(key);
            // 存放到map集合中
            urlMap.put(key,value);
        }
        // 测试是否解析到了数据
        for (String key:urlMap.keySet()){
            System.out.println(key+" : "+urlMap.get(key));
        }
    }


    // 反射创建类对象
    public static Object getBean(String id) {
        try {
            // 先从bean容器中获取对象
            Object obj = beansMap.get(id);
            if(obj==null){
                // 根据id获取对应的类的全限定名
                String className = urlMap.get(id);
                // 反射创建类对象
                obj = Class.forName(className).newInstance();
                // 将创建好的bean对象存放到beansMap容器中
                beansMap.put(id,obj);
            }
            return obj;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

立即加载的方式创建

package com.itheima.factory;

import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.ResourceBundle;

/**
 * bean工厂: 专门用于创建Bean对象(java对象)
 */
public class BeanFactory2 {

    // 用于存放创建的bean对象(容器)
    private static Map<String,Object> beansMap = new HashMap<>();
    // 用于存放解析到的全限定名
    private static Map<String,String> urlMap = new HashMap<>();
    static {

        try {
            // 1.解析配置文件,获取配置文件中配置的全限定名
            // ResourceBundle: jdk提供的工具,专门用于解析properties配置文件
            ResourceBundle bundle = ResourceBundle.getBundle("beans");
            // 获取properties配置文件中所有的key
            Enumeration<String> keys = bundle.getKeys();
            while (keys.hasMoreElements()){
                // 获取下一个key
                String key = keys.nextElement();
                // 根据key获取对应的全限定名
                String value = bundle.getString(key);
                // 存放到map集合中
                urlMap.put(key,value);
                // 立即加载的思想创建bean对象
                Object obj = Class.forName(value).newInstance();
                // 将创建好的对象存放到beansMap容器中
                beansMap.put(key,obj);
            }
            // 测试是否解析到了数据
            // for (String key:urlMap.keySet()){
            //     System.out.println(key+" : "+urlMap.get(key));
            // }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    // 反射创建类对象
    public static Object getBean(String id) {
        try {
            // 先从bean容器中获取对象
            Object obj = beansMap.get(id);
            if(obj==null){
                // 根据id获取对应的类的全限定名
                String className = urlMap.get(id);
                // 反射创建类对象
                obj = Class.forName(className).newInstance();
                // 将创建好的bean对象存放到beansMap容器中
                beansMap.put(id,obj);
            }
            return obj;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

配置文件

# 格式:key=value
# key: 自定义,一般为当前类实现的接口的名称
# value: 当前需要使用的类的全限定名
userDao=com.itheima.dao.impl.UserDaoImpl
userService=com.itheima.service.UserServiceImpl

2.5 Spring发展历程

1590636704098

3.IOC的相关概念

  • IoC(Inversion Of Control)控制反转,Spring反向控制应用程序所需要使用的外部资源;
  • Spring控制的资源全部放置在Spring容器中,该容器称为IoC容器;
  • spring容器中存储的对象称为bean对象;
IOC(inversion of control): 控制反转,反转的是对象的创建权,用于削减程序之间的耦合关系,底层使用反射技术实现
	传统方式创建对象:  new 对象(); (主动创建)
	IOC方式创建对象: 找容器(被动接收),本质上就是一个Map集合

	作用:解耦
		通过标记(标记就是配置文件中的key)找工厂,工厂帮我们创建对应的类对象,并返回给我们使用
		当前类可以选择主动出击(new的方式)创建对象,但是此时耦合度高。
		把主动式改成被动接收,由工厂对象为当前类生产所必须的关联对象,此时降低了两个类的依赖关系。
控制反转:资源创建的权限(比如dao)由应用方(service)转移到工厂去创建(factory,spring容器去创建)   

1576738380977

4.基于XML的IOC环境搭建

1.导入Spring的核心jar包的坐标:
```xml org.springframework spring-context 5.0.2.RELEASE ```
2.创建applicationContext.xml,并导入约束:
```xml
<!-- id: 容器中的唯一标识  class:被创建的类的全限定名(包名+类名) -->
<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"></bean>

xml和properties区别:
二者都可以做配置文件
properties更容易解析
Spring之所以使用xml作为配置文件,是因为:
xml结构清晰,嵌套关系明确,一目了然
xml可以通过嵌套关系描述更多的事情.



<div style="background-color:orange">3.获取IOC容器:</div>
```java
a.从类路径下解析xml配置文件,获取容器
// 将配置文件中放在resources
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
b.从磁盘路径下解析xml配置文件
// 将配置文件方法磁盘目录下
ApplicationContext ac = new FileSystemXmlApplicationContext("C:\Users\Administrator.DESKTOP-NG3ICNP\Desktop\applicationContext.xml");
4.测试类代码:
```java package com.itheima.web;

import com.itheima.service.AccountService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

public class WebClient {
@Test
public void test01(){
// ClassPathXmlApplicationContext: 读取类路径下的xml文件
// 类路径: 指的就是resources目录
//1.调用Spring的API,解析配置文件让Spring创建IOC容器
ApplicationContext ac =
new ClassPathXmlApplicationContext("applicationContext.xml");
//2.调用应用上下文对象的API,从IOC容器中获取类对象
//AccountService service = (AccountService) ac.getBean("AccountService");
AccountService service = ac.getBean("AccountService", AccountService.class);
service.add();
}

@Test
public void test02(){
    // FileSystemXmlApplicationContext: 解析系统路径下的xml文件
    //1.调用Spring的API,解析配置文件让Spring创建IOC容器
    ApplicationContext ac =
            new FileSystemXmlApplicationContext("C:\\Users\\Administrator.DESKTOP-NG3ICNP\\Desktop\\applicationContext.xml");
    //2.调用应用上下文对象的API,从IOC容器中获取类对象
    //AccountService service = (AccountService) ac.getBean("AccountService");
    AccountService service = ac.getBean("AccountService", AccountService.class);
    service.add();
}

}




## 5.Spring中IOC容器(API)

### 5.1 bean工厂的结构

ApplicationContext: 应用上下文 接口

```java
ApplicationContext: 当解析完applicationContext.xml文件后,立即创建类对象(饿汉加载模式)
	它是一个接口。是spring中的IOC容器接口,可以通过该接口的方法来获取想要的bean对象。需要提供bean的id。
    它有3个常用的实现类
     	ClassPathXmlApplicationContext★:
					它是用于读取类路径(resources)下的xml配置文件,不在类路径下读取不到
     	FileSystemXmlApplicationContext:
					它是读取文件系统中的配置文件,只要有访问权限,在文件系统中都能读取的到
     	AnnotationConfigApplicationContext:
					它是用于根据注解配置 创建容器的。
            
(★★)ApplicationContext它是在一读取完配置文件,就马上创建配置文件中所配置的所有对象。(得到IOC容器)
    
在IDEA中查看类的继承体系:ctrl + alt + U

image-20210520113350110

BeanFactory: 接口

BeanFactory:
     它是spring中ioc容器的顶层接口,ApplicationContext只是它的子接口。
     它提供创建容器中对象的时机,使用延迟加载(懒加载)的思想。而ApplicationContext不仅继承了它的加载方式,而且还扩展出来了立即加载思想的创建容器的方式。
     它是每次在使用时才真正的创建对象。
延迟加载: BeanFactory
		/**
     * BeanFactory顶层接口延迟加载思想演示
     */
    @Test
    public void test03(){
        ClassPathResource resource = new ClassPathResource("applicationContext.xml");
        BeanFactory beanFactory = new XmlBeanFactory(resource);
        AccountService service = (AccountService)beanFactory.getBean("AccountService");
        System.out.println(service);
        service.add();
    }

BeanFactory与ApplicationContext接口的区别?
1.父子关系:ApplicationContext是BeanFactory的一个子接口;
2.bean的加载时机:ApplicationContext立即加载,也就是说容器一初始化,就创建bean对象
				BeanFactory:延迟加载,当调用getBean方法时,才会加载;

IDEA中查看类的层级结构,快捷方式: ctrl + alt + U

1576721082767

1.什么是IOC?
ioc:控制翻转,创建对象的职责有程序本身交给spring取创建;
2.spring核心思想?
工厂模式+xml配置文件+反射
---》解耦
3.耦合和内聚
耦合:表示软件中【模块与模块】之间的联系程度,编程过程中我们希望耦合越低越好;--》男女朋友关系
内聚:表示软件中各个模块内部的聚合程度;
	方法:一个方法最好只干一件事;
	类:类只维护该类相关的业务;
	功能:功能模块中只解决某个业务功能;
4.开发中代码的原则:高内聚,低耦合;(耦合不能百分百消灭的,但是尽量降低)
5.spring中核心的接口和实现类:
顶级接口:BeanFactory 实现类:XmlBeanFactory  特点:对象延迟加载,只有调用getBean方法时对象初始化
子接口:ApplicationContext: 实现:
			1.ClassPathXmlApplicationContext: 特点:通过类路径加载xml资源
			2.FileSystemXmlApplicationContext: 特点:通过xml在系统中磁盘的真实路径加载资源【了解】
			3.AnnotationConfigApplicationContext: 基于注解开发会使用到;

5.2 创建Bean对象的三种方式

第一种:通过默认构造函数创建
	<bean id="userService" class="com.itheima.service.impl.UserServiceImpl"></bean>
	此种方式通常用于我们自己写的类,在spring中配置。
第二种:通过工厂对象的方法来创建(静态)
	class属性: 指定的是工厂的全限定类名
	factory-method属性:指定的是工厂中用于创建对象的静态方法
	<bean id="userService" class="com.itheima.factory.StaticFactory" factory-method="createBean"></bean>
	此种方法通常用于不是我们自己写的类,而是存在于jar包中已经写好的类。(它都是.class文件)
第三种:通过工厂对象的方法来创建(非静态)
	factory-bean属性:指定的是工厂bean的id.
	factory-method属性:指定的是工厂中用于创建对象的非静态方法
	<bean id="instanceFactory" class="com.itheima.factory.InstanceFactory"></bean>
	<bean id="userService" factory-bean="instanceFactory" factory-method="createBean"></bean>
	此种方式通常用于不是我们自己写的类。
示例代码:
```xml
<!-- 
    将项目中一切可能使用到的对象通通创建出来,并交个Spring的IOC管理
    创建Bean对象的三种方式
        方式1: 无参构造创建对象,存放到IOC容器中
        方式2: 调用工厂的静态方法创建类对象,存放到IOC容器中
        方式3: 调用工厂的非静态方法创建类对象,存放到IOC容器中
 -->
<!-- 方式1: 无参构造创建对象,存放到IOC容器中 -->
<bean id="AccountService1" class="com.itheima.service.impl.AccountServiceImpl"></bean>

<!-- 方式2: 调用工厂的静态方法创建类对象,存放到IOC容器中 -->
<!--
    调用工厂的静态方法,将方法的返回值存放到IOC容器中
       id: 存放到IOC容器时,对象的唯一标识
       class: 工厂的全限定名
       factory-method: 指定静态方法名称
-->
<bean id="AccountService2" class="com.itheima.factory.MethodFactory"
      factory-method="createObject"></bean>
<!-- 方式3: 调用工厂的非静态方法创建类对象,存放到IOC容器中 -->
<!--3.1: 创建工厂类对象,并存放到IOC容器中 -->
<bean id="methodFactory" class="com.itheima.factory.MethodFactory"></bean>
<!--3.2: 调用工厂实例的非静态方法创建类对象 -->
<!--
    调用工厂的非静态方法,将非静态方法的返回值存放到IOC容器中
        id:存放到IOC容器时,对象的唯一标识
        factory-bean:工厂对象实例的引用
        factory-method:调用实例工厂的非静态方法
-->
<bean id="AccountService3" factory-bean="methodFactory" factory-method="createObject1"></bean>
```
package com.itheima.web;

import com.itheima.service.AccountService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * 测试Spring创建类对象的三种方式
 */
public class AccountClient01 {
    // 通过反射调用无参构造创建bean对象
    @Test
    public void test01(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        AccountService service = ac.getBean("AccountService1", AccountService.class);
        System.out.println(service);
    }
    // 获取 工厂的静态方法返回值存放到IOC容器中的对象
    @Test
    public void test02(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        AccountService service = ac.getBean("AccountService2", AccountService.class);
        System.out.println(service);
    }

    @Test
    public void test03(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        AccountService service = ac.getBean("AccountService3", AccountService.class);
        System.out.println(service);
    }
}

5.3 Bean对象的作用范围

bean的作用范围调整:
    调整bean的作用范围,使用的是bean标签的scope属性。
    它的属性取值有以下5个
      singleton           : 单例对象      用的最多的           它是默认值(最常用)
      prototype           :多例对象       用的最多的
      ------------------------------------
      request             :请求范围      (存入了请求域)
      session             :会话范围      (存入了会话域)
      global-session      :全局会话范围   当非集群环境下,它就是session
-------------
如果是有状态的bean选择多例;
如估无无状态的bean选择单例;
示例代码:
```java
<!-- 测试IOC容器中bean的作用范围
        scope: 域,范围
            singleton : 默认值,单实例对象
            prototype : 多实例对象
 -->
<bean id="AccountService1" scope="singleton"
      class="com.itheima.service.impl.AccountServiceImpl2"></bean>

<bean id="AccountService2" scope="prototype"
      class="com.itheima.service.impl.AccountServiceImpl2"></bean>
```
package com.itheima.web;


import com.itheima.service.AccountService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AccountClient2 {

    @Test
    public void test01() {
        ApplicationContext ac =
                new ClassPathXmlApplicationContext("applicationContext2.xml");
        for (int i = 0; i < 10; i++) {
            AccountService service = (AccountService)ac.getBean("AccountService1");
            System.out.println(service);
        }
    }

    @Test
    public void test02() {
        ApplicationContext ac =
                new ClassPathXmlApplicationContext("applicationContext2.xml");
        for (int i = 0; i < 10; i++) {
            AccountService service = (AccountService)ac.getBean("AccountService2");
            System.out.println(service);
        }
    }
}

5.4 Bean对象的生命周期

bean对象的生命周期: 从加载到内存哪一刻起对象就出生了,当对象从内存中移除时,对象的生命就完结了

bean的生命周期:
    单例对象: 将创建的bean放入容器
    	出生:容器创建,对象出生
    	活着:只要容器在,对象就一直活着
    	死亡:容器销毁,对象消亡
    特点: 生命周期与容器相同
	<!--
        单例对象:
            init-method: 初始化方法(构造器初始化对象之后被调用)
            destroy-method: 销毁时调用的方法(对象被销毁之前被调用)
    -->
    <bean id="AccountService" class="com.itheima.service.impl.AccountServiceImpl"
          init-method="init" destroy-method="destory"></bean>

多例对象:
    出生:每次使用时创建
    活着:在使用过程中
    死亡:使用完成之后,等待垃圾回收器回收。gc,也就是说多例模式下spring不负责对象的销毁,不会执行destroy方法;
    	多实例bean对象的生命周期
            scope的值必须为: prototype
示例代码:
```xml
<!-- 测试IOC容器中bean的生命周期:
        单实例:
            创建: 配置文件解析完毕后,会立即创建对象,并存放到IOC容器中
            销毁: IOC容器销毁销毁
        多实例:
            创建: 调用getBean方法时创建.
            销毁: 等待GC回收
 -->
<bean id="AccountService2" scope="prototype"
      init-method="initMethod" destroy-method="destoryMethod"
      class="com.itheima.service.impl.AccountServiceImpl3"></bean>
```
package com.itheima.web;


import com.itheima.service.AccountService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AccountClient3 {

    @Test
    public void test01() {
        ApplicationContext ac =
                new ClassPathXmlApplicationContext("applicationContext3.xml");
        AccountService service = (AccountService)ac.getBean("AccountService1");
        System.out.println(service);
        // 手动关闭上下文对象,当上下文对象关闭时,销毁IOC容器
        ((ClassPathXmlApplicationContext) ac).close();
    }

    @Test
    public void test02() {
        ApplicationContext ac =
                new ClassPathXmlApplicationContext("applicationContext3.xml");
        AccountService service = (AccountService)ac.getBean("AccountService2");
        System.out.println(service);
        ((ClassPathXmlApplicationContext) ac).close();
    }
}

6.Spring中的DI(依赖注入)

6.1 依赖注入概述

依赖注入:Dependency Injection
	通俗来讲: 缺什么给什么(给的对象从IOC容器中获取)
    简单的说,就是在程序运行期,给当前类传入依赖的对象。【缺什么传什么】。
  	例如:
    在创建UserService的bean对象时,该对象中需要依赖UserDao对象,那么就将这些依赖的对象注入当前对象中;

6.2 IOC和DI区别

  • IoC与DI是同一件事站在不同角度看待问题

    ​ 在应用程序的角度看程序需要被动等待Spring提供资源(注入资源)是DI;

    ​ 但是在Spring容器的角度看是,是将资源的创建权利做了翻转,且由容器提供数据,是IOC;

  • 半杯水

1590659854696

半杯水:乐观的人会庆幸还有半杯水,而悲观的人是恼怒只剩半杯水;

6.3 注入数据的方式和类型

Spring中的依赖注入:
    注入的方式有三种:
        第一种:使用构造方法注入
            要求:必须有对应参数列表的构造函数
        第二种:使用setter方法注入(XML开发主流)
            要求:提供被注入对象的set方法(不需要get方法)
        第三种:使用注解注入(第二天会学)

    注入的数据类型有三类:
        第一类:基本类型和String
        第二类:其他bean类型
            要求:其他bean指的是在spring的配置文件中定义过的bean,或者是用注解注释过的类。
        第三类:复杂类型(集合类型)
            Array: 数组
            List:
            Map:
            Properties:
示例代码:
```java 宝强 乃亮 羽凡 大郎 蓉蓉 璐璐 合合 莲莲 昌老师 40
<!-- 创建user对象存放到IOC容器中 -->
<bean id="user" class="com.itheima.pojo.User">
    <property name="username" value="大幂幂"></property>
    <property name="age" value="18"></property>
</bean>
```

测试代码:

package com.itheima.web;

import com.itheima.service.AccountService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * 测试依赖注入
 */
public class AccountClient04_di {

    @Test
    public void test01(){
        ApplicationContext ac =
                new ClassPathXmlApplicationContext("applicationContext_di.xml");
        AccountService service = ac.getBean("AccountService1", AccountService.class);
        System.out.println(service);
        service.add();
    }
}

总结

Spring框架:
		Spring为我们的javaEE企业级应用提供了全方位的解决方案.
    web: 控制层
		SpringMVC
	service: 业务层
      	service层可以使用Spring提供了AOP完成事务的控制
    dao: 持久层
      	Spring提供了JDBCTemplate封装jdbc
Spring的两大核心:
		IOC: 控制反转
				作用: 解耦,解开程序编译期的耦合
        控制反转,反转的是对象的创建权,将对象的创建权交给Spring框架.
        当我们使用对象时,无需自己创建对象,直接找Spring框要获取即可
		AOP: 面向切面编程
      	作用: 方法增强(在不改变源码的基础上实现方法增强)
				AOP底层采用的是动态代理
java中的耦合,如何解耦:
		耦合: 程序代码之间的依赖关系
    解耦合:
		工厂 + 反射 + 配置文件
        配置文件: 存放被需要创建的类的全限定名
        工厂: 解析配置文件,根据配置文件中的配置创建bean对象
          	1.解析配置文件,获取配置文件中配置的类全限定名
          	2.根据配置的全限定名创建对象的bean对象
    思考:
		工厂可以根据配置文件创建bean对象,那么工厂创建的bean对象是单实例还是多实例的?
          	创建单实例:
					将创建的bean对象存放到一个map集合中,我们管这个集合叫做bean对象容器;
			创建多实例:
					工厂创建的多实例对象属于每一个线程,不会往容器中存放;

作业

问答题:
	Spring的两大核心是什么?
        IOC AOP
    简述Spring的IOC?
        控制反转
    简述IOC的作用?
        
    简述解耦的方式?
        
    简述Spring的核心API,并描述其功能?
        
    简述bean对象的多种创建方式?
        
    简述bean对象的作用范围?
        
    简述bean对象的生命周期?
        
    什么是DI?
        
    依赖注入的方式?
        
  	依赖注入的数据类型?	
        
      
代码题:
	实现SpringIOC(上课所敲代码) ★
        bean对象的多种创建方式
        bean对象的生命周期
        依赖注入: 要求注入所有类型

本文作者:Mr_Yan的blog

本文链接:https://www.cnblogs.com/ygq-study/p/16380052.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Mr_Yan的blog  阅读(31)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起