一、了解Spring IOC/DI

  1:Spring有两大核心技术,控制反转(Inversion of Control, IOC)/依赖注入(Dependency Injection,DI)和面向切面编程(Aspect Oriented Programming,AOP)

  2. IOC/DI: 它用来管理所有的java类,类对象的创建和依赖关系都由IOC/DI进行控制。控制反转(IOC)和依赖注入(DI)在spring中表示同一种意思,只是看问题的角度不同,例如

  当在A类中new一个B类时,控制权由A掌握,可以理解为控制正转,当A类使用的B类实例有spring创建时,控制权由spring掌握,就是控制反转;

  依赖注入可以理解为A类依赖于spring,由spring注入B类。控制反转是抽象的概念,只是提出了一种“控制”的方式,而依赖注入是spring框架实现“控制反转”的具体方法。

  3. IOC/DI工作原理:spring IOC/DI的更为直观的叫法是容器,这是因为spring可以管理很多类,当需要某一类对象的实例时,spring就会提供相应的实例,就像是一个容器里面

  可以放入很多东西,需要什么就取什么。那么在spring容器中都有什么类可以使用呢?这需要预先定义在spring的配置文件中,默认的配置文件名称是applicationContext.xml

  例如在配置文件中定义了A类和B类,而A类中使用到了B类,那么配置文件中再定义好这种依赖关系,即可由Spring自动地把B类实例注入到A类中,但是,这种注入是有条件的,

  类需要符合Javabean的定义规范,在A类中需要定义对B类赋值的setter方法。这是Spring对管理的类唯一的要求,不需要像EJB那样实现框架本身的任何接口,也是spring被称

  为轻量级框架的原因。

二、IOC/DI使用到的技术

  1. JDOM:JDOM是对xml文件进行解析的技术,Spring的配置文件applicationContext.xml就是由JDOM进行解析的,它可以提取出xml文件中定义的标签和属性值。

  1.1 环境的搭建:

  

  1.2 StudentAction.java

public class StudentAction {
private StudentService studentService; public void setStudentService(StudentService studentService) {
this.studentService = studentService;
}
public void printName() {
System.out.println(studentService.getName());
}
}

  1.3 StudentServiceImpl.java

public class StudentServiceImpl implements StudentService{
private StudentDao studentDao; public void setStudentDao(StudentDao studentDao) {
this.studentDao = studentDao;
} public String getName() {
return studentDao.getName();
}
}

  1.4 StudentService.java

public interface StudentService {
public String getName();
}

  1.5 StudentDao.java

public interface StudentDao {
public String getName();
}

  1.6 StudentDaoImpl.java

public class StudentDaoImpl implements StudentDao{

    public String getName() {
return "Jike Wang";
}
}

  1.7 测试

public class TestAction {
public static void main(String[] args) {
//使用ApplicationContext接口的实现类ClassPathXmlApplicationContext加载spring配置文件
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/applicationContext.xml");
//通过ApplicationContext接口的getBean方法获取id或name为studentAction的Bean实例
StudentAction studentAction = (StudentAction) applicationContext.getBean("studentAction");
//调用方法
studentAction.printName();
}
}

  1.8 使用jdom模拟spring解析xml文件,读取关键信息

  自定义XML代码:

