1 官方资料
1.1 官网
1.2 进入 Spring5
下拉 projects, 进入 Spring Framework

进入 Spring5 的 github

1.3 在maven项目中导入依赖
<dependencies>
    <!--加入spring开发的基本包-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.3.8</version>
    </dependency>
    <!--加入spring开发切面编程需要的包-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>5.3.8</version>
    </dependency>
</dependencies>1.4 官方文档
2 Spring核心内容

上图说明:
3 Spring的几个重要概念
(1)Spring 可以整合其他的框架(Spring 是管理框架的框架)
(2)Spring 有两个核心的概念: IOC 和 AOP
(3)IOC(Inversion Of Control 反转控制)
- 传统的开发模式[JdbcUtils / 反射]
程序------>环境(程序读取环境配置,然后自己创建对象.)

解读:程序员编写程序, 在程序中读取配置信息;创建对象, new 或者 反射方式;使用对象完成任务
- IOC 的开发模式 [EmpAction EmpService EmpDao Emp]
程序<-----容器(容器创建好对象,程序直接使用.)

解读:
 
 
  4 Spring快速入门
4.1 需求说明
 
 
4.2 实现步骤
(1)创建一个maven项目,在pom.xml文件中导入以下依赖
<dependencies>
    <!--加入spring开发的基本包-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.3.8</version>
    </dependency>
    <!--加入spring开发切面编程需要的包-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>5.3.8</version>
    </dependency>
</dependencies>(2) 创建 Moster 的javabean/entity,无参构造器一定要写
public class Monster {
    private Integer monsterId;
    private String name;
    private String skill;
    //全参构造器
    public Monster(Integer monsterId, String name, String skill) {
        this.monsterId = monsterId;
        this.name = name;
        this.skill = skill;
    }
    //无参构造器一定要写,Spring反射创建对象时,需要使用
    public Monster() {
    }
    public Integer getMonsterId() {
        return monsterId;
    }
    public void setMonsterId(Integer monsterId) {
        this.monsterId = monsterId;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSkill() {
        return skill;
    }
    public void setSkill(String skill) {
        this.skill = skill;
    }
    @Override
    public String toString() {
        return "Monster{" +
                "monsterId=" + monsterId +
                ", name='" + name + '\'' +
                ", skill='" + skill + '\'' +
                '}';
    }
}(3) 新建一个容器配置文件:鼠标右键目录名 --> new --> XML Configuration --> Spring Config,然后给配置文件取个名字,这里取beans(对于Maven项目XML文件通常在 src/main/resources 目录)

点击 创建 Spring facet ,然后点击确定

 
 
(4)在xml文件中配置Moster对象,在beans标签加入以下配置
注意:将class属性值修改为指定类的全路径
<!--
        1. 配置monster对象/javabean
        2. 在beans中可以配置多个bean
        3. 一个bean表示就是一个java对象
        4. class属性是用于指定类的全路径->spring底层使用反射创建
        5. id属性表示该java对象在spring容器中的id, 通过id可以获取到对象
        6. <property name="monsterId" value="100"> 用于给该对象的属性赋值
-->
<bean class="com.spring.bean.Monster" id="monster01">
    <property name="monsterId" value="100"/>
    <property name="name" value="牛魔王"/>
    <property name="skill" value="芭蕉扇"/>
</bean>
<bean class="com.spring.bean.Monster" id="monster02">
    <property name="monsterId" value="1001"/>
    <property name="name" value="牛魔王~"/>
    <property name="skill" value="芭蕉扇~"/>
</bean>(5)新建一个测试类来获取容器中的对象
public class SpringBeanTest {
    @Test
    public void getMonster(){
        //1. 创建容器 ApplicationContext
        //2. 该容器和容器配置文件关联
        ApplicationContext ioc =
                new ClassPathXmlApplicationContext("beans.xml");
        //3. 通过getBean获取对应的对象
        //   默认返回的是Object , 但是运行类型Monster
        //Object monster01 = ioc.getBean("monster01");
        Monster monster01 = (Monster) ioc.getBean("monster01");
        //4. 输出
        System.out.println("monster01=" + monster01 + " 运行类型=" + monster01.getClass());
        System.out.println("monster01=" + monster01 + "属性name=" + monster01.getName() +
                " monserid=" + monster01.getMonsterId());
        //5. 也可以在获取的时候,直接指定Class类型, 可以再次获取
        Monster monster011 = ioc.getBean("monster01", Monster.class);
        System.out.println("monster011=" + monster011);
        System.out.println("monster011.name=" + monster011.getName());
        //6. 查看容器注入了哪些bean对象,会输出bean的id
        System.out.println("================================");
        String[] beanDefinitionNames = ioc.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            System.out.println("beanDefinitionName=" + beanDefinitionName);
        }
        System.out.println("================================");
        System.out.println("ok~~~");
    }
}
运行结果:

