前言:
正文:
<pre name="code" class="java">public class A {
public void getMethod(){
B b = new B();
b.eat();
}
public void getMethod1(){
B b = new B();
b.eat();
}
public void getMethod2(){
B b = new B();
b.eat();
}
public void getMethod3(){
B b = new B();
b.eat();
}
}
B类
public class B {
public String eat(){
return "aaaa";
};
}
从上面的代码片我们不难看的出,上面是在不使用ioc的情况下,A类中的方法调用B类中的eat()方法,需要new一个B对象出来调用;这是一次调用,我们来联想一个场景,如果B中的这个方法在很多类中都被调用了,那是不是每次都要A主动地new一次B对象才能进行调用,这样的话得new多少次;而通过ioc就方便多了,无论你A类中需要调用多少次的不需要你主动地去new多少个B类,只需要把这个B类加入到bean容器中管理,spring会在A需要的时候主动给你new一个B然后调用方法,这样是不是省去了很多new,也方便了;实现ioc的方式有两种,一种是在xml文件中配置bean,那些类是要加入bean中管理的就手动加进去;另外一种就是注解,只要在你申明的那个类上加制定注解就可以了;
看下代码:
import org.springframework.beans.factory.annotation.Autowired;
public class A {
@Autowired
private B b;
public void getMethod(){
b.eat();
}
public void getMethod1(){
b.eat();
}
public void getMethod2(){
b.eat();
}
public void getMethod3(){
b.eat();
}
}
B类:
public class B {
public String eat(){
return "aaaa";
};
}
好了,现在我们知道了控制反转是什么意思了,那在来看看控制反转是怎么实现的呢;我们有就得认识一个新词,DI:依赖注入;就比如说我上面代码片中的那个在声明B上面的@Autowired注解;要知道注解的的实现过程就得知道java中的一个功能,反射;
反射在我们通常的编码情况下不是经常用到;什么是反射呢,简单来讲,就是有一个类,你只知道类名,里面到底有什么你不知道,然后可以通过一些方法你可以动态获取
这个类中的所有方法和属性,就结束了;是怎么实现的呢,现在我们有个类C,先是根据forName("C的路径")或者是C.getClass()来取到C的实例,假如得到的实例叫c1,然后通过c1.getDeclaredMethods();来获取到所有的方法,返回的是个数组;通过c1.getDeclaredFields();获取到所有属性;
下面来看下这段代码:
首先有个未知的类C:
public class C {
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "C [age=" + age + ", name=" + name + ", getAge()=" + getAge()
+ ", getName()=" + getName() + ", getClass()=" + getClass()
+ ", hashCode()=" + hashCode() + ", toString()="
+ super.toString() + "]";
}
}
然后在写个TestC类来取出C类中的属性和方法:
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class TestC {
public static void main(String[] args) {
C c = new C();
Class<? extends Object> c1 = c.getClass();//取得class对象
Method[] method=c1.getDeclaredMethods();//获取对象中的方法
for(Method m : method){
System.out.println("C中的方法有:"+m.toString());
}
Field[] field=c1.getDeclaredFields();
for(Field f : field){
System.out.println("C中的属性有:"+f.toString());
}
}
}
下面是打印出的结果:
C中的方法有:public java.lang.String com.yoho.controller.C.toString()
C中的方法有:public java.lang.String com.yoho.controller.C.getName()
C中的方法有:public void com.yoho.controller.C.setName(java.lang.String)
C中的方法有:public int com.yoho.controller.C.getAge()
C中的方法有:public void com.yoho.controller.C.setAge(int)
C中的属性有:private int com.yoho.controller.C.age
C中的属性有:private java.lang.String com.yoho.controller.C.name
这样是不是就能直观的看出来了,C中的两个属性和set,get,tostring方法都被打出来了;
行了,反射讲清楚后,那注解就很容易理解了,上面那个@Autowried注解就是类似这样实现的,通过取到注解可以取到类名,或者是类对象类型,这边插个题外话,一般实现装箱的注解@Autowried和@Resource两个都可以,前者是按类型,后者是按名称;好了回归正题,通过取到类名后,就通过反射把这个类中的所有方法都取出来,当然肯定不是像我上面打印出来,而是通过加入到spring的bean容器中管理,然后在有需要用的时候spring就会自动给你提供;