Spring容器的通俗理解及简单写法

问题描述:

  1. 初学者新接触到Spring容器的时候,总是各种懵。
  2. 不知道对象为什么可以在想要的地方,直接@Autowired一下,就可以用。
  3. 这篇文章就是通俗的讲讲,如何做到用@Autowired就可以获得想要的对象。

先想一想为什么要引入Spring容器?

  1. 在实际的开发工作中,开发人员需要编写很多Class去完成一个功能的编写,完成一个事务的处理。
  2. 要使用一个Class去干活,我们先得new一个这个Class的实例对象对吧,会向JVM(Java Virtual Machine)申请空间,然后才可以执行Class中编写的非静态代码段。
  3. 如果没有Spring容器,那么每次new出来的对象干完活,是不是得释放掉呀,避免占用空间对吧。

那么问题就来了,这样重复的对常用的Class去new对象,去释放对象,反而不如就让这些常用的Class保留一个对象对系统的资源开销小。于是Spring容器,应运而生。就是为了解决此处的开发痛点而出现的。

Spring容器的通俗理解:

  1. Spring容器的实际作用,老师们都应该讲过,就是一个承装对象的东西。
  2. 具体点,比如:可以将Spring容器理解为一个工具箱,工具箱里面可以有锤子、钳子、扳手、卷尺等等。

其实Spring容器,也就主要干了三事情。

  1. 创建并保留对象实例。
  2. 给对象实例打上标记管理起来。
  3. 提供给外部通过实例对象的标记获取对象的接口。

实践,干!不怂:

下面来用简单的代码实现一个非常粗犷的Spring容器吧,跟着看一遍,就能懂了。

编码准备:

  1. java JDK1.8版本
  2. IDE工具,首选IntelliJ IDEA(这个要收费,有点小贵,当然破解的方法我是不会告诉你们的,我公开是支持正版的),或者Eclipse,不建议用MyEclipse

准备几个Class:

自定义注册注解:

package com.example.demo.annotation;

import java.lang.annotation.*;

/**
 * Created by CN94740284 on 2/9/2020.
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyComponent {
}

自定义绑定注解:

package com.example.demo.annotation;

import java.lang.annotation.*;

/**
 * Created by CN94740284 on 2/9/2020.
 */
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyAutowired {
}

注册和数据绑定器:

/**
 * Created by CN94740284 on 11/20/2020.
 */
public class Register {

    private static Container container = new Container();

    private static Container getContainer() {
        return container;
    }

    private static boolean regist(Class<?> clzz){
        Container container = Register.getContainer();
        Map<String, Object> tools = container.getTools();
        Object o = null;
        try {
            o = clzz.newInstance();
            tools.put(clzz.getName(),o);
            return true;
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return false;
    }

    private static boolean myAutowired(){
        Map<String, Object> tools = Register.getContainer().getTools();

        tools.forEach((key,value)->{
            Class<?> clzz = value.getClass();
            Field[] fs = clzz.getDeclaredFields();
            try {
                bindFields(value, fs, tools);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        });

        return true;
    }

    public static <T> T getBean(Class<T> clzz){
        Map<String, Object> tools = Register.getContainer().getTools();
        T t = (T) tools.get(Test.class.getName());
        return t;
    }

    private static boolean bindFields(Object obj,Field[] fields,Map<String, Object> tools) throws IllegalAccessException {
        for (Field field : fields) {
            //获取属性上T类型的注解
            if(field.isAnnotationPresent(MyAutowired.class)) {
                Class<?> type = field.getType();
                Object tool = tools.get(type.getName());
                if(tool!=null){
                    field.setAccessible(true);
                    field.set(obj,tool);
                }else{
                    return false;
                }
            }
        }
        return true;
    }

    public static boolean registAndAutoBind(ScanFileTool t) {
        t.findClassLocal(ScanFileTool.STARATEGY_PATH);
        List<Class<? extends String>> eleStrategyList = t.getEleStrategyList();

        // 注册对象
        if(eleStrategyList!=null && eleStrategyList.size()>0){
            eleStrategyList.forEach((clzz)->{
                if(clzz.isAnnotationPresent(MyComponent.class)){
                    Register.regist(clzz);
                }
            });
        }

        // 绑定属性对象
        Register.myAutowired();

        return true;
    }
}

使用@MyComponent注解:

package com.example.demo.tools;

import com.example.demo.annotation.MyComponent;

/**
 * Created by CN94740284 on 11/20/2020.
 */

@MyComponent
public class Hamer extends Tool {

}

准备抽象类:

package com.example.demo.tools;

import com.alibaba.fastjson.JSON;

/**
 * Created by CN94740284 on 11/20/2020.
 */
public abstract class Tool {

    public String getToolName() {
        return getClass().getName();
    }

    @Override
    public String toString() {
        return JSON.toJSONString(this);
    }
}

使用自定义注解@MyComponent注册,使用@MyAutowired绑定注入数据

package com.example.demo.tools.test;

import com.example.demo.annotation.MyAutowired;
import com.example.demo.annotation.MyComponent;
import com.example.demo.tools.Hamer;

/**
 * Created by CN94740284 on 11/20/2020.
 */
@MyComponent
public class Test {

    @MyAutowired
    private Hamer hamer;

    public void printHamerName(){
        System.out.println("Test : "+hamer.getToolName());
    }

}

以上方法和类的放心食用方式:

package com.example.demo;

import com.example.demo.register.Register;
import com.example.demo.tools.test.Test;
import com.example.demo.utils.ScanFileTool;

import java.net.URISyntaxException;

public class DemoApplication {

    public static void main(String[] args) throws URISyntaxException {

        // 根据包路径扫描含有自定义注解的对象
        ScanFileTool t = new ScanFileTool();

        // 注册并绑定
        boolean b = Register.registAndAutoBind(t);

        // 类似SpringUtils.getBean
        Test test = Register.getBean(Test.class);

        // 调用对象方法
        test.printHamerName();

    }

}

流程如下:

注册
绑定
根据类名
扫描包ScanFileTool
容器Map
绑定对象
容器准备完毕
获取/使用对象

相关代码下载链接:点此下载

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值