Spring(day01)IOC反转控制入门、控制反转、bean对象的范围和生命周期、依赖注入(注入集合属性)

spring的概述

1. spring 的 开源的轻量级框架
2. spring的两大核心:IOC ,AOP

耦合和解耦

1. 什么是耦合
    模块之间的关联程度, 依赖程度
2. 什么是解耦
    降低模块之间的耦合度(依赖关系)
3. 解耦的目的
    编译器不依赖,运行期才依赖
4. 解耦思路
    1)把全限类名都放到配置文件中
    2)  通过工厂帮助创建对象

当是我们讲解 jdbc 时,是通过反射来注册驱动的,代码如下: Class.forName("com.mysql.jdbc.Driver");//此处只是一个字符串 此时的好处是,我们的类中不再依赖具体的驱动类,此时就算删除 mysql 的驱动 jar 包,依然可以编译(运 行就不要想了,没有驱动不可能运行成功的)。 

 

控制反转-- 自定义IOC

1.接口及接口实现类

2. 配置文件

<beans>
    <!--
        用bean标签配置所有的bean对象
        id: 对象的唯一的标志
        class:类名
    -->
    <bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl2"></bean>
    <bean id="userService" class="com.itheima.service.impl.UserServiceImpl"></bean>
</beans>

3. 创建BeanFactory工厂对象

package com.itheima.factory;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

 /* 创建bean对象的工厂类
 */
public class BeanFactory {
    private static Map<String ,Object> map = new HashMap<>();
    //提前把所有的对象创建出来,存储 //Map  :因为有查找需求 --相当于容器对象-- 包含了所有的对象
    //静态代码块    编译时创建
    //  有些代码需要在项目启动的时候就执行
    //   一个项目启动需要加载的很多配置文件等资源,我们就可以都放入静态代码块中
    static{                       //获取配置文件的输入流对象
        InputStream inputStream = BeanFactory.class.getResourceAsStream("/beans.xml");
        SAXReader reader = new SAXReader();//解析xml获取xml中所有的信息
        try {
            Document doc = reader.read(inputStream);//创建文档对象
            Element root = doc.getRootElement();//获取根节点
            //获取根节点中所有的子节点//element("bean") : 获取第一个叫bean的子节点
            //elements("bean") : 获取所有叫bean的子节点//elements() : 获取所有的子节点
            List<Element> beanList = root.elements("bean");//获取每一个bean的id和class
            for (Element element : beanList) {
                String id = element.attributeValue("id");
                String className = element.attributeValue("class");
                //通过className全限类名创建对象--获取字节码
                Class clazz = Class.forName(className);
                Object obj = clazz.newInstance(); //无参构造一个对象//通过反射创建对象
                //存储在Map集合中  //key: id //value:obj
                map.put(id ,obj);
            }
        } catch (Exception e) { e.printStackTrace(); }
    }//需要实现的功能,传入一个名字,获取一个Bean对象
    public static Object getBean(String name){
        return map.get(name);   // 根据名字取出对象
    }
}

4. 测试

package com.itheima;

import com.itheima.factory.BeanFactory;

public class TestCustomIOC {

    public static void main(String[] args) {
                              //   静态方法   通过类直接调用
        Object userService1 = BeanFactory.getBean("userService");
        System.out.println(userService1);
        Object userService2 = BeanFactory.getBean("userService");
        System.out.println(userService2);

    }
}

5.执行结果

com.itheima.service.impl.UserServiceImpl@2bbf4b8b
com.itheima.service.impl.UserServiceImpl@2bbf4b8b

Process finished with exit code 0

上一小节我们通过使用工厂模式,实现了表现层——业务层以及业务层——持久层的解耦。 它的核心思想就是:  

1、通过读取配置文件反射创建对象。  

2、把创建出来的对象都存起来,当我们下次使用时可以直接从存储的位置获取。

这里面要解释两个问题:  

第一个:存哪去?   分析:由于我们是很多对象,肯定要找个集合来存。这时候有 Map 和 List 供选择。      到底选 Map 还是 List 就看我们有没有查找需求。有查找需求,选 Map。   所以我们的答案就是    在应用加载时,创建一个 Map,用于存放三层对象。    我们把这个 map 称之为容器。  

第二个:什么是工厂?   工厂就是负责给我们从容器中获取指定对象的类。这时候我们获取对象的方式发生了改变。   原来:      我们在获取对象时,都是采用 new 的方式。是主动的。 

明确 ioc(inversion of control)的作用:  削减计算机程序的耦合(解除我们代码中的依赖关系)

以上为自定义IOC,以下为Spring的IOC

============================================================================

Spring的IOC入门(掌握)

1.引入依赖

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.0.2.RELEASE</version>
    </dependency>

2.创建接口和实现类

3. 创建beans.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!--
http://www.springframework.org/schema/beans: 引入bean的名称空间
约束:现在xml的书写
    dtd:mybatis
    schema:spring

http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd 引入约束
-->
<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.itheima.dao.impl.UserDaoImpl"></bean>

    <bean id="userService" class="com.itheima.service.impl.UserServiceImpl"></bean>
</beans>

4. 创建容器对象,根据id获取对象

package com.itheima;

import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

public class TestSpringIOC {

