手写Spring框架学习Spring原理 之xml(二)

  • 一. 使用XML文件配置BeanDefinition信息
  • 二. 增加ApplicationContext
  • 为什么要增加ApplicationContext而不是继续扩展BeanFactory?
  • 三.实现XmlApplicationContext
  • 四.生成测试类测试
  • 手写Spring框架学习Spring原理 之注解配置原理(三)
  • 1.定义Component注解
  • 2.业务Bean加上 上述注解
  • 3.定义扫描类
  • 4.精简代码
  • 5.开始实现注解功能



GitHub地址:

https://github.com/dixinjoker/king-spring-theory

一. 使用XML文件配置BeanDefinition信息

test文件夹内创建resouces测试文件夹,创建application.xml文件

Spring xml 定义list spring创建xml文件_spring

<?xml version="1.0" encoding="UTF-8"?>
<beans>
    <bean id="userService" class="com.study.spring.theory.king.sample.UserServiceImpl"/>
</beans>

二. 增加ApplicationContext

为什么要增加ApplicationContext而不是继续扩展BeanFactory?

单一职责,也便于后续灵活扩展功能

context包下创建ApplicationContext接口继承BeanFactory

public interface ApplicationContext extends BeanFactory {
}

三.实现XmlApplicationContext

实现基于XML配置的XmlApplicationContext

public class XmlApplicationContext implements ApplicationContext{
    //1.持有BeanFactory
    private DefaultBeanFactory beanFactory;

    public XmlApplicationContext(String xmlConfigFileName) {
        this.beanFactory = new DefaultBeanFactory();
        //1.因为基于XML解析的,所以完成xml解析得到BeanDefinition,注册到BeanFactory
        //2.解析
            parseXmlRegistBeanDefinition(xmlConfigFileName);
    }
    //2.解析
    private void parseXmlRegistBeanDefinition(String xmlConfigFileName) {
        //3.使用document
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        try{
            DocumentBuilder builder = factory.newDocumentBuilder();
            //4.开始解析
            Document doc = builder.parse(this.getClass().getResourceAsStream(xmlConfigFileName));
            //5.得到所有的bean元素
            NodeList nodeList = doc.getElementsByTagName("bean");
            Element e = null;
            //类加载器
            ClassLoader classLoader = this.getClass().getClassLoader();
            //一个一个注册BeanDefinition
            for (int i = 0; i<nodeList.getLength(); i++){
                e = (Element)nodeList.item(i);
                String beanName = e.getAttribute("id");
                Class<?> beanClass = classLoader.loadClass(e.getAttribute("class"));
                //其他属性的处理略
                //注册beanDefinition
                this.beanFactory.registerBeanDefinition(beanName,new BeanDefinition(beanClass));
            }
        } catch (ParserConfigurationException | SAXException | IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

嗯,有注释。需要注意的是这里没贴重写的方法。

四.生成测试类测试

Spring xml 定义list spring创建xml文件_spring_02


测试成功。

这周有点忙,可能这篇文章看起来很水但是内容是实打实的。后续会继续增加,应该就是接着这篇写。

为了不误人子弟,暂不更新此系列。我好菜啊。

手写Spring框架学习Spring原理 之注解配置原理(三)

xml配置太繁琐,采用注解配置

1.定义Component注解

bean工厂包下创建annotation包定义Component注解

package com.study.spring.theory.king.beans.factory.annotation;
import java.lang.annotation.*;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Component {
    /**
     * Component name ,没有给定则使用类名
     */
    String value() default "";
}

对上面代码进行说明:
@Target:可以使用在哪里
@Retention:留存范围
@Documented://生成jacadoc时会有标识,无实际作用

2.业务Bean加上 上述注解

Spring xml 定义list spring创建xml文件_java_03

3.定义扫描类

创建AnnotationApplicaitonContext实现类

Spring xml 定义list spring创建xml文件_Spring xml 定义list_04

4.精简代码

结合之前代码发现比较冗余,精简下代码。将公共代码抽取到一个类中。

1.将公共代码抽取到AbstractApplicationContext类中

Spring xml 定义list spring创建xml文件_Spring xml 定义list_05

5.开始实现注解功能

1.创建构造方法,提供扫描功能

Spring xml 定义list spring创建xml文件_xml_06


2.实现扫描功能

Spring xml 定义list spring创建xml文件_spring_07


3.完善扫描功能

Spring xml 定义list spring创建xml文件_Spring xml 定义list_08

4.扫描注册Bean定义信息,并稍稍优化下代码

Spring xml 定义list spring创建xml文件_Spring xml 定义list_09


注释比较详细就不额外做说明了。5.80行左右就写完了。开始测试吧。狗头.jpg

Spring xml 定义list spring创建xml文件_spring_10

完结撒花 (注解部分),扩展部分:实现注解和xml同时生效。