模拟实现spring中DI的实现方式

Spring:轻量级的容器框架,核心是IOC和AOP,今天主要讲解模拟IOC(DI)

IOC:

依赖注入(Dependecy Injection)和控制反转(Inversion of Control)是同一个概念,具体的讲:当某个角色需要另外一个角色协助的时候,在传统的程序设计过程中,通常由调用者来创建被调用者的实例。但在spring中创建被调用者的工作不再由调用者来完成,因此称为控制反转。创建被调用者的工作由spring来完成,然后注入调用者,因此也称为依赖注入。 spring以动态灵活的方式来管理对象 , 注入的两种方式,设置注入和构造注入。 

设置注入的优点:直观,自然 

构造注入的优点:可以在构造器中决定依赖关系的顺序。

工程结构

UserController

package com.simulate.simulatedi.controller;

import com.simulate.simulatedi.annotation.MyAutowired;
import com.simulate.simulatedi.service.UserService;

/**
 * <pre>
 *    @author  : liquid
 *    email   : xiaokui.li@guigu.com
 *    time    : 19/7/21上午11:57
 *    desc    : 输入描述
 *    version : v1.0
 * </pre>
 */
public class UserController {
    @MyAutowired
    private UserService userService;
    public void controllerMethod(){
        userService.print();
    }
}

UserService

package com.simulate.simulatedi.service;

/**
 * <pre>
 *    @author  : liquid
 *    email   : xiaokui.li@guigu.com
 *    time    : 19/7/21上午11:57
 *    desc    : 输入描述
 *    version : v1.0
 * </pre>
 */
public class UserService {
    public void print(){
        System.out.println("调用了UserService的print方法,说明自定义注解成功了。");
    }
}

MyAutowired,自定义注解,没有任何方法,只是做了一个注解声明,来表示对象注入

package com.simulate.simulatedi.annotation;

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

/**
 * <pre>
 *    @author  : liquid
 *    email   : xiaokui.li@guigu.com
 *    time    : 19/7/21上午11:53
 *    desc    : 模拟注解注入对象
 *    version : v1.0
 * </pre>
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAutowired {

}

BeanFactory,通过反射来获取对象

package com.simulate.simulatedi.BeanFactory;

import com.simulate.simulatedi.annotation.MyAutowired;

import java.lang.reflect.Field;

/**
 * <pre>
 *    @author  : liquid
 *    email   : xiaokui.li@guigu.com
 *    time    : 19/7/21下午12:20
 *    desc    : 输入描述
 *    version : v1.0
 * </pre>
 */
public class BeanFactory {
    public static <Q> Q getBean(Class<Q> clazz) {
        Q result = null;
        try {
            result = clazz.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
            System.out.println("get the " + clazz.getName() + "failed!!");
            return null;
        } catch (IllegalAccessException e) {
            System.out.println("get the " + clazz.getName() + "failed!!");
            e.printStackTrace();
            return null;
        }
        //查找所有的字段
        Field[] fields = clazz.getDeclaredFields();
        //查找字段中含有依赖注入的字段 存在就进行注入
        for (Field field : fields) {
            MyAutowired inject = field.getAnnotation(MyAutowired.class);
            if (inject != null) {
                Object object = getBean(field.getType());
                if (!field.isAccessible())
                    //当isAccessible()的结果是false时不允许通过反射访问该字段
                    field.setAccessible(true);
                try {
                    field.set(result,object);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                    System.out.println("MyAutowired the " + field.getName() + "failed!!");
                }
            }
        }
        return result;
    }
}

UserControllerTest

package com.simulate.simulatedi.controller;

import com.simulate.simulatedi.BeanFactory.BeanFactory;
import com.simulate.simulatedi.annotation.MyAutowired;

/**
 * <pre>
 *    @author  : liquid
 *    email   : xiaokui.li@guigu.com
 *    time    : 19/7/21下午12:01
 *    desc    : 测试类
 *    version : v1.0
 * </pre>
 */
public class UserControllerTest {
    @MyAutowired
    public static UserController userController;
    public static void main(String[] args) {
        BeanFactory.getBean(UserControllerTest.class);
        userController.controllerMethod();
    }
}

运行结果

调用了UserService的print方法,说明自定义注解成功了。

Process finished with exit code 0

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值