栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringIoc模拟实现Demo

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringIoc模拟实现Demo

原理:SpringIoC控制反转底层实现利用了java自身提供的反射技术来创建对象

Class.forName(classPath).newInstance();

 通过这种方式,spring控制了对象的生命周期,可以随时自行增强对象,如DI依赖注入,如AOP,环绕通知在类创建前后增强功能,如Transaction事务加强等。

开发步骤
  1. 创建容器管理bean,并初始化容器-> [user,dept,hello]
  2. 创建spring容器,并初始化容器-> {hello=new Hello(),user=new Uer() }
  3. 提供getBean(),根据bean的名字,从spring容器中获取对应的对象
Bean.java

抽象Bean的定义,取代java中的Object,Spring框架中万物皆Bean。

package com;

public class Bean {
    //Bean的名字Id
    private String name;
    //Bean(java中的对象)对应的路径“包名.类名”
    private String path;

    
    public String getName() {
        return name;
    }

    public String getPath() {
        return path;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setPath(String path) {
        this.path = path;
    }
}
SpringContext.java

逻辑复杂,IoC实现的核心,最关键点还是怎么创建对象实例:

package com;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


public class SpringContext {
    //创建一个容器存放Bean
    private List beanFactory = new ArrayList<>();
    //构造方法创建框架是自动执行
    public SpringContext() throws Exception {
        //创建一个Bean
        Bean bean = new Bean();

        bean.setName("Hello");
        bean.setPath("com.Hello");
        //将Bean加入容器
        beanFactory.add(bean);
        init();
    }

    
    private final Map factoryBeanObject =
            new ConcurrentHashMap<>();
    public void init() throws Exception {
        for(Bean b : beanFactory){
            String key = b.getName();
            //反射创建对象,作为value存入map
            String path = b.getPath();
            Object value = Class.forName(path).newInstance();
            factoryBeanObject.put(key, value);
        }
    }

    //3,getBean()有就直接取出来,没有就创建并放入容器
    public Object getBean (String name){
        return factoryBeanObject.get(name);
    }
}
创建一个对象
package com;

public class Hello {
    public void hi(){
        System.out.println("你好,springIOC");
    }

}
测试类
package cn.tedu.spring;

import cn.tedu.design.SpringContext;
import cn.tedu.pojo.Hello;

public class TestMyIOC {
	public static void main(String[] args) throws Exception {
		SpringContext spring = new SpringContext();
		Hello o = (Hello)spring.getBean("hello");
		System.out.println(o);//cn.tedu.pojo.Hello@6d06d69c
		o.hi();
	}
}

模拟SpringDI的底层实现

自定义注解模拟Spring中的@Autowired注解

package com.di;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//注解只能加载属性上
@Target(ElementType.FIELD)
//设置运行时有效,需要动态注入
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAutowired {
    String value() default "";
}

创建一个Teacher类用来向其他对象注入

package com.di;

import org.springframework.stereotype.Component;

@Component
public class Teacher {
    private String name = "韩梅梅";

    @Override
    public String toString() {
        return "Teacher{" +
                "name='" + name + ''' +
                '}';
    }
}

创建一个Student类需要将Teacher注入到Student对象中

package com.di;

import org.springframework.stereotype.Component;

@Component
public class Student {
    private String name="李雷";

    //使用自定义注解标记注入对象
    @MyAutowired
    private Teacher teacher;

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + ''' +
                ", teacher=" + teacher +
                '}';
    }
}

创建一个测试类实现对象的注入,

package com.di;

import org.junit.Test;

import java.lang.reflect.Field;

public class TestDI {
    @Test

    public void di() throws Exception {
        //通过反射获取对象
        Class s = Class.forName("com.di.Student");
        //创建一个对象
        Object o = s.newInstance();
        //获取对象全部属性
        Field[] fs = s.getDeclaredFields();
        //遍历对象属性,拿到每一个属性
        for (Field f : fs) {
            //获取student中的注解
            MyAutowired an = f.getAnnotation(MyAutowired.class);
            //判断注解是否为空
            if(an != null){
                //需要将Teacher对象注入
                f.setAccessible(true);
                f.set(o,new Teacher());
            }
        }
        System.out.println((Student)o);
    }
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/315667.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号