學框架不學spring都很差意思跟別人說本身懂框架,並且如今好多java方面的工做要求熟練spring/myBaits等主流框架,本身學 spring也有一段時間了,作一篇博客整理下本身的思路,技術嗎,不沉澱下來終究沒法轉化成本身的東西,之因此寫的通俗一點,權且是對本身渣比的調侃吧。java
從spring的兩大思想開始:1.IOC; 2.AOPspring
IOC(inversion of control),控制反轉,這裏的控制是指控制對象的建立,衆所周知,java中是經過new關鍵字來建立對象的,有些僅僅使用一次的對象反覆建立,造 成了資源的浪費,若是將對象的建立交付給容器,不只能省去大量資源使對象複用,更能省去某些麻煩(反覆new對象形成的麻煩應該不僅資源浪費,猜想)。個 人感受,設計模式的重要想法就是專門弄一項技術來處理某些專門的需求,正是對象資源的管理催生了ioc,將對象管理交給容器來管理,須要對象時候從容器裏 面拿一個就好,是否是很方便,哈哈。所謂容器,實現起來就是由jvm建立和管理一塊專門放對象的內存,容器的啓動,初始化,銷燬特性歸納起來就是生命周 期,spring正是在容器的生命週期內完成對象的管理的。下面是new對象方式和ioc方式處理對象的對照:編程
public class Car{ public car(){ //汽車初始化時候也要初始化發動機 Egnine eg=new Egnine(); } } //使用時候 Car car=new Car();
使用ioc方式,把對象的關係寫在xml文件中,這樣汽車一初始化的時候,引擎也隨之初始化,就是把它們的建立關係寫在另一個擅長邏輯關係管理的文件中,這種文件名字叫xml.
這樣作的另一個好處就是,若是一個car須要兩個引擎,把xml改掉以後原來代碼照樣跑,有個高大上的名字叫-解耦,須要什麼在bean的配置文件裏面嵌套一些bean做爲參數,這種
方式稱之爲注入.
Step 1
<bean id="Car" class="cn.usct.Car">
<constructor-arg ref="eg"></constructor-arg>
</bean>
<bean id="eg" class="cn.usct.Egnine"></bean>
Car和Egnine的代碼照常(ioc只提供對象管理,但對象是什麼樣子仍是靠.java文件裏的類)
Step 2
Car c=ApplicationContext.get("Car");
spring3和spring2.5的一大區別就是經過id的getBean()方法還須要用a.class做爲第二個參數設計模式
第一個spring使用:數組
1.建立項目,導入jar包,項目結構:「src」用於存放java文件;「lib」用於存放jar文件;「resources」用於存放配置文件框架
2.寫接口和實現類dom
3.jvm
- ApplicationContext context = new ClassPathXmlApplicationContext("helloworld.xml");
-
- HelloApi helloApi = context.getBean("hello", HelloApi.class);
-
- helloApi.sayHello();
最經常使用API:Object getBean(String name) 根據名稱返回一個Bean,客戶端須要本身進行類型轉換;ide
二,獲取bean的方式(四種)測試
id,類(car.class),名字+類
三,實例化
1.<constructor-args index="0" value="hello!"/> 爲一個參數的構造方法提供了字符串類型參數
2.普通工廠實例化
- package cn.javass.spring.chapter2;
- public class HelloApiInstanceFactory {
- public HelloApi newInstance(String message) {
- return new HelloImpl2(message);
- }
- }
xml
- <!—1、定義實例工廠Bean -->
- <bean id="beanInstanceFactory"
- class="cn.javass.spring.chapter2.HelloApiInstanceFactory"/>
- <!—2、使用實例工廠Bean建立Bean -->
- <bean id="bean4"
- factory-bean="beanInstanceFactory"
- factory-method="newInstance">
- <constructor-arg index="0" value="Hello Spring!"></constructor-arg>
- </bean>
測試代碼
- BeanFactory beanFactory =
- new ClassPathXmlApplicationContext("chapter2/instantiatingBean.xml");
- HelloApi bean4 = beanFactory.getBean("bean4", HelloApi.class);
- bean4.sayHello();
四,注入
1.
構造方法注入:index,name,type
- <!-- 經過構造器參數索引方式依賴注入 -->
- <bean id="byIndex" class="cn.javass.spring.chapter3.HelloImpl3">
- <constructor-arg index="0" value="Hello World!"/>
- <constructor-arg index="1" value="1"/>
- </bean>
- <!-- 經過構造器參數類型方式依賴注入 -->
- <bean id="byType" class="cn.javass.spring.chapter3.HelloImpl3">
- <constructor-arg type="java.lang.String" value="Hello World!"/>
- <constructor-arg type="int" value="2"/>
- </bean>
- <!-- 經過構造器參數名稱方式依賴注入 -->
- <bean id="byName" class="cn.javass.spring.chapter3.HelloImpl3">
- <constructor-arg name="message" value="Hello World!"/>
- <constructor-arg name="index" value="3"/>
- </bean>
不建議使用name注入
2.
2.1注入普通屬性
setter方法注入
1.類文件
- package cn.javass.spring.chapter3;
- import cn.javass.spring.chapter2.helloworld.HelloApi;
- public class HelloImpl4 implements HelloApi {
- private String message;
- private int index;
- public void setMessage(String message) {
- this.message = message;
- }
- public void setIndex(int index) {
- this.index = index;
- }
- @Override
- public void sayHello() {
- System.out.println(index + ":" + message);
- }
- }
2.配置bean,主要是property
- <!-- 經過setter方式進行依賴注入 -->
- <bean id="bean" class="cn.javass.spring.chapter3.HelloImpl4">
- <property name="message" value="Hello World!"/>
- <property name="index">
- <value>1</value>
- </property>
- </bean>
2.2注入集合
1類
- package cn.javass.spring.chapter3.bean;
- import java.util.List;
- public class ListTestBean {
- private List<String> values;
- public List<String> getValues() {
- return values;
- }
- public void setValues(List<String> values) {
- this.values = values;
- }
- }
2注入
- <bean id="listBean" class="cn.javass.spring.chapter3.bean.ListTestBean">
- <property name="values">
- <list>
- <value>1</value>
- <value>2</value>
- <value>3</value>
- </list>
- </property>
- </bean>
3測試
- @Test
- public void testListInject() {
- BeanFactory beanFactory =
- new ClassPathXmlApplicationContext("chapter3/listInject.xml");
- ListTestBean listBean = beanFactory.getBean("listBean", ListTestBean.class);
- System.out.println(listBean.getValues().size());
- Assert.assertEquals(3, listBean.getValues().size());
- }
Assert.assertEquals();方法判斷先後兩個值是否相等
set集合類型與之相同
3
注入其餘bean
- <bean id="bean2" class="cn.javass.spring.chapter3.bean.HelloApiDecorator">
- <property name="helloApi"><ref bean=" helloApi"/></property>
- </bean>
注入總結
1、構造器注入:
1)常量值
簡寫:<constructor-arg index="0" value="常量"/>
全寫:<constructor-arg index="0"><value>常量</value></constructor-arg>
2)引用
簡寫:<constructor-arg index="0" ref="引用"/>
全寫:<constructor-arg index="0"><ref bean="引用"/></constructor-arg>
2、setter注入:
1)常量值
簡寫:<property name="message" value="常量"/>
全寫:<property name="message"><value>常量</value></ property>
2)引用
簡寫:<property name="message" ref="引用"/>
全寫:<property name="message"><ref bean="引用"/></ property>
3)數組:<array>沒有簡寫形式
4)列表:<list>沒有簡寫形式
5)集合:<set>沒有簡寫形式
6)字典
簡寫:<map>
<entry key="鍵常量" value="值常量"/>
<entry key-ref="鍵引用" value-ref="值引用"/>
</map>
全寫:<map>
<entry><key><value>鍵常量</value></key><value>值常量</value></entry>
<entry><key><ref bean="鍵引用"/></key><ref bean="值引用"/></entry>
</map>
7)Properties:沒有簡寫形式
ps:null值注入
<property name="name"></null></>
(原理篇)
還有一個問題,ioc是如何實現的?
個人理解是依靠反射,基於dom解析器的解析原理,當讀到一個id時候,按照符合ioc的dtd,class裏面理應是這個bean的實現類,本質上仍是經過new來建立而且返回,只是spring默認的是單例模式,那麼建立以前先加判斷 if(instance==null){建立}