ABSTRACT

Spring的IOC(控制反转)是Spring框架的灵魂,有了它才有了Spring的很多其他的灵活的特性。使用 Spring 开发项目时,控制层、业务层、DAO 层都是通过 IoC 来完成依赖注入的。

IOC其实就是工厂模式+Java的反射机制,所以要理解IOC,我们必须要对工厂模式和反射机制有了解。

什么是IOC

在传统的程序开发中,当需要调用对象时,通常由调用者来创建被调用者的实例,即对象是由调用者主动 new 出来的。

但在 Spring 框架中创建对象的工作不再由调用者来完成,而是交给 IoC 容器来创建,再推送给调用者,整个流程完成反转,因此是控制反转。

反射机制

反射(Reflection)是其Java非常突出的一个动态相关机制。它可以于运行时加载、使用编译期间完全未知的classes(但是要知道类的名字)。也就是说,在运行时,我们还可以获取一个类中所有的方法和属性,可以实例化任何类的对象,还能判断一个对象所属的类。

这样做的好处是,我们在程序运行时才会确定类型绑定对象,而不是在编译时。很多基础框架都用到了Java的这个机制,例如Spring框架、Struct等等,因为这些基础框架往往需要适用于不同的场景,因此对程序的灵活性要求很高,所以动态创建对象、获得类的信息就尤为有用。再比如,一个大型的软件发布后,如果需要更新功能,停止运行然后在重新编译是不现实的,如果利用了java的反射机制,就不需要为了新增加的功能重新编译程序。

反射机制的实现

我们可能之前就有见过反射机制的出现,就是在JDBC中加载数据库驱动时的

Class.forName(“com.mysql.jdbc.Driver”)

如果我们要使用一个类,就要获得这个类的反射类。有三种方法:

1. GETCLASS()方法

所有类的对象都是Class的实例。

String s = “Tomato”;

Class> c = s.getClass();

2. CLASS的静态方法FORNAME

Class> c = Class.forName(“Tomato”);

3. 知道类名,我们可以直接用.CLASS

Class> c = String.class;

实例化一个(构造函数不带参)类的对象:

Object obj = a.newInstance();

实例化一个(构造函数带参)类的对象:

Constructor constructor=c.getConstructor(String.class,int.class);

constructor.newInstance(“Java”,30);

获取对象中的所有方法:

Method[] methods = classType.getDeclaredMethods();

