Spring学习日记——Day01(简单配置使用Spring,手写Spring的简单工厂模式)

哈喽大家好,今天继续肝 Spring 框架,从最基础的环境、设计模式,一路冲到IoC 控制反转DI 依赖注入,全是干货,直接当笔记抄~


一、先搞懂:Spring 是什么?

  • 轻量级、开源、JavaEE 一站式解决方案
  • 核心目的:让 JavaEE 开发更简单
  • 非侵入式、体积小、不挑运行环境

二、前置技能(必须会)

  • JavaSE
  • 数据库(MySQL/Oracle)
  • Web 基础(HTML/JSP/Servlet)
  • Maven
  • 持久层框架(MyBatis/Hibernate 可选)

三、Spring 用到的核心设计模式

1. 工厂模式

作用:解耦,不用 new 对象,通过工厂反射创建

  • 支持 properties 配置
  • 支持 XML 配置
  • 底层:反射 + 配置文件
  • 我们只需要告诉工厂类我们需要的工件名,工厂就会给我们生产对应的工件,避免了硬编码

简单手写一个工厂模式:

这是读取xml文件的工厂模式,Spring源码中是通过获取set方法来进行属性赋值操作的,而我是通过field获取access权限之后,直接赋值的;

java 复制代码
package com.djw.user;

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

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.List;

/**
 * @author djw
 */
public class XMLBeanFactory {
    public static Object getDaoImpl(String key){
        SAXReader reader = new SAXReader();
        try {
            Document document = reader.read("D:\\workspace\\SpringFrameWork\\day01\\target\\classes\\bean.xml");
            Element rootElement = document.getRootElement();
            List<Element> elements = rootElement.elements();
            for (Element element : elements) {
                if(key.equals(element.attributeValue("id"))){
                    String clazz = element.attributeValue("class");
                    Class<?> aclass = Class.forName(clazz);
                    Object o = aclass.getConstructor().newInstance();
                    List<Element> elements1 = element.elements();
                    if(elements1.size() > 0){
                        for(Element e : elements1){
                            String s = e.attributeValue("name");
                            Field field = aclass.getDeclaredField(s);
                            field.setAccessible(true);
                            field.set(o,e.attributeValue("value"));
                        }
                    }
                    return o;
                }
            }
        } catch (DocumentException e) {
            throw new RuntimeException(e);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        }
        return null;
    }
    public static void main(String[] args) {
        Boy boy = (Boy) XMLBeanFactory.getDaoImpl("boy");
        System.out.println(boy);
    }
}

2. 单例模式

一个类只产生一个对象

  • 饿汉式:类加载就创建
  • 懒汉式:用到才创建
  • Spring Bean默认单例

这里我也简单手搓了一个单例模式的例子

java 复制代码
//饿汉模式
public class Sington {
    private static Sington single = new Sington();
    private Sington() {}
    public static Sington getInstance() {
        return single;
    }
}
java 复制代码
//懒汉模式
public class Singleton{
    private static Singleton st = null;
    private Singleton(){};
    private getInstance(){
        if(st==null){
            st = new Singleton();
        }
        return st;
    }

}

四、Spring 入门程序(标准步骤)

1. Maven 依赖

复制代码
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.3.15</version>
</dependency>

2. 编写 bean.xml

复制代码
<beans ...>
    <bean id="userDao" class="com.xzit.user.UserDaoJdbcImpl"></bean>
    <bean id="userDao1" class="com.xzit.user.UserDaoMybatisImpl"></bean>
</beans>

3. 测试类(重点规范)

复制代码
public class Test {
    public static void main(String[] args) {
        // 只在main/入口类加载Spring容器
        ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");
        
        // 从容器拿bean
        UserDao dao = (UserDao) ctx.getBean("userDao1");
        System.out.println(dao);
    }
}
  • Spring 容器(ApplicationContext)只在 main 方法、启动类等入口创建一次
  • 业务类(Service/Dao)绝对不能出现 new ClassPathXmlApplicationContext
  • 业务类需要对象,靠注入,不要自己拿容器

五、属性赋值(set 注入)

1. 基本类型

复制代码
<bean id="boy" class="com.xzit.user.Boy">
    <property name="name" value="李四"></property>
    <property name="age" value="20"></property>
</bean>

2. 引用类型

复制代码
<bean id="girl" class="com.xzit.user.Girl">
    <property name="name" value="李某"></property>
</bean>

<bean id="boy" class="com.xzit.user.Boy">
    <property name="girl" ref="girl"></property>
</bean>

六、核心:IoC & DI 到底啥意思?

1. IoC 控制反转

  • 以前:自己new UserDao() → 自己控制对象生命周期
  • 现在:对象交给 Spring 容器创建、管理
  • 控制权:从程序员 → 反转给 Spring 容器

一句话:IoC 就是容器帮你管对象

2. DI 依赖注入

  • 作用:给对象的属性自动赋值
  • 方式:set 注入、构造注入、自动装配
  • 前提:必须开启 IoC

一句话:DI 就是容器帮你自动填属性


七、DI 依赖注入(常用写法)

1. set 注入(最常用)

复制代码
<property name="name" value="李四"></property>
<property name="girl" ref="girl"></property>

2. 构造方法注入

复制代码
<constructor-arg name="name" value="张三"></constructor-arg>
<constructor-arg name="age" value="20"></constructor-arg>

3. 自动注入

  • byName:按属性名匹配 bean id

  • byType:按类型匹配(同类型只能有一个 Bean)

    <bean id="student" class="com.xzit.auto.Student" autowire="byName"></bean>

相关推荐
木易 士心1 小时前
深度解析:一个 Java 对象究竟占用多少字节?
java·开发语言·后端
夜猫子ing1 小时前
《嵌入式 Linux 控制服务从零搭建(二):从目录结构到 CMakeLists,搭一个像样的 C++ 工程骨架》
java·前端·c++
人道领域2 小时前
【LeetCode刷题日记】二叉树翻转:递归与迭代全解析
java·算法·leetcode
Cyan_RA92 小时前
SpringMVC 视图和视图解析器 万字详解
java·spring·mvc·springmvc·请求重定向·modelandview·视图解析器
想学习java初学者10 小时前
SpringBoot整合Vertx-Mqtt多租户(优化版)
java·spring boot·后端
AC赳赳老秦10 小时前
政企内网落地:OpenClaw 离线环境深度适配方案,无外网场景下本地化模型对接与全功能使用
java·大数据·运维·python·自动化·deepseek·openclaw
weixin_4491736511 小时前
在 Java 中,‌线程安全的 List‌ 主要有以下几种实现方式,它们的效率取决于具体的使用场景(尤其是读写比例):
java·线程安全的list
砚底藏山河11 小时前
股票数据API接口:如何获取股票历历史分时KDJ数据
java·python·maven
MegaDataFlowers12 小时前
运行若依项目
java