JavaEE学习日志(八十七): springIOC入门

JavaEE学习日志持续更新----> 必看!JavaEE学习路线(文章总汇)

Spring

Spring概述

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

解耦和耦合

耦合:模块之间的关联程度, 依赖程度
解耦:降低模块之间的耦合度(依赖关系)
目的编译器不依赖,运行期才依赖

解耦思路:

  • 把全限类名都放到配置文件中
  • 通过工厂帮助创建对象

自定义IOC

创建接口和实现类
在这里插入图片描述

配置文件

<beans>
    <!--
        用bean标签配置所有的bean对象
        id:对象的唯一的标志
        class:全限类名

    -->
    <bean id="UserDao" class="com.itheima.dao.impl.UserDaoImpl"></bean>
    <bean id="UserService" class="com.itheima.service.impl.UserServiceImpl"></bean>
</beans>

单例模式的BeanFactory

package com.itheima.factory;

import org.dom4j.Document;
import org.dom4j.DocumentException;
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 is = BeanFactory.class.getClassLoader().getResourceAsStream("beans.xml");
        //解析xml获取xml中所有信息
        SAXReader reader = new SAXReader();
        try {
            //创建文档对象
            Document doc = reader.read(is);
            //获取根节点
            Element root = doc.getRootElement();
            //获取根节点的所有子节点
            List<Element> beans = root.elements("bean");
            //获取每一个bean的id和class
            for (Element bean : beans) {
                String id = bean.attributeValue("id");
                String className = bean.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);
    }
}

测试类

public static void main(String[] args) {
        Object userService = BeanFactory.getBean("UserService");
        System.out.println(userService);
}

SpringIOC入门

IOC:控制反转,把创建对象的任务交给框架

1、引入依赖

<!--引入spring核心依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>

2、创建beans.xml

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

http://www.springframework.org/schema/beans
        https://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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="UserDao" class="com.itheima.dao.impl.UserDaoImpl"></bean>

</beans>

3、创建容器对象,根据id获取对象

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

容器对象的类结构

  • BeanFactory是spring容器的顶层接口
  • 接口ApplicationContextBeanFactory的子接口
    实现类:
    • ClassPathXmlApplicationContext 从类路径下读取配置文件(常用)
    • FileSystemXmlApplicationContext 从绝对路径读取配置文件
    • AnnotationConfigApplicationContext 纯注解配置使用的类(常用)

BeanFactory创建对象的过程

@Test
    public void test(){
        Resource resource = new ClassPathResource("beans.xml");
        BeanFactory beanFactory = new XmlBeanFactory(resource);
        Object userDao = beanFactory.getBean("userDao");
        System.out.println(userDao);
    }

BeanFactoryApplicationContext的区别

  • BeanFactory:创建容器对象时,只加载了配置文件,没有创建对象
  • ApplicationContext容器:在创建容器对象时,创建对象(常用)

getBean方法

1、根据名称获取该对象

Object userDao = ac.getBean("userDao");

2、根据类型获取对象,如果有两个该类型的实现类,就会出现问题

UserDao userDao = ac.getBean(UserDao.class);

3、得到id为userDao的对象,类型为UserDao接口的实现类

UserDao userDao = ac.getBean("userDao", UserDao.class);

bean对象的生命周期

bean标签的基本属性

  • id
  • class
  • name:和id基本相同
  • scope:
    • prototype 多例模式
    • singleton 默认,单例模式
    • request 请求范围
    • session 会话范围
    • global session 全局范围 spring5中被删除

注意:ApplicationContext在创建容器时,只创建单例模式的对象,多例模式不创建。

bean标签的对象的初始化和销毁属性

  • init-method=“初始化对象的方法”
  • destroy-method=“销毁对象的方法”

注意:

  • 单例模式的对象在创建模式时创建,销毁容器时销毁
  • 多例模式的对象获取时创建;当对象长时间不用时,被垃圾回收机制回收

创建bean对象的三种方式

1、 <bean id="name" class="全限类名">
然后调用方法getBean(name)

2、 根据静态工厂获取对象

创建静态工厂

package com.itheima.factory;

import com.itheima.dao.UserDao;
import com.itheima.dao.impl.UserDaoImpl;

/*
    通过静态工厂获取对象
 */
public class StaticFactory {
    public static UserDao getUserDao(){
        return new UserDaoImpl();
    }
}

配置xml
factory-method:工厂方法,返回UserDao对象的方法名

<bean id="userDao" class="com.itheima.factory.StaticFactory" factory-method="getUserDao"></bean>

测试类

@Test
    public void test2(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        Object userDao = ac.getBean("userDao");
        System.out.println(userDao);
    }

3、 根据实例(非静态)工厂获取对象

创建实例工厂

package com.itheima.factory;

import com.itheima.dao.UserDao;
import com.itheima.dao.impl.UserDaoImpl;

/*
    实例工厂创建对象
 */
public class InstanceFactory {
    public UserDao getUserDao(){
        return new UserDaoImpl();
    }
}

配置xml
factory-bean:创建该对象的实例工厂类

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

测试类

@Test
    public void test2(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        Object userDao = ac.getBean("userDao");
        System.out.println(userDao);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值