Spring
Java Web发展历史
- 第一阶段 JavaBean + Servlet + JSP
- 第二阶段 EJB重量级框架
- 第三阶段 SpringMVC/Struts + Spring + Hibernate/MyBatis
- 第四阶段 SpringBoot 约定大于配置
- 第五阶段 Dubbo为代表的SOA微服务架构体系
- 第六阶段 SpringCloud 微服务框架爱技术生态圈
课程内容IoC
- 介绍IoC并编写一个简单的IoC容器
- 介绍通过xml方式完成SpringIoC对Bean的管理
- 介绍SpringIoC相关注解的使用
IoC介绍
IoC Inversion of Control 控制反转,依赖注入
控制:控制对象的创建及销毁(生命周期)
反转:将对象的控制权交给IoC容器
简化约定
- 所有的Bean的生命周期都交由IoC容器管理
- 所有被依赖的Bean通过构造函数方法执行注入
- 被依赖的Bean需要优先创建
IoC实现
依赖关系
Car +start() +stop() +turnLeft() +turnRight() <- AudiCar <- BuickCar Human +goHome() <- HumanWithCar -car +goHome() <- LisiHuman <- ZhangsanHuman
代码实现
package com.demo.ioc.car; /** * 汽车 */ public interface Car { void start(); void stop(); void turnLeft(); void turnRight(); }
package com.demo.ioc.car; /** * 奥迪车 */ public class AudiCar implements Car{ @Override public void start() { System.out.println("AudiCar start"); } @Override public void stop() { System.out.println("AudiCar stop"); } @Override public void turnLeft() { System.out.println("AudiCar turnLeft"); } @Override public void turnRight() { System.out.println("AudiCar turnRight"); } }
package com.demo.ioc.car; /** * 别克车 */ public class BuickCar implements Car{ @Override public void start() { System.out.println("BuickCar start"); } @Override public void stop() { System.out.println("BuickCar stop"); } @Override public void turnLeft() { System.out.println("BuickCar turnLeft"); } @Override public void turnRight() { System.out.println("BuickCar turnRight"); } } package com.demo.ioc.human; /** * 人类接口 */ public interface Human { void goHome(); }
package com.demo.ioc.human; import com.demo.ioc.car.Car; /** * 有车人 */ public abstract class HumanWithCar implements Human { protected Car car; public HumanWithCar(Car car) { this.car = car; } public abstract void goHome(); } package com.demo.ioc.human; import com.demo.ioc.car.Car; /** * 张三 */ public class ZhangsanHuman extends HumanWithCar{ public ZhangsanHuman(Car car) { super(car); } @Override public void goHome() { this.car.start(); this.car.turnLeft(); this.car.stop(); } }
package com.demo.ioc.human; import com.demo.ioc.car.Car; /** * 李四 */ public class LisiHuman extends HumanWithCar{ public LisiHuman(Car car) { super(car); } @Override public void goHome() { this.car.start(); this.car.turnRight(); this.car.stop(); } }
package com.demo.ioc; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * 1. 实例化Bean * 2. 保存Bean * 3. 提供Bean * 4. 每个Bean要与唯一的id对应 */ public class IocContainer { private Map<String, Object> beans = new ConcurrentHashMap<>(); /** * 根据 beanId获取Bean * * @param beanId * @return */ public Object getBean(String beanId) { return beans.get(beanId); } /** * 委托IoC容器创建一个Bean * * @param clazz Bean的class * @param beanId Bean 的id * @param paramBeanIds class构造函数所需参数的beanId */ public void setBean(Class<?> clazz, String beanId, String... paramBeanIds) { // 1. 组装构造方法所需要的参数值 Object[] paramBeans = new Object[paramBeanIds.length]; for (int i = 0; i < paramBeanIds.length; i++) { paramBeans[i] = beans.get(paramBeanIds[i]); } // 2. 调用构造方法实例化Bean Object bean = null; for (Constructor<?> constructor: clazz.getConstructors()){ try { bean = constructor.newInstance(paramBeans); } catch (InstantiationException e) { } catch (IllegalAccessException e) { } catch (InvocationTargetException e) { } } if(bean == null){ throw new RuntimeException("Bean实例化失败"); } // 3. 将示例化的bean放入beans beans.put(beanId, bean); } }
代码回顾
所有的依赖关系被集中统一的管理起来,清晰明了
每个类只需要关注自己的业务逻辑
修改依赖关系将是一件很容易的事情