4.3 注意事项
(1)该代码为什么读取到beans.xml文件
ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");该代码通过类路径加载配置文件,可通过以下方式输出类加载路径
File f = new File(this.getClass().getResource("/").getPath());
System.out.println(f);maven项目的类加载路径是:target\classes
(2)debug 看看 spring 容器结构/机制




 
 


(3) 当调用getBean(),方法获取对象时,会去beanDefinitionMap中去查找,如果发生该bean是单例的,就会返回 singletonobject 中初始化好了的对象,如果不是,就会动态的通过反射机制返回一个临时创建的对象
5 实现简单的基于XML配置的Spring
5.1 需求说明
5.2 思路分析
(1)使用xml的解析技术-Dom4j
 (2)读取beans.xml
 (3)解析得到monster对象的id,classpath,属性
 (4)使用反射,创建对象
 (5)放入到ioc容器(hashmap)
 (6)提供一个getBean方法
5.3 实现步骤
(1)在maven项目中添加dom4j依赖
第一种方式:如果导入低版本(1.6.1),需要如下两个依赖
<dependency>
            <groupId>dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>1.6.1</version>
</dependency>
<dependency>
            <groupId>jaxen</groupId>
            <artifactId>jaxen</artifactId>
            <version>1.1.1</version>
</dependency>
第二种方式:如果导入高版本(2.0.0),需要如下一个依赖
<dependency>
    <groupId>org.dom4j</groupId>
    <artifactId>dom4j</artifactId>
    <version>2.0.0</version>
</dependency>
(2)实现容器类 WwjApplicationContext,java
注意:项目系统目录不能有中文,或者会找不到XML文件
package com.spring.wwjApplicationContext;
import com.spring.bean.Monster;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.File;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
/**
 * 1. 这个程序用于实现Spring的一个简单容器机制
 * 2. 这里实现如何将beans.xml文件进行解析,并生成对象,放入容器中
 * 3. 提供一个方法 getBean(id) 返回对应的对象
 */
public class WwjApplicationContext {
    private ConcurrentHashMap<String, Object> singletonObjects =
            new ConcurrentHashMap<>();
    //构造器
    //接收一个容器的配置文件 比如 beans.xml, 该文件默认在resources
    public WwjApplicationContext(String iocBeanXmlFile) throws Exception {
        //1. 得到类加载路径
//        String path = this.getClass().getClassLoader().getPath();
        String path = this.getClass().getResource("/").getPath();
        //2. 创建 Saxreader
        SAXReader saxReader = new SAXReader();
        //3. 得到Document对象
        Document document =
                saxReader.read(new File(path + iocBeanXmlFile));
        //4. 得到rootDocument
        Element rootElement = document.getRootElement();
        //5. 得到第一个bean-monster01
        Element bean = (Element) rootElement.elements("bean").get(0);
        //6. 获取到第一个bean-monster01的相关属性
        String id = bean.attributeValue("id");
        String classFullPath = bean.attributeValue("class");
        List<Element> property = bean.elements("property");
        //遍历
        Integer monsterId =
                Integer.parseInt(property.get(0).attributeValue("value"));
        String name = property.get(1).attributeValue("value");
        String skill = property.get(2).attributeValue("value");
        //7. 使用反射创建对象.=> 回顾反射机制
        Class<?> aClass = Class.forName(classFullPath);
        //这里o对象就是Monster对象
        Monster o = (Monster) aClass.newInstance();
        //给o对象赋值
        o.setMonsterId(monsterId);
        o.setName(name);
        o.setSkill(skill);
        //8. 将创建好的对象放入到singletonObjects
        singletonObjects.put(id, o);
    }
    public Object getBean(String id) {
        return singletonObjects.get(id);
    }
}
(3)创建main类测试
package com.spring;
import com.spring.bean.Monster;
import com.spring.wwjApplicationContext.WwjApplicationContext;
public class AppMain {
    public static void main(String[] args) throws Exception {
        WwjApplicationContext ioc = new WwjApplicationContext("beans.xml");
        Monster monster01 = (Monster)ioc.getBean("monster01");
        System.out.println("monster01 = " + monster01);
    }
}
运行结果:

6 Spring 原生容器底层结构
 
 



















