码迷,mamicode.com
首页 > 编程语言 > 详细

好程序员Java干货分享Spring框架之IOC原理

时间:2019-07-09 16:42:44      阅读:125      评论:0      收藏:0      [点我收藏+]

标签:ret   sys   邮件   实现原理   junit   quartz   简单   软件   inter   

好程序员Java干货分享Spring框架之IOC原理,前言:Spring框架是我们进行企业级开发的最常用框架,本章我们将了解Spring框架,并学习SpringIOC特性以及IOC的实现原理:注解和反射。

Spring框架简介

  Spring是一种轻量级的控制反转(IOC)和面向切面编程(AOP)的容器框架,能够为企业级开发提供一站式服务。

  Spring的优点有

  1.方便解耦,简化开发

  通过Spring提供的IoC容器,我们可以将对象之间的依赖关系交由Spring进行控制,避免硬编码所造成的过度程序耦合。有了Spring,用户不必再为单实例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。

  2.AOP编程的支持

  通过Spring提供的AOP功能,方便进行面向切面的编程,许多不容易用传统OOP实现的功能可以通过AOP轻松应付。

  3.声明式事务的支持

  在Spring中,我们可以从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活地进行事务的管理,提高开发效率和质量。

  4.方便程序的测试

  可以用非容器依赖的编程方式进行几乎所有的测试工作,在Spring里,测试不再是昂贵的操作,而是随手可做的事情。例如:SpringJunit4支持,可以通过注解方便的测试Spring程序。

  5.方便集成各种优秀框架

  Spring不排斥各种优秀的开源框架,相反,Spring可以降低各种框架的使用难度,Spring提供了对各种优秀框架(如Struts,HibernateHessianQuartz)等的直接支持。

  6.降低Java EE API的使用难度

  Spring对很多难用的Java EE API(如JDBCJavaMail,远程调用等)提供了一个薄薄的封装层,通过Spring的简易封装,这些Java EE API的使用难度大为降低。

  

Spring的组成

技术图片

  Spring CoreSpring 框架的核心。Spring其它组件都依赖于核心组件,主要通过BeanFactory提供IOC等服务。

  Spring ContextSprin上下文是一个配置文件,向 Spring框架提供上下文信息。Spring 上下文包括企业服务,例如JNDIEJB、电子邮件、国际化、校验和调度功能。

  Spring AOP:通过配置管理特性,Spring AOP 模块直接将面向切面的编程功能集成到了 Spring 框架中。

  Spring ORMSpring 框架插入了若干个ORM框架,从而提供了 ORM 的对象关系工具,其中包括JDOHibernateiBatisSQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。

  Spring DAO:  DAO抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。

  Spring Web:  Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以,Spring框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。

  Spring Web MVC: web 应用提供了模型视图控制(MVC)和 REST Web 服务的实现。Spring MVC 框架可以使领域模型代码和 web 表单完全地分离,且可以与 Spring 框架的其它所有功能进行集成。

  

IOCDI

  IOCInverse Of Control)是控制反转的意思,作用是降低对象之间的耦合度。

  一般情况下我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而IoC是有专门一个容器来创建这些对象,即由Ioc容器来控制对象的创建;这样就是由容器来控制对象,而不是由我们的对象来控制,这样就完成了控制反转。

  DI(Dependency Injection)即“依赖注入”:是组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系注入到组件之中。依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需要关心具体的资源来自何处,由谁实现。

  

IOC的原理:注解+反射

