简单的手动实现spring中的自动装配案例

news/2024/7/8 12:37:10 标签: java, 开发语言, spring

简简单单的实现一个spring中的自动装配和容器管理的小骚操作。

1,创建AutoSetBean.java

使用injectBeans静态方法,可以扫描指定包下的所有带MyInject注解的字段,如果在beans的Map中存在这个字段的实例化类,则执行装配。

java">import java.lang.reflect.Field;
import java.util.Set;
import org.example.test.custominj.myAnno.MyInject;
import org.reflections.Reflections;
import org.reflections.scanners.Scanners;
import org.reflections.util.ConfigurationBuilder;

public class AutoSetBean {

    public static void injectBeans(String packageName) {
        // 使用Reflections库来扫描指定包名下的所有类
        Reflections reflections = new Reflections(new ConfigurationBuilder()
                .forPackages(packageName)
                .addScanners(Scanners.FieldsAnnotated)
        );

        // 获取所有带有@MyInject注解的字段
        Set<Field> fields = reflections.getFieldsAnnotatedWith(MyInject.class);

        for (Field field : fields) {
            try {
                // 获取字段所在的类
                Class<?> declaringClass = field.getDeclaringClass();
                // 设置字段可访问
                field.setAccessible(true);

                // 如果MyBean.beans中已经存在这个类的实例,则直接使用
                Object instance = MyBean.beans.get(declaringClass);
                if (instance == null) {
                    // 如果不存在这个类的实例,则创建一个新的实例
                    instance = declaringClass.getDeclaredConstructor().newInstance();
                    MyBean.beans.put(declaringClass, instance);
                }

                // 获取需要注入的字段的类型
                Class<?> fieldType = field.getType();

                // 从MyBean.beans中获取该类型的实例
                Object beanToInject = MyBean.beans.get(fieldType);

                if (beanToInject != null) {
                    // 注入实例
                    field.set(instance, beanToInject);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

2, 创建MyBean.java

通过使用registerBean静态方法,扫描传入的包名,检查其是否有@MyRegister注解,并将所有有此注解的类实例化后装入beans中,以备后续的装配。

java">
import org.example.test.custominj.myAnno.MyRegister;
import org.reflections.Reflections;
import org.reflections.scanners.Scanners;
import org.reflections.util.ConfigurationBuilder;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class MyBean {
    public static Map<Class<?>, Object> beans = new HashMap<>();

    public static void registBean(String packageName) {
        // 配置Reflections库
        Reflections reflections = new Reflections(new ConfigurationBuilder()
                .forPackages(packageName)
                .addScanners(Scanners.TypesAnnotated)
        );

        // 获取所有带有@MyRegister注解的类
        Set<Class<?>> annotatedClasses = reflections.getTypesAnnotatedWith(MyRegister.class);

        for (Class<?> clazz : annotatedClasses) {
            try {
                // 实例化对象并放入beans Map中
                beans.put(clazz, clazz.getDeclaredConstructor().newInstance());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

3, 创建MyInject.java 和MyRegister注解

配置两个自定义注解,用于标识是否执行装配。

java">
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface MyInject {
}

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface MyRegister {
}

4,创建测试的Client.java 和被注入的MyService.java

@MyRegister作用于类上,注释后可以将这个类放入beans中,

@MyInject作用于字段,可以实现从容器中找到特定类型的实例化对象后执行装配。

java">import org.example.test.custominj.myAnno.MyInject;
import org.example.test.custominj.myAnno.MyRegister;

@MyRegister
public class Client {
    @MyInject
    private MyService myService;

    public void doSomething() {
        myService.doSomething();
    }
}

import org.example.test.custominj.myAnno.MyRegister;


@MyRegister
public class MyService {
    public void doSomething() {
        System.out.println("do something");
    }
}

5,创建测试类

@Test 测试自定义的自动装配

java">    @Test
    public void test4() {
        MyBean.registBean("org.example.test.myinjtest");
        // 打印已注册的beans
        for (Map.Entry<Class<?>, Object> entry : MyBean.beans.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
        AutoSetBean.injectBeans("org.example.test.myinjtest");
        client = (Client) MyBean.beans.get(Client.class);
        client.doSomething();
    }

执行结果,成功执行Service下的dosomething方法,成功打印!


http://www.niftyadmin.cn/n/5537190.html

相关文章

vue this.$refs加变量名

想动态获取$refs&#xff0c;我们可以用模板字符串来动态绑定ref的值。代码如下&#xff1a; this.$refs[${this.treeQueFlag}].setCheckedNodes([]); $refs后面拼变量&#xff0c;vue动态给$refs赋值_vue ref动态赋值-CSDN博客

Docker的基本介绍

Docker 简单介绍 基本概念 镜像 docker 镜像好比一个模板&#xff0c;可以通过这个模板来创建容器服务&#xff0c;是一种轻量级、可执行的软件包&#xff0c;包含运行应用程序时所需要的一切&#xff1a;代码、运行时、库、环境变量、配置文件等 所有的应用打包成一个 doc…

uniapp中实现瀑布流 短视频页面展示

直接上干货 第一部分为结构 <swiper class"list" :currentindex change"swiperchange" scrolltolower"onReachBottom"><swiper-item style"overflow: scroll;" v-for"(item,index) in 2" :key"index"&g…

网络安全筑基篇——反序列化漏洞

目录 序列化是什么&#xff1f; 反序列化又是什么&#xff1f; 反序列化漏洞的危害 代码样例 常见的魔术方法 修复方式有哪些&#xff1f; 常见的反序列化漏洞 Shiro反序列化漏洞 Fastjson反序列化漏洞 序列化是什么&#xff1f; 将实例化对象转换成字节流的过程 反序…

矩阵运算在数据分析中的应用

矩阵运算在数据分析中的应用 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 矩阵运算作为数学和计算机科学中的重要概念&#xff0c;在数据分析和科学计算中发…

类和对象-C++运算符重载-加号运算符重载

加号运算符重载 1、成员函数重载号 #include<iostream>using namespace std;class Person { public://1、成员函数重载号Person operator(Person &p){Person temp;temp.m_Athis->m_Ap.m_A;temp.m_Bthis->m_Bp.m_B;return temp; }int m_A;int m_B; }; void t…

【数据集】中国农田栅格数据CACD(1986-2021)

中国农田栅格数据(1986-2021) 数据概述数据下载参考精确、详细和及时的耕地范围信息对于保障食品安全和环境可持续性至关重要。然而,由于农业景观的复杂性以及缺乏足够的训练样本,要在大范围地理区域内高空间和时间分辨率下监测耕地动态仍然具有挑战性,特别是对于农业土地…

自动化革新者:PlugLink在“智创设计”中的实战应用

PlugLink&#xff1a;小微企业运营自动化的新引擎 在当今竞争激烈的市场环境下&#xff0c;小微企业要想脱颖而出&#xff0c;除了要有敏锐的市场洞察力&#xff0c;还需具备高效灵活的运营能力。本文将通过一个生动的实例&#xff0c;揭示开源项目PlugLink如何助力一家名为“…