for (int i=0;i

//获取方法名字

String methodName=methods[i].getName();

//获取本方法所有参数类型,存入数组

Class>[] parameterTypes = methods[i].getParameterTypes();

根据方法名用于获取Class类指代对象自己声明的某个方法 getDeclaredMethod();

Method m = c.getDeclaredMethod();

invoke(); 就可以触发方法

m.setAccessible(true);

m.invoke(c);

*不管是public,default,protect还是pricate方法,通过反射类我们都可以自由调用。(但是实际开发中不建议)

获取方法的注解

在Spring中注解扮演着很关键的角色,反射机制也能让我们获取方法的注解

m.getAnnotation(UseCase.class);

工厂模式

工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

使用场景:在我们明确地计划不同条件下创建不同实例时使用,而且通常情况下,客户代码不知道或不需要知道创建的对象是来自哪一个类(由服务提供者决定)。主要解决接口选择的问题。

简单的工厂模式

Shape.java 创建一个Shape接口

public interface Shape {

void draw();

}

三个接口的实体类

Rectangle.java

public class Rectangle implements Shape {

@Override

public void draw() {

System.out.println(“Inside Rectangle::draw() method.”);

}

}

Square.java

public class Square implements Shape {

@Override

public void draw() {

System.out.println(“Inside Square::draw() method.”);

}

}

Circle.java

public class Circle implements Shape {

@Override

public void draw() {

System.out.println(“Inside Circle::draw() method.”);

}

}

工厂类,决定实例化哪一个类的对象

public class ShapeFactory {

//使用 getShape 方法获取形状类型的对象

public Shape getShape(String shapeType){

if(shapeType == null){

return null;

}

if(shapeType.equalsIgnoreCase(“CIRCLE”)){

return new Circle();

} else if(shapeType.equalsIgnoreCase(“RECTANGLE”)){

return new Rectangle();

} else if(shapeType.equalsIgnoreCase(“SQUARE”)){

return new Square();

}

return null;

}

}

这个工厂模式有一个问题是,它的工厂类是静态的,如果我们需要增加产品类别,就必须要添加判断条件,这不符合面对对象的开放封闭原则。当然有其他的设计模式可以解决这个问题,例如工厂方法模式,把工厂类变为抽象类,在它的实现类里实例化对象,然后客户代码中,通过配置文件等来实例化工厂类的实体类。如果利用反射,可以轻松解决这个问题。

在工厂类中,我们提前不知道会需要实现什么类,只有在程序运行时我们才会知道。这就符合了反射机制的特性。

在工厂模式中加入反射机制:

public class ShapeFactory {

public Shape getShape(String ClassName){

if(shapeType == null){

return null;

}

Shape s = null;

try{

s = (Shape)Class.forName(ClassName).newInstance();

}catch (Exception e) {

e.printStackTrace();

}

return s;

}

}

现在就算我们添加任意多个子类的时候,工厂类就不需要修改。当然,简单使用上述代码需要传入完整的包名和反射类名,用户可能并不知道,所以我们通过属性文件的形式配置所需要的子类。(属性文件就不说啦)

说回SPRING中的IOC

在Spring中,是在 spring.xml 中配置 bean 标签,IoC 容器通过加载 bean 标签来创建对象的。

BEAN有两种构造方法:有参构造和无参构造。

无参构造:

有参构造:

如何获得IOC创建的对象呢?

Spring提供了两种方法来获取这个对象:通过ID和运行时类

通过ID:

1.加载 spring.xml 配置文件

ApplicationContext applicationContext = new ClassPathXmlApplicationContext(“spring.xml”);

2.通过 id 值获取对象

Student stu = (Student) applicationContext.getBean(“stu”);

通过运行时类

1.加载 spring.xml 配置文件

ApplicationContext applicationContext = new ClassPathXmlApplicationContext(“spring.xml”);

2.通过运行时类获取对象

Student stu = applicationContext.getBean(Student.class);

System.out.println(stu);

什么是依赖注入?(DI)

依赖注入是将不同对象进行关联的一种方式。

例如创建了一个class对象后,再创建一个student对象,student对象中有一个属性是class,需要绑定刚刚创建的class。此时就需要用到依赖注入。

如有疏漏,欢迎交流!

Reference:

《Java设计模式》Steven John Metsker; William C. Wake

欢迎收藏我的blog:

java 反射 工厂_JAVA反射机制、工厂模式与SPRING IOC相关推荐

  1. java中的静态、动态代理模式以及Spring中的CgLib动态代理解读(面试必问)

    java中的静态.动态代理模式以及Spring中的CgLib动态代理解读(面试必问) 静态代理 动态代理 CgLib动态代理     基础知: 反射知识 代理(Proxy)是一种设计模式,提供了对目标 ...

  2. java 反射代价_Java反射机制

    # 反射 ## 什么是反射 反射是Java提供的动态执行机制, 可以动态加载类, 动态创建对象, 动态访问属性, 动态调用方法.. 静态执行: Java代码经过编译以后就确定的执行次序, 称为静态执行 ...

  3. Java的反射作用_java反射机制的作用与优点

    java的反射机制就是增加程序的灵活性,避免将程序写死到代码里, 例如: 实例化一个 person()对象, 不使用反射, new person(); 如果想变成 实例化 其他类, 那么必须修改源代码 ...

  4. java 设计模式 路由器_java设计模式2————工厂模式

    java设计模式2----工厂模式 1.工厂模式介绍: 1.1.实现了创建者与调用者的分离 1.2.详细分类: 简单工厂模式 工厂方法模式 抽象工厂模式 1.3.所遵循的OOP原则: 开闭原则:对扩展 ...

  5. java中的工厂_java中的工厂模式

    1.工厂模式 java中的工厂模式,个人理解是:要想制作一个汽车,则必须有轮子,发动机,座椅等. 1.创建一个接口,并且使得轮子,发动机,座椅三个实现类实现这个接口. 2.创建一个工厂,生成基于给定信 ...

  6. java 反射应用_java反射(二)--反射应用案例

    一.反射实例化对象 经过一系列的分析之后发现虽然可以获取Class类的实例化对象,但是依然觉得这个对象的获取意义不是很大,因此可以通过以下几个案例去理解反射的核心意义 --反射实例化对象:获取Clas ...

  7. java反射类型转换_Java反射探索研究(转)

    林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankakay 摘要:本文详细深入讲解是Java中反射的机制,并介绍了如何通过反射来生成对象.调用函数.取得 ...

  8. java 反射练习_JAVA反射的基础学习

    反射 :reflection 程序的一种内省机制 程序可以在运行期间动态的创建对象,获取对象类型,调用对象行为 内省机制在java和.net语言中有,在早期的C,C++,delphi,vb这些语言都没 ...

  9. java反射类型转换_java反射(转)

    反射是框架设计的灵魂 (使用的前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码)) 一.反射的概述 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道 ...

最新文章

  1. matlab的syms无法在函数中使用_Python函数中使用@
  2. 在JFinal的Controller中接收json数据
  3. 复制本张表数据并插入本张表中
  4. C++运算符重载-mfc演示
  5. 《编译原理》实验预习报告——TINY语言的词法分析
  6. 服务拆分-案例Demo
  7. 未能加载文件或程序集rsy3_abp vnext2.0之核心组件模块加载系统源码解析
  8. .NET建议使用的大小写命名原则
  9. 带你自学Python系列(一):变量和简单数据类型(附思维导图)
  10. Uva 11178 Morley's Theorem 向量旋转+求直线交点
  11. 玩转SpringBoot2.x之缓存对象
  12. Oracle数据库中IN参数个数超过1000的问题
  13. spark原理和spark与mapreduce的最大区别
  14. VMware 配置虚拟机端口映射,实现局域网络互相访问
  15. ANSYS19.0安装(无比详细的图文示范教程)
  16. CentOS 安装SVN以及可视化管理工具iF.SVNAdmin
  17. 开源的魔兽世界参考架构——mangos--网络游戏引擎BigWorld 服务器介绍
  18. 2020年计算机设计大赛参赛回顾与总结
  19. 半透明导航栏css代码,纯CSS实现的紫罗兰风格导航条效果代码
  20. 你缺的不是一个“大牛” 而是一个透视宝

热门文章

  1. 说好的敬畏每一行代码呢?Antd代码彩蛋炸翻一圈人
  2. 寄Android开发Gradle你需要知道的知识
  3. Apache支持多端口配置处理
  4. 初心大陆-----python宝典之以外学习对比去重
  5. 大学生应该学习python和linux而不是matlab和windows
  6. Java 设计模式 之 中介者模式(Mediator)
  7. (转)iPhone wifi使用socket连接Internet
  8. SQL查询所有客人的第一次用餐时间
  9. [周年感悟]看软件项目中的四种角色
  10. 如何识别AWARD的BIOS-ID