java 反射 工厂_JAVA反射机制、工厂模式与SPRING IOC
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相关推荐
- java中的静态、动态代理模式以及Spring中的CgLib动态代理解读(面试必问)
java中的静态.动态代理模式以及Spring中的CgLib动态代理解读(面试必问) 静态代理 动态代理 CgLib动态代理 基础知: 反射知识 代理(Proxy)是一种设计模式,提供了对目标 ...
- java 反射代价_Java反射机制
# 反射 ## 什么是反射 反射是Java提供的动态执行机制, 可以动态加载类, 动态创建对象, 动态访问属性, 动态调用方法.. 静态执行: Java代码经过编译以后就确定的执行次序, 称为静态执行 ...
- Java的反射作用_java反射机制的作用与优点
java的反射机制就是增加程序的灵活性,避免将程序写死到代码里, 例如: 实例化一个 person()对象, 不使用反射, new person(); 如果想变成 实例化 其他类, 那么必须修改源代码 ...
- java 设计模式 路由器_java设计模式2————工厂模式
java设计模式2----工厂模式 1.工厂模式介绍: 1.1.实现了创建者与调用者的分离 1.2.详细分类: 简单工厂模式 工厂方法模式 抽象工厂模式 1.3.所遵循的OOP原则: 开闭原则:对扩展 ...
- java中的工厂_java中的工厂模式
1.工厂模式 java中的工厂模式,个人理解是:要想制作一个汽车,则必须有轮子,发动机,座椅等. 1.创建一个接口,并且使得轮子,发动机,座椅三个实现类实现这个接口. 2.创建一个工厂,生成基于给定信 ...
- java 反射应用_java反射(二)--反射应用案例
一.反射实例化对象 经过一系列的分析之后发现虽然可以获取Class类的实例化对象,但是依然觉得这个对象的获取意义不是很大,因此可以通过以下几个案例去理解反射的核心意义 --反射实例化对象:获取Clas ...
- java反射类型转换_Java反射探索研究(转)
林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankakay 摘要:本文详细深入讲解是Java中反射的机制,并介绍了如何通过反射来生成对象.调用函数.取得 ...
- java 反射练习_JAVA反射的基础学习
反射 :reflection 程序的一种内省机制 程序可以在运行期间动态的创建对象,获取对象类型,调用对象行为 内省机制在java和.net语言中有,在早期的C,C++,delphi,vb这些语言都没 ...
- java反射类型转换_java反射(转)
反射是框架设计的灵魂 (使用的前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码)) 一.反射的概述 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道 ...
最新文章
- matlab的syms无法在函数中使用_Python函数中使用@
- 在JFinal的Controller中接收json数据
- 复制本张表数据并插入本张表中
- C++运算符重载-mfc演示
- 《编译原理》实验预习报告——TINY语言的词法分析
- 服务拆分-案例Demo
- 未能加载文件或程序集rsy3_abp vnext2.0之核心组件模块加载系统源码解析
- .NET建议使用的大小写命名原则
- 带你自学Python系列(一):变量和简单数据类型(附思维导图)
- Uva 11178 Morley's Theorem 向量旋转+求直线交点
- 玩转SpringBoot2.x之缓存对象
- Oracle数据库中IN参数个数超过1000的问题
- spark原理和spark与mapreduce的最大区别
- VMware 配置虚拟机端口映射,实现局域网络互相访问
- ANSYS19.0安装(无比详细的图文示范教程)
- CentOS 安装SVN以及可视化管理工具iF.SVNAdmin
- 开源的魔兽世界参考架构——mangos--网络游戏引擎BigWorld 服务器介绍
- 2020年计算机设计大赛参赛回顾与总结
- 半透明导航栏css代码,纯CSS实现的紫罗兰风格导航条效果代码
- 你缺的不是一个“大牛” 而是一个透视宝