    public static void main(String[] args) {
        //创建spring的IOC容器
        ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
        //获取对象
        Object userDao = ac.getBean("userDao");  // 获取对象
        System.out.println(userDao);


        Object userService = ac.getBean("userService");  //到配置文件获取对象
        System.out.println(userService);

    }
}

根据配置文件中的id取出对应接口对象。

5.执行结果

com.itheima.dao.impl.UserDaoImpl@10d68fcd
com.itheima.service.impl.UserServiceImpl@117e949d

Process finished with exit code 0

IOC的细节

1、容器对象的类结构图

a、beanFactory 是spring容器的顶层接口

b、接口ApplicationContext是 beanFactory子接口
    实现类:ClassPathXmlApplicationContext  -- 从类路径之下读取配置文件 (常用)
                 FileSystemXmlApplicationContext - 从绝对路径指定的配置文件读取
                 AnnotationConfigApplicationContext -- 纯注解配置使用的类 (常用)
c、BeanFactory与ApplicationContext区别

//ApplicationContext:在创建容器时只创建单例模式的对象
//                               多例模式的对象,在获取时创建

2、getBean方法(掌握)   配置文件默认 applicationContext.xml

3、bean对象的范围和生命周期(掌握)

springIOC容器默认的单例模式:  单例模式的对象在创建容器时创建,销毁容器时销毁
scope:prototype 原型模式(多例模式):获取时创建,当对象长时间不在被引用, 则被垃圾回收机制回收
scope:singleton :单例模式 默认
scope :request:  请求范围
scope: session : 回话范围

单例模式在

ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");

就已经创建对象了

ac.close();

的时候销毁。

多例模式需在获取创建,长时间不用时回收销毁。

=======================================================================================

4、实例化bean的三种方法

=====================================================================

1 .<bean id="name" class="全限类名">
    getBean(name)

============================================================================ 

2. 根据静态工厂获取对象
/**
 * 通过静态工厂获取对象
 */
public class StaticFactory {

    public static UserDao getUserDao(){
        return new UserDaoImpl();
    }
}

    <!--通过静态工厂创建UserDao对象-->
    <!--
        factory-method: 工厂方法,返回UserDao对象的方法名
    -->
    <bean id="userDao" class="com.itheima.factory.StaticFactory" factory-method="getUserDao"></bean>

 

 

<!--通过静态工厂创建UserDao对象-->
<!--
    factory-method: 工厂方法,返回UserDao 对象的方法名
-->

==========================================================================================

3. 根据实例(非静态)工厂获取对象
/**
 * 实例工厂创建对象
 */
public class InstanceFactory {
    public UserDao getUserDao(){
        return new UserDaoImpl();
    }
}

 <!--创建实例工厂对象-->
 <bean id="instanceFatory" class="com.itheima.factory.InstanceFactory"></bean>
 <!--通过实例工厂创建UserDao对象-->
 <bean id="userDao2" factory-bean="instanceFatory" factory-method="getUserDao"></bean>
 

 

===============================================================================================

5、依赖注入(掌握)

a.什么是依赖注入
    业务层需要持久层的对象在配置文件中给业务层传入持久层的对象,就是依赖注入
b. ioc
    控制反转包含了依赖注入和依赖查找 

=====================================================================================

A、构造方法注入(掌握)        <constructor-arg>标签       需构造方法

 value属性只能赋值简单类型

ref:  pojo类型,复杂类型, 关联创建好的对象

========================================================================================

B、set方法注入属性(常用)(掌握)     <property>标签       需set方法  比较常用(因为构造方法中有有参构造方法,必须就要有无参构造方法)

==================================================================================

C、p名称空间注入:基于set方法注入--- 了解

a、在头部文件中引入p名称空间


b、使用p名称空间注入属性
    <bean id="user3" class="com.itheima.domain.User"
        p:id="5" p:username="马汉" p:sex="男" p:birthday-ref="birthday" >

   </bean>

=========================================================================================

D、注入集合属性(掌握)

array ,list ,set 结构相同,标签可以混用

<!--map集合properties结构相同,可以通用-->

 

spring第一天
    
 spring介绍
    spring 轻量级框架
    两个核心:IOC 控制反转 包括依赖注入和依赖查找  , 主要作用:降低耦合度
        AOP:面向切面编程
 耦合和解耦
 springIOC的入门
    1)引入依赖
        spring-context-5.0.2.RELEASE.jar
        spring-core-5.0.2.RELEASE.jar
        spring-aop-5.0.2.RELEASE.jar
        spring-beans-5.0.2.RELEASE.jar
        spring-expression-5.0.2.RELEASE.jar
    2) 配置文件:beans.xml    applicationContext.xml
        创建对象 <bean/>
    3) 测试
        创建容器对象
        从容器中获取对象:getBean("id | name")  getBean(Class) , getBean("id | name", Class )
  容器对象的类结构图
    BeanFactory: 
    ApplicationContext:在创建容器时创建单例模式的对象
            多例模式的对象在使用时创建对象
 Bean     
    scope: 
    
  依赖注入
    构造方法 : 按照,索引,名称,类型注入
    set方法注入:  必须提供set方法
        <property name="username" >
    p名称空间注入
        1) 添加p名称空间
        2) p:username=""

  赋值
    value: 赋值简单类型
    ref:赋值pojo类型
  注入集合属性: list ,set ,array
           map properties

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值