五、控制反转(IOC)和依赖注入(DI)
概念
控制反转:将创建对象的控制权反转给了spring
依赖注入:spring在创建对象的过程中,动态地将依赖对象注入到Bean组件
实现
工厂模式-BeanFactory
从BeanFactory中获取对象,没有就创建,依赖没有就创建依赖,对象一般默认单例模式
递归创建依赖会遇到循环依赖问题:
- 如果需要的依赖正处于创建状态,则发生了循环依赖(可用ConcurrentHashMap缓存对象来判断)
- 处理:将那个依赖的初始状态对象注入,即那个依赖对象里的成员变量为null
BeanFactory简易实现代码:
public class BeanFactory { //一个类对应一个对象 private static Map
, Object> classToBean = new ConcurrentHashMap<>(); public static Object getBean(Class cls) { return classToBean.get(cls); } public static void initBean(List > classList) throws Exception { List > toCreate = new ArrayList<>(classList); while (toCreate.size() != 0) { int remainSize = toCreate.size(); for (int i=0;i cls) throws IllegalAccessException, InstantiationException { if (!cls.isAnnotationPresent(Bean.class) && !cls.isAnnotationPresent(Controller.class)) { return true; } Object bean = cls.newInstance(); for (Field field : cls.getDeclaredFields()) { if (field.isAnnotationPresent(AutoWired.class)) { Class fieldType = field.getType(); Object reliantBean = BeanFactory.getBean(fieldType); if (reliantBean == null) { return false; } field.setAccessible(true); field.set(bean, reliantBean); } } classToBean.put(cls, bean); return true; }}
六、AOP
概念:弥补OOP的缺点,给每个函数前后留一个切面,可以实现业务代码和功能代码的分离
jdk代理
被代理对象需要有个接口,jdk通过动态实现这个接口来实现代理
cgLib代理
被代理对象没有接口怎么办?我们通过获取它的class字节码文件,创造一个继承它的子类,从而实现代理