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);