下面的案例讲解了IOC的原理,模拟为电脑配置不同的CPU和内存,CPUAMDINTEL两种,内存有DDR8GDDR16G两种

  1. /**
  2. * CPU接口
  3. */
  4. public interface Cpu {
  5. void run();
  6. }
  7. /**
  8. * 内存接口
  9. */
  10. public interface Memory {
  11. void read();
  12. void write();
  13. }
  14. /**
  15. * AMDCPU
  16. */
  17. public class AMDCpu implements Cpu {
  18. public void run() {
  19. System.out.println("AMDCPU正在运行....");
  20. }
  21. }
  22. /**
  23. * IntelCPU
  24. */
  25. public class IntelCpu implements Cpu{
  26. public void run() {
  27. System.out.println("IntelCPU正在运行....");
  28. }
  29. }
  30. /**
  31. * DDR8G的内存
  32. */
  33. public class DDR8GMemory implements Memory {
  34. public void read() {
  35. System.out.println("使用DDR8G的内存读取数据....");
  36. }
  37. public void write() {
  38. System.out.println("使用DDR8G的内存写入数据....");
  39. }
  40. }
  41. /**
  42. * DDR16G的内存
  43. */
  44. public class DDR16GMemory implements Memory {
  45. public void read() {
  46. System.out.println("使用DDR16G的内存读取数据....");
  47. }
  48. public void write() {
  49. System.out.println("使用DDR16G的内存写入数据....");
  50. }
  51. }
  52. public class TestComputer {
  53. @Test
  54. public void testComputer(){
  55. //硬编码方式创建对象
  56. Computer computer = new Computer();
  57. Cpu cpu = new IntelCpu();
  58. Memory memory = new DDR16GMemory();
  59. computer.setCpu(cpu);
  60. computer.setMemory(memory);
  61. computer.start();
  62. }
  63. }

 

上面是使用硬编码方式创建电脑的CPU和内存属性,代码和具体的子类紧密耦合,不利于后期的维护和扩展。

修改的思路是:不由让程序主动创建去创建CPU和内存对象,而是通过注解方式标记CPU和内存的类型,使用反射将CPU和内存的对象注入到电脑的属性中。

添加代码:

  1. /**
  2. * 电脑组件的注解
  3. */
  4. @Retention(RetentionPolicy.RUNTIME)
  5. @Target(ElementType.FIELD)
  6. public @interface MyComponent {
  7. /**
  8. * 组件类型
  9. * @return
  10. */
  11. Class componentClass();
  12. }
  13. /**
  14. * 电脑类
  15. */
  16. public class Computer {
  17. @MyComponent(componentClass = IntelCpu.class)
  18. private Cpu cpu;
  19. @MyComponent(componentClass = DDR8GMemory.class)
  20. private Memory memory;
  21. ....}
  22. public class TestComputer {
  23. @Test
  24. public void testComputer(){
  25. //通过反射和注解,将cpumemory属性注入进去
  26. try {
  27. //获得Computer类型
  28. Class<Computer> computerClass = Computer.class;
  29. //创建Computer对象
  30. Computer computer = computerClass.newInstance();
  31. //获得Computer对象的属性
  32. Field[] fields = computerClass.getDeclaredFields();
  33. //遍历属性
  34. for(Field field : fields){
  35. //获得属性上定义的MyComponent注解
  36. MyComponent anno = field.getDeclaredAnnotation(MyComponent.class);
  37. //获得配置的组件类型
  38. Class aClass = anno.componentClass();
  39. //创建该组件的对象
  40. Object comp = aClass.newInstance();
  41. //调用set方法赋值给属性
  42. String name = field.getName();
  43. name = "set" + name.substring(0,1).toUpperCase() + name.substring(1);
  44. //通过方法名和参数类型获得方法
  45. Method method = computerClass.getDeclaredMethod(name, field.getType());
  46. //调用方法
  47. method.invoke(computer,comp);
  48. }
  49. //启动电脑
  50. computer.start();
  51. } catch (Exception e) {
  52. e.printStackTrace();
  53. }
  54. }
  55. }

程序如上面修改后,后期如果需要修改电脑的配置,只需要修改注解配置的类型,就可以注入不同的电脑组件,这样就降低了代码间的耦合性,维护代码变得比较简单。

  @MyComponent(componentClass = AMDCpu.class)

    private Cpu cpu;

 

  @MyComponent(componentClass = DDR16GMemory.class)

   private Memory memory;

 

总结

IOC(控制反转)是Spring最重要的原理,它将创建对象的主动权交给Spring容器,Spring程序只需要进行一些配置,就可以使用不同的对象,极大的降低了代码耦合性,提高了程序的灵活性,IOC的实现原理是反射机制。

好程序员Java干货分享Spring框架之IOC原理

标签:ret   sys   邮件   实现原理   junit   quartz   简单   软件   inter   

原文地址:https://www.cnblogs.com/gcghcxy/p/11158283.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!