草庐IT

Spring核心容器之IOC详解

小钟不想敲代码 2023-04-27 原文

一、Ioc入门案例(XML版)

1、创建Maven工程,导入Spring坐标

 <properties>
        <spring.version>5.2.10.RELEASE</spring.version>
 </properties>
 
  <dependencies>
  		 <!--导入spring的context坐标,context依赖core、beans、expression aop-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!--junit单元测试-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

2、定义Spring管理的类(接口)

package com.liming.service;
public interface UserService {
    public void addUser();
}
package com.liming.service.impl;
import com.liming.service.UserService;
public class UserServiceImpl implements UserService {

    public void addUser() {
        System.out.println("这是在新增用户的service哦");
    }
}

3、创建Spring配置文件,配置对应类作为Spring管理的bean

<?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">
    <!--id值要唯一,用于后期获取指定对象时的标志
    class要创建对象的类,是完全限定名-->
    <bean id="ud" class="com.etime.dao.impl.UserDaoImpl"></bean>
    <bean id="us" class="com.etime.service.impl.UserServiceImpl"></bean>
</beans>

注意:bean定义时id属性在同一个上下文中不能重复

4、初始化 Ioc容器(Spring核心容器),通过容器获取bean

	@Test
    public void test1(){
        //new的方式创建对象调用方法
       /*
        UserService userService = new UserServiceImpl();
        userService.addUser();
       */

        //Ioc方式创建对象调用方法
        //1、加载并获取SpringIOC容器
        ApplicationContext ctx = new ClassPathXmlApplicationContext("application.xml");
        //2、根据id获取对象
        UserService userservice = ctx.getBean("userservice", UserService.class);
        userservice.addUser();
    }

二、Ioc详解

1、IOC配置文件详解

  • bean标签: 用于配置对象交给Spring 来创建。

默认情况下他会调用类中无参数的构造器,如果没有无参数构造器则不能成功创建

  • 基本属性:

    • id : Bean实例对象在Spring容器当中的唯一标识

    • class: Bean 的全限定类名(全类名)

2、创建容器

  • 方式一:类路径加载配置文件
ApplicationContext ctx = new ClassPathXmlApplicationContext("application.xml");
  • 方式二:文件路径加载配置文件(绝对路径)
ApplicationContext ctx = new FileSystemXmlApplicationContext("D:\\JavaSSM305\\day01_Spring\\src\\main\\resources\\application.xml");
  • 方式三:使用注解方式时,创建容器方式
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
  • 加载多个配置文件
ApplicationContext ctx = new ClassPathXmlApplicationContext("application1.xml","application2.xml");

3、获取bean

  • 方式一:使用bean名称获取
UserDao userdao = (UserDao) ctx.getBean("userdao");
  • 方式二:使用bean名称获取并指定类型
UserDao userdao = ctx.getBean("userdao", UserDao.class);
  • 方式三:使用bean类型获取
UserDao userdao = ctx.getBean(UserDao.class);

4、容器类层次结构图

  • BeanFactory :是Ioc容器的顶层接口,不提供开发人员使用,加载配置文件初始化BeanFactory对象时,不会创建对象,在获得(使用)对象时才采取创建对象。(延迟加载)
  • ApplicationContext: BeanFactory接口的子接口(Spring容器的核心接口),提供更多强大的功能,一般由开发人员使用。初始化时bean立即加载
  • ApplicationContext接口常用初始化类:
    -ClassPathXmlApplicationContext
    -AnnotationConfigApplicationContext

三、手动实现自己的IOC容器

Ⅰ、分析IOC 实现思路

Ⅱ、构建maven工程,引入依赖

	<properties>
        <spring.version>5.2.10.RELEASE</spring.version>
    </properties>
    
    <dependencies>
        <!--导入spring的context坐标-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!--导入junit单元测试-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <!--引入dom4J-->
        <dependency>
            <groupId>dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>1.6.1</version>
        </dependency>
    </dependencies>

Ⅲ、设计接口

//dao层接口
public interface UserDao {
    public abstract void addUser();
}

//dao层实现类
public class UserDaoImpl implements UserDao {
    @Override
    public void addUser() {
        System.out.println("这是在新增用户的dao哦");
    }
}
//service层接口
public interface UserService {
    public abstract void addUser();
}

