Spring IOC/DI(控制反转/依赖注入)的实现及其原理

一、什么是IOC

  • IOC:把创建和查找依赖对象的控制权交给 IoC 容器,由 IoC 容器进行注入、组合对象。这样对象与对象之间是松耦合、便于测试、功能可复用(减少对象的创建和内存消耗),使得程序的整个体系结构可维护性、灵活性、扩展性变高。

二、工厂模式+反射

  • 工厂模式:

1、定义fruit接口:

package com.peanut.springstudy;

/**
 * @Author :  peanut
 * @Created : 2020/6/10 下午2:12
 */
public interface FruitInterface {

    void eat();
    
}

2、实现fruit接口:

package com.peanut.springstudy;

/**
 * @Author :  peanut
 * @Created : 2020/6/10 下午2:17
 */
public class Apple implements FruitInterface {
    @Override
    public void eat() {
        System.out.println("Apple");
    }
}


package com.peanut.springstudy;

/**
 * @Author :  peanut
 * @Created : 2020/6/10 下午2:17
 */
public class Orange implements FruitInterface {
    @Override
    public void eat() {
        System.out.println("Orange");
    }
}

3、实现fruit工厂(未加反射)

package com.peanut.springstudy;

/**
 * 构造水果工厂类
 *
 * @Author :  peanut
 * @Created : 2020/6/10 下午2:02
 */
public class FruitFactory {
    //也就是说以后如果我们在添加其他种类的水果的时候只需要简单修改一下水果工厂即可
    public static FruitInterface getInstance(String fruitName) {
        FruitInterface f = null;
        if ("Apple".equals(fruitName)) {
            f = new Apple();
        }
        if ("Orange".equals(fruitName)) {
            f = new Orange();
        }
        return f;
    }

    public static void main(String[] a) {
        FruitInterface f = FruitFactory.getInstance("Orange");
        f.eat();
    }

}

  • 反射:
    通过反射实现的工厂模式:无论用户添加多少实现类,都无需修改工厂
package com.peanut.springstudy;

/**
 * 构造水果工厂类
 *
 * @Author :  peanut
 * @Created : 2020/6/10 下午2:02
 */
public class FruitFactory {
    public static FruitInterface getInstance(String fruitName) throws ClassNotFoundException {
        FruitInterface f = null;

        try {
         //   这里只是简单地处理一下类名,实际应用可能还需更加复杂的处理
            f = (FruitInterface) Class.forName("com.peanut.springstudy."+fruitName).newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        return f;
    }

    public static void main(String[] a) throws ClassNotFoundException {
        FruitInterface f = FruitFactory.getInstance("Orange");
        f.eat();
    }

}

三、IOC的实现

自定义注解

package com.peanut.springstudy.annotation;


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

/**
 * 自定义MyAutowired注解
 * @Author :  peanut
 * @Created : 2020/6/10 下午2:46
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface MyAutowired {
}

service

package com.peanut.springstudy.service;

/**
 * @Author :  peanut
 * @Created : 2020/6/10 下午2:44
 */
public class UserService {
}

controller

package com.peanut.springstudy.controller;

import com.peanut.springstudy.annotation.MyAutowired;
import com.peanut.springstudy.service.UserService;

import java.util.stream.Stream;


/**
 * @Author :  peanut
 * @Created : 2020/6/10 下午2:43
 */
public class UserController {
    @MyAutowired
    //  通过反射为引用userService赋予实例
    private UserService userService;

    //   方便测试使用
    public UserService getUserService() {
        return userService;
    }

    public static void main(String[] args) {
        UserController userController = new UserController();
        Stream.of(userController.getClass().getDeclaredFields()).forEach((field) -> {
            MyAutowired myAutowired = field.getAnnotation(MyAutowired.class);
            if (myAutowired != null) {
                field.setAccessible(true);
                try {
//                  根据field的类型得到实例,并且set到userController中
                    field.set(userController,field.getType().newInstance());
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        });
        System.out.println(userController.getUserService());
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

-乾坤-

????????????????????????

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值