Spring IoC(控制反转)【IoC的技术基础】

IoC的底层是使用Java的反射机制和JavaBean自省机制实现的。


反射技术

反射是Java语言的特性之一, 让Java程序在运行时动态地执行类的方法、构造方法等。

创建Demo类:

public class Demo{
	public static Object invoke(String className,String methodName,Object[] args){
	}
}

上述代码中的Demo类定义了invoke方法,该方法定义了三个参数,分别是类名、方法名、方法的参数,

invoke方法有一个Object类型的返回值。

invoke方法需要实现的功能是:

通过类名,调用该类中指定名字的方法,将参数传递给该方法,并将方法的返回值返回。


要实现这样的功能,就需要使用Java的反射机制,以便能够通过类名、方法名等这样的类基本信息,实例化类并调用方法。


反射API中常用的类:

1、Class

①Class<?> forName(String className):该方法获得名字为className的类的Class实例。

②public Method[] getMethods():该方法返回该Class实例的所有方法对象,封装为Method[]对象。

③Constructor[] getConstructors():该方法返回该Class实例的所有构造方法对象,封装为Constructor[]对象。

2、Method类

Method类表示方法,将类的方法封装成对象。其中常用的方法有:

①Object invoke(Object obj,Object...args):该方法能够调用obj实例的方法,方法参数为args。

②public String getName():该方法能够返回方法的名字。

3、Constructor

Constructor类表示构造方法,将类的构造方法封装成对象,其中常用的方法有:

newInstance(Object...initargs):通过参数构造类的实例。


使用反射机制完成Demo中的invoke方法,如下:

package test;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;



public class Demo {

	public static Object invoke(String className,String methodName,Object[] args){
		Object obj=null;
		try{
			Class clazz=Class.forName(className);
			Method[] methods=clazz.getMethods();
			for(Method m:methods){
				if(m.getName().equals(methodName)){
					obj=m.invoke(clazz.newInstance(),args);
				}
			}
		}catch(ClassNotFoundException e){
			e.printStackTrace();
		}catch(IllegalArgumentException e){
			e.printStackTrace();
		}catch(IllegalAccessException e){
			e.printStackTrace();
		}catch(InvocationTargetException e){
			e.printStackTrace();
		}catch(InstantiationException e){
			e.printStackTrace();
		}
		return obj;
	}
	public static void main(String[] args) {
		System.out.println(Demo.invoke("test.Calculator", "div", new Integer[]{100,12}));
		System.out.println(Demo.invoke("test.Calculator", "add", new Integer[]{100,12}));
	}

}

上述代码中,使用反设机制实现了invoke方法。

首先使用Class.forName方法根据类名返回该类的Class实例,

接下来使用Class实例的getMethods方法返回类中所有方法对应的Method实例,

最后使用invoke方法调用了指定名字的Method。


Calculator类:

package test;

	public class Calculator {
		public int add(int i,int j){
			return (i+j);
		}
		
		public int div(int i,int j){
			return (i/j);
		}
	}

运行结果:

8
112
invoke方法可以动态调用任何类的任何方法,并返回方法的返回值,如果不使用Java的反射机制,将无法实现这样动态获得类信息的功能。


JavaBean自省技术

JavaBean是遵守一定命名规范的类,往往使用getter/setter方法获取或者设置属性的值。

JavaBean的自省机制可以再不知道JavaBean有哪些属性的情况下设置它们的值。


自省机制的核心是前面提到的反射机制。JavaBean的自省机制主要由Introspector实现,该接口中提供了如下的关键方法:

BeanInfo getBeanInfo(Classs<?> beanClass):该方法通过JavaBean的Class实例返回JavaBean的信息,封装到BeanInfo类型的实例返回。

getBeanInfo方法的返回值是BeanInfo类型,BeanInfo中提供了如下所示的一系列方法,能够进一步得到JavaBean的信息:

①BeanDescriptor getBeanDescriptor():获得Bean的描述信息。

②MethodDescriptor[] getMethodDescriptors():获得Bean的方法信息。

③PropertyDescriptor[] getPropertyDescriptors():获得Bean的属性信息。


使用实例展示JavaBean自省机制的含义和作用。

创建JavaBean类Course:

package vo;

public class Course {

	private Integer id;
	private String title;
	private double price;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public double getPrice() {
		return price;
	}
	public void setPrice(double price) {
		this.price = price;
	}
	
}

上述代码中的Course类是一个JavaBean类,声明了三个属性,并为每个属性都定义了getter和setter方法。

使用如下代码测试:

	public static void main(String[] args) throws IntrospectionException {
		BeanInfo info =Introspector.getBeanInfo(Course.class);
		for(PropertyDescriptor pd:info.getPropertyDescriptors()){
			System.out.println(pd.getName());
		}
	}
测试结果输出如下:

class
id
price
title

可见,使用JavaBean自省机制,可以在只知道类名的情况下获取JavaBean的属性等信息,进一步使用反射机制,就可以对属性进行赋值等操作。


Spring的IoC机制,正是基于Java反射和JavaBean自行机制实现的。

Spring框架在applicationContext.xml中定义了bean的名字、类的名字、属性名字、属性值等信息,

IoC容器通过反射和自省机制能够根据这些信息对bean进行实例化以及装配操作,从而得到一个完整的bean实例,供应用使用。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值