//service层接口实现类
public class UserServiceImpl implements UserService {
    @Override
    public void addUser() {
        System.out.println("这是在新增用户的service哦");
    }
}

Ⅳ、在resources中创建myapplication.xml核心配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!--标签名自定义(随意)-->
<objects>
    <object id="userDao" name="com.etime.dao.impl.UserDaoImpl"></object>
    <object id="userService" name="com.etime.service.impl.UserServiceImpl"></object>
</objects>

Ⅴ、使用dom4j技术解析xml配置文件

package com.liming.util;

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

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

public class MyFactory {
    private static Map<String,Object> map = new HashMap<>();

    static {
        try {
            //1、创建一个Dom4j的解析器对象,代表了整个dom4j框架
            SAXReader reader = new SAXReader();
            //2、把XML文件加载到内存中成为一个Document文档对象
            Document  document = reader.read("src/main/resources/myapplication.xml");
            //3、获取根元素对象
            Element root = document.getRootElement();
            //4、获取根元素的所有子元素
            List<Element> elements = root.elements();
            //5、获取每一个元素的指定属性值
            for (Element element : elements) {
                String name = element.attributeValue("name");
                String id = element.attributeValue("id");
                //根据获取的name属性的值,创建对象
                Class clazz = Class.forName(name);
                //newInstance()调用无参构造创建类对象
                Object obj = clazz.newInstance();
                //根据id添加对象到集合
                map.put(id,obj);
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    //对外提供获取对象方法
    public static Object getBean(String id){
        return map.get(id);
    }
}

Ⅵ、编写测试文件,展示测试结果

 	@Test
    public void test2(){
        UserDao userdao = (UserDao) MyFactory.getBean("userdao");
        userdao.addUser();
        UserService userservice = (UserService) MyFactory.getBean("userservice");
        userservice.addUser();
    }

有关Spring核心容器之IOC详解的更多相关文章

  1. ruby-on-rails - 带 Spring 锁的 Rails 4 控制台 - 2

    我正在使用Ruby2.1.1和Rails4.1.0.rc1。当执行railsc时,它被锁定了。使用Ctrl-C停止,我得到以下错误日志:~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`gets':Interruptfrom~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`verify_server_version'from~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.

  2. spring.profiles.active和spring.profiles.include的使用及区别说明 - 2

    转自:spring.profiles.active和spring.profiles.include的使用及区别说明下文笔者讲述spring.profiles.active和spring.profiles.include的区别简介说明,如下所示我们都知道,在日常开发中,开发|测试|生产环境都拥有不同的配置信息如:jdbc地址、ip、端口等此时为了避免每次都修改全部信息,我们则可以采用以上的属性处理此类异常spring.profiles.active属性例:配置文件,可使用以下方式定义application-${profile}.properties开发环境配置文件:application-dev

  3. ruby-on-rails - Spring 不起作用。 [未初始化常量 Spring::SID::DL] - 2

    我无法运行Spring。这是错误日志。myid-no-MacBook-Pro:myid$spring/Users/myid/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/spring-0.0.10/lib/spring/sid.rb:17:in`fiddle_func':uninitializedconstantSpring::SID::DL(NameError)from/Users/myid/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/spring-0.0.10/li

  4. 物联网MQTT协议详解 - 2

    一、什么是MQTT协议MessageQueuingTelemetryTransport:消息队列遥测传输协议。是一种基于客户端-服务端的发布/订阅模式。与HTTP一样,基于TCP/IP协议之上的通讯协议,提供有序、无损、双向连接,由IBM(蓝色巨人)发布。原理:(1)MQTT协议身份和消息格式有三种身份:发布者(Publish)、代理(Broker)(服务器)、订阅者(Subscribe)。其中,消息的发布者和订阅者都是客户端,消息代理是服务器,消息发布者可以同时是订阅者。MQTT传输的消息分为:主题(Topic)和负载(payload)两部分Topic,可以理解为消息的类型,订阅者订阅(Su

  5. Tcl脚本入门笔记详解(一) - 2

    TCL脚本语言简介•TCL(ToolCommandLanguage)是一种解释执行的脚本语言(ScriptingLanguage),它提供了通用的编程能力:支持变量、过程和控制结构;同时TCL还拥有一个功能强大的固有的核心命令集。TCL经常被用于快速原型开发,脚本编程,GUI和测试等方面。•实际上包含了两个部分:一个语言和一个库。首先,Tcl是一种简单的脚本语言,主要使用于发布命令给一些互交程序如文本编辑器、调试器和shell。由于TCL的解释器是用C\C++语言的过程库实现的,因此在某种意义上我们又可以把TCL看作C库,这个库中有丰富的用于扩展TCL命令的C\C++过程和函数,所以,Tcl是

  6. 【云原生】SpringCloud-Spring Boot Starter使用测试 - 2

    目录SpringBootStarter是什么?以前传统的做法使用SpringBootStarter之后starter的理念:starter的实现: 创建SpringBootStarter步骤在idea新建一个starter项目、直接执行下一步即可生成项目。 在xml中加入如下配置文件:创建proterties类来保存配置信息创建业务类:创建AutoConfiguration测试如下:SpringBootStarter是什么? SpringBootStarter是在SpringBoot组件中被提出来的一种概念、简化了很多烦琐的配置、通过引入各种SpringBootStarter包可以快速搭建出一

  7. ruby - 如何让 ruby​​-prof 忽略 Ruby 核心/标准库/gem 方法? - 2

    我是Ruby分析的新手,看起来像ruby-prof是一个受欢迎的选择。我刚刚安装了gem并调用了我的程序:ruby-prof./my-prog.rb但是,输出非常冗长,因为包含所有Ruby核心和标准库方法以及其他gem的分析数据。例如,前三行是:8.790.0110.0100.0000.0013343*String#%7.280.0780.0090.0000.0692068*Array#each4.930.0380.0060.0000.0321098*Array#map这对我来说不是什么有用的信息,因为我已经知道我的程序经常处理字符串和数组,并且大概已经对这些类进行了优化。我只关心我代

  8. 【详解】Docker安装Elasticsearch7.16.1集群 - 2

    开门见山|拉取镜像dockerpullelasticsearch:7.16.1|配置存放的目录#存放配置文件的文件夹mkdir-p/opt/docker/elasticsearch/node-1/config#存放数据的文件夹mkdir-p/opt/docker/elasticsearch/node-1/data#存放运行日志的文件夹mkdir-p/opt/docker/elasticsearch/node-1/log#存放IK分词插件的文件夹mkdir-p/opt/docker/elasticsearch/node-1/plugins若你使用了moba,直接右键新建即可如上图所示依次类推创建

  9. Spring Boot集成ElasticSearach - 2

    文章目录前言一、Elasticsearch版本介绍二、客户端种类三、客户端与版本兼容性四、引入Elasticsearch依赖包五、客户端配置六、Elasticsearch使用前言ElasticSearch是Elastic公司出品的一款功能强大的搜索引擎,被广泛的应用于各大IT公司,它的代码位于https://github.com/elastic/elasticsearch,目前是一个开源项目。ElasticSearch公司的另外两个开源产品Logstash、Kibana与ElasticSearch构成了著名的ELK技术栈。。他们三个共同形成了一个强大的生态圈。简单地说,Logstash负责数据

  10. 【Elasticsearch基础】Elasticsearch索引、文档以及映射操作详解 - 2

    文章目录概念索引相关操作创建索引更新副本查看索引删除索引索引的打开与关闭收缩索引索引别名查询索引别名文档相关操作新建文档查询文档更新文档删除文档映射相关操作查询文档映射创建静态映射创建索引并添加映射概念es中有三个概念要清楚,分别为索引、映射和文档(不用死记硬背,大概有个印象就可以)索引可理解为MySQL数据库;映射可理解为MySQL的表结构;文档可理解为MySQL表中的每行数据静态映射和动态映射上面已经介绍了,映射可理解为MySQL的表结构,在MySQL中,向表中插入数据是需要先创建表结构的;但在es中不必这样,可以直接插入文档,es可以根据插入的文档(数据),动态的创建映射(表结构),这就

随机推荐