<?xml version="1.0" encoding="UTF-8"?>
<beans>
<!-- 定义StudentDaoImpl对象并指定id为studentDao -->
<bean id="studentDao" class="com.IOC.dao.impl.StudentDaoImpl"></bean>
<!-- 定义StudentServiceImpl对象并指定id为studentService-->
<bean id="studentService" class="com.IOC.service.impl.StudentServiceImpl">
<property name="studentDao" ref="studentDao"></property>
</bean>
<!-- 定义StudentAction对象并指定id为studentAction -->
<bean id="studentAction" class="com.IOC.action.StudentAction">
<property name="studentService" ref="studentService"></property>
</bean>
</beans>
public class TestJDOM {
public static void main(String[] args) {
String path = "src/main/resources/applicationContext.xml";//xml文件目录
//用于创建文档对象
SAXBuilder sb = new SAXBuilder();
//构造的XML文档对象
Document doc;
try {
//创建文档对象
doc = sb.build(path);
//得到文档的根元素<beans>
Element rootElement = doc.getRootElement(); //得到文档的所有<bean>
List<Element> list = rootElement.getChildren("bean");
for (Element element : list) {
//得到<bean>的id属性值
String id = element.getAttributeValue("id");
//得到<bean>的class属性值
String classValue = element.getAttributeValue("class");
//得到<bean>的子元素<property>
Element propertyElement = element.getChild("property");
String propertyName = null;
String propertyRef = null;
if (propertyElement != null) {
//得到<property>的name属性值
propertyName = propertyElement.getAttributeValue("name");
//得到property的内容
propertyRef = propertyElement.getAttributeValue("ref");
}
System.out.println("========================");
System.out.println("id="+id);
System.out.println("class="+classValue);
System.out.println("propertyName="+propertyName);
System.out.println("propertyRef="+propertyRef);
System.out.println("========================");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

测试结果:

 2. 反射机制:对配置文件中的类名使用反射机制可以实现类加载初始化等工作,也可以调用类的方法进行属性注入,java.lang.reflect提供了反射相关的工具

public class TestReflect {
public static void main(String[] args) {
//表示StudentDao接口全路径
String studentDao = "com.IOC.dao.StudentDao";
//表示StudentService接口全路径
String studentService = "com.IOC.service.StudentService";
//表示StudentDaoImpl类全路径
String studentDaoImpl = "com.IOC.dao.impl.StudentDaoImpl";
//表示StudentServiceImpl
String studentServiceImpl = "com.IOC.service.impl.StudentServiceImpl";
//表示StudentAction类全路径
String studentAction = "com.IOC.action.StudentAction"; //表示setStudentService方法的字符串
String setStudentService = "setStudentService";
//表示setStudentDao方法的字符串
String setStudentDao = "setStudentDao";
try {
//使用全路径字符串加载StudentDao类别
Class studentDaoClass = Class.forName(studentDao);
//使用全路径字符串加载StudentService类别
Class studentServiceClass = Class.forName(studentService);
//使用全路径字符串加载StudentDaoImpl类别
Class studentDaoImplClass = Class.forName(studentDaoImpl);
//使用全路径字符串加载StudentServiceImpl类别
Class studentServiceImplClass = Class.forName(studentServiceImpl);
//使用全路径字符串加载StudentAction类别
Class studentActionClass = Class.forName(studentAction); //setStudentDao方法签名,相当于获取次此方法,使用类别获取setStudentDao方法
Method setDaoMethod = studentServiceImplClass.getMethod(setStudentDao, studentDaoClass);
//setStudentService方法签名,使用类别获取setStudentService方法
Method setServiceMethod = studentActionClass.getMethod(setStudentService, studentServiceClass); //创建StudentDaoImpl对象,相当于new StudentDaoImpl(),但返回的是Object对象
Object studentDaoImplnstance = studentDaoImplClass.newInstance();
//创建StudentServiceImpl对象,相当于new StudentServiceImpl(),但返回的是Object对象
Object studentServiceImplInstance = studentServiceImplClass.newInstance();
//创建StudentAction对象,相当于new StudentAction(),但返回的是Object对象
Object studentActionInstance = studentActionClass.newInstance(); //使用反射机制调用StudentServiceImpl的setStudentDao方法,参数是StudentDaoImpl对象,
//第一个参数是执行方法的类实例,第二个参数是方法参数
setDaoMethod.invoke(studentServiceImplInstance, studentDaoImplnstance);
setServiceMethod.invoke(studentActionInstance, studentServiceImplInstance);
//调用StudentAction的printName方法
((StudentAction)studentActionInstance).printName(); } catch (Exception e) {
e.printStackTrace();
}
}
}

测试结果:

Spring的IOC/DI使用到的技术的更多相关文章

  1. Spring框架-IOC/DI详细学习

    一.IOC/DI概念 参考博客:https://www.cnblogs.com/xdp-gacl/p/4249939.html IOC(inversion of control, 控制反转)是一种设计 ...

  2. Spring框架——IOC&DI

    Spring Spring 目标 内容 Spring与web整合的原理 Spring 中包含的关键特性 Spring架构图 企业级框架 企业级系统 IOCDI IOC DI IOC和DI 为什么使用依 ...

  3. spring的IOC/DI功能实践

    一.写在前面: 做这个Demo主要是为了能够更好的理解Spring的原理,看再多的文章,听再多的讲解最终都最好自己去实现一遍,可以将Spring的功能分块实现,最终自然比较容易将各个功能组合起来. 这 ...

  4. Spring之IOC/DI(反转控制/依赖注入)_入门Demo

    在平时的java应用开发中,我们要实现某一个功能或者说是完成某个业务逻辑时至少需要两个或以上的对象来协作完成,在没有使用Spring的时候,每个对象在需要使用他的合作对象时,自己均要使用像new ob ...

  5. 个人对spring的IOC+DI的封装

    暂时支持8种基本数据类型,String类型,引用类型,List的注入. 核心代码 package day01; import java.lang.reflect.Field;import java.l ...

  6. Spring基础[IOC/DI、AOP]

    一.Spring作用:管理项目中各种业务Bean(service类.Dao类.Action类),实例化类,属性赋值 二.Spring IOC(Inversion of Control )控制反转,也被 ...

  7. Spring理解IOC,DI,AOP作用,概念,理解。

    IOC控制反转:创建实例对象的控制权从代码转换到Spring容器.实际就是在xml中配置.配置对象 实例化对象时,进行强转为自定义类型.默认返回类型是Object强类型. ApplicationCon ...

  8. Spring注解IOC/DI(4)

    2019-03-08/11:10:17 演示:使用注解的方式完成注入对象中的效果 注解参考链接:https://www.cnblogs.com/szlbm/p/5512931.html Spring中 ...

  9. 解释Spring中IOC, DI, AOP

    oc就是控制翻转或是依赖注入.通俗的讲就是如果在什么地方需要一个对象,你自己不用去通过new 生成你需要的对象,而是通过spring的bean工厂为你长生这样一个对象.aop就是面向切面的编程.比如说 ...

随机推荐

  1. CCPC-2017-秦皇岛站

    10月25日 听说信用卡到了好兴奋,然而没有额度是啥情况啊qwq. 晚上坐飞机出发,成都-鄂尔多斯-石家庄-秦皇岛,队友吐槽鄂尔多斯到石家庄好近啊,然后过了一会儿我们因为石家庄大雾迫降在了济南.嘤嘤嘤 ...

  2. 关于esp32的省电模式的WiFi连接

    对于ESP32,其作为一款集成了2.4GHz WiFi和蓝牙双模块的单芯片,所有基于wifi和蓝牙开发是学习esp32的重要一环,今天WiFi原理和网络结构 可以点击链接进行详细的了解,这里就不做详细 ...

  3. 冲刺博客NO.7

    今天做了什么: 在Iconfont-阿里巴巴矢量图标库找了个图标,仍感觉不是很好看. 查询函数遇到了很多困难 困难:不会真机测试,链接USB后 adb没检测到设备(包括真机和虚拟机). 在Termin ...

  4. Vuejs——(10)组件——父子组件通信

    版权声明:出处http://blog.csdn.net/qq20004604   目录(?)[+]   本篇资料来于官方文档: http://cn.vuejs.org/guide/components ...

  5. day_1 Python介绍及计算机组成和系统

    python学习路线 基础语法 - 文件操作 - 函数 - 模块 - 面向对象(类) - 网络编程 - 数据库 - 前段 - 项目 学习方法 wwwh: what-why-where-how #wha ...

  6. Android开发 - 掌握ConstraintLayout(五)偏差(Bias)

    比如实现这样一个场景: "在屏幕宽度的1/4的地方放置一个View" 使用传统布局时,实现按照屏幕的宽度(高度),或者相对两个View之间距离的一个比例来进行布局,就显得非常麻烦, ...

  7. 42_并发编程-JionableQueue

    一.生产者消费者模型   在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程.在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生 ...

  8. 前后端分离开发之前端自己的API(DB)---- (1)

    Creating demo APIs for Front-End Developer 心理准备 Tool-1 开发工具/编辑器:Visual Studio Code , 即 VSCode官网: htt ...

  9. linux/cmd中python路径导入ModuleNotFoundError: No module named 'xxx'

    在linux或者直接在cmd中运行python文件时 会遇到导包错误的情况ModuleNotFoundError: No module named 'xxx’由于不在pycharm中 所以这里不能将上 ...

  10. Python:标准库(包含下载地址及书本目录)

    下载地址 英文版(文字版) 官方文档 The Python Standard Library <Python标准库>一书的目录 <python标准库> 译者序 序 前言 第1章 ...