Spring IOC(依赖注入)的实现及其原理

一、什么是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());
    }
}

猜你喜欢

转载自blog.csdn.net/peanutwzk/article/details/106664189