1. 程式人生 > >spring整理:(一)Ioc和DI思想

spring整理:(一)Ioc和DI思想

正控:若呼叫者需要使用某個物件,其自身就得負責該物件及該物件所依賴物件的建立和組裝

反控:呼叫得只管理從Spring容器中獲取需要使用的物件,不關心物件的建立過程,也不關心該物件依賴物件的建立及依賴關係的組裝,也就是把建立物件的控制權反轉給了Spring框架。

Ioc:Inversion of Control(控制反轉/反轉控制),這不是什麼新技術,而是一種設計思想,好比如MVC,其本意是將原本在程式中手動建立物件的控制,交由Spring框架來管理

DI:Dependency Injecttion(依賴注入)從字面上分析,Ioc指將物件的建立權反轉給了Spring容器;即指Spring建立物件的過程中,將物件依賴屬性(常量,物件,集合)通過配置設值給該物件

例子:

實體類:

public class HelloWorld{
    private String name;
    private int age;
   ...相應的get和set方法
}

XML配置:

<bean id="helloWorld" class="com.bigfong.HelloWorld">
  <property name="name" value="bigfong">對應HelloWorld中的setName方法
   <property name="age" value="20">對應HelloWorld中的setAge方法
</bean>

測試程式碼:

HelloWorld helloWorld = null;
//載入Spring配置檔案applicationContext.xml
Resource resource = new ClassPathResource("applicationContext.xml");
//建立Spring容器物件
BeanFactory factory = new XmlBeanFactory(resource);
//從Spring容器中獲取制定名為helloWorld的bean
helloWorld = (HelloWorld)factory.getBean("helloWorld");//xml對應bean配置的id值
helloWorld.sayHello();

BeanFactory是Spring最古老的介面,表示Spring Ioc容器------生產bean物件的工廠,負責配置,建立和管理bean,被Spring Ioc容器管理的物件稱之為bean

Spring Ioc容器如何得知哪些是它管理的物件:

  此時需要配置檔案,Spring Ioc容器通過讀取配置檔案中的配置元資料,通過元資料對應用中的各個物件進行例項化及裝配

Spring Ioc管理bean的原理:

1.通過Resource物件載入配置檔案

2.解析配置檔案,得到指定名稱的bean

3.解析bean元素,id作為bean的名字,class用於反射得到bean的例項;(此時,bean類必須存在一個無參構造器【和訪問許可權無關】);

4.呼叫getBean方法的時候,從容器中返回物件例項

結論:就是把程式碼從java檔案中轉移到了XML中

模擬Spring Ioc容器操作

HelloWorld helloWorld = null;
String className = "com.bigfong.HelloWorld";
Class clz = Class.forName(className);
Constructor con = clz.getDeclaredConstructor();
con.setAccessible(true);
helloWorld = (HelloWorld)con.newInstance();
BeanInfo beanInfo = Introspector.getBeanInfo(helloWorld.getClass());
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();

for(PropertyDescriptor pd:pds){
   String propertyName = pd.getName();
   Method setterMethod = pd.getWriteMethod();
   if("name".equals(propertyName)){
     setterMethod.invoke(helloWorld,"bigfong");
   }elseif("age".equals(propertyName)){
     setterMethod.invoke(helloWorld,20);
   }
}

helloWorld.sayHello();

getBean方法的三種簽名

1.按照bean的名字拿bean

    helloWorld = (HelloWorld)factory.getBean("helloWorld");

2.按照型別拿bean,要求在Spring中只配置一個這種型別的例項

   helloWorld = (HelloWorld)factory.getBean(HelloWorld.class);

3.按照名字和型別拿bean(推薦)

   helloWorld = (HelloWorld)factory.getBean("helloWorld",HelloWorld.class);