Spring簡介
Spring不是服務于開發web專案的功能,或業務,而是服務于專案的開發,方便各層間的解耦呼叫,方便對類的批量管理,是提高軟體開發效率,降低后期維護成本的框架,
Spring的核心思想是IOC(控制反轉),AOP(切面編程)兩點,
IOC:即不再需要程式員去顯式地`new`一個物件,而是把Spring框架把框架創建出的物件拿來用,因為是spring框架創建的物件,物件都在spring框架物件中保存,亦稱為spring容器,這樣spring就知道當前專案中都創建了哪些物件,這個物件歸屬于那一層,該如何管理,想使用spring的其他功能第一點就是要用spring的物件,也稱為將控制權交給spring管理,
AOP:對某種路徑下的所有類,或有共同特性的類或方法統一管理,在原任務執行的前后,加入新功能,做出監控,初始化,整理,銷毀等一系列統一的伴隨動作,
如果你從事Java編程有一段時間了, 那么你或許會發現(可能你也實際使用過) 很多框架通過強迫應用繼承它們的類或實作它們的介面從而導致應用與框架綁死,這種侵入式的編程方式在早期版本的Struts以及無數其他的Java規范和框架中都能看到,Spring竭力避免因自身的API而弄亂你的應用代碼,Spring不會強迫你實作Spring規范的介面或繼承Spring規范的類,相反,在基于Spring構建的應用中,它的類通常沒有任何痕跡表明你使用了Spring, 最壞的場景是, 一個類或許會使用Spring注解, 但它依舊是POJO,
任何一個有實際意義的應用(肯定比Hello World示例更復雜) 都會由兩個或者更多的類組成, 這些類相互之間進行協作來完成特定的業務邏輯, 按照傳統的做法, 每個物件負責管理與自己相互協作的物件(即它所依賴的物件) 的參考, 這將會導致高度耦合和難以測驗的代碼,
IOC宣告Bean
首先創建的Maven Poject,詳細包結構如下

其中AOP會在下一篇進行講解;
Controller_.java
/** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub response.getWriter().append("Served at: ").append(request.getContextPath()); ClassPathXmlApplicationContext ctx=new ClassPathXmlApplicationContext("/ApplicationContext.xml"); Service_ s = (Service_) ctx.getBean("service_Impl1_new"); System.out.println(s); s.show(); }
由于Spring無法單獨演示,所以Controller_.java是創建的是一個Servlet,直接呼叫doPost或者doGet方法,進行Service的實作,輸出Service_物件s,執行show方法,
Service_.java
public interface Service_ { public void show(); }
創建一個Service介面,用來實作Spring,
1.無參構造方法宣告bean
Service_Impl1.java
public class Service_Impl1 implements Service_{ public Service_Impl1() { // TODO Auto-generated constructor stub System.out.println("service1-無參構造方法"); } @Override public void show() { // TODO Auto-generated method stub System.out.println("Service_Impl1"); } }
重寫Service_的show方法輸出實作了Service_Impl1,撰寫無參構造方法,
ApplicationContext.xml
<!-- 默認構造方法 -->
<bean id="service_Impl1" class="com.zy.spring.service.serviceimpl.Service_Impl1"></bean>
只需要設定id與class,class對應Service_Impl1,id則是Controller_.java呼叫的getBean中的引數,運行結果見自定義構造方法注入bean
2.自定義構造方法宣告bean
Service_Impl2.java
public class Service_Impl2 implements Service_{ public Service_Impl2(int a) { // TODO Auto-generated constructor stub System.out.println("service2-自定義構造引數:"+a); } @Override public void show() { // TODO Auto-generated method stub System.out.println("Service_Impl2"); } }
ApplicationContext.xml
<!-- 自定義構造方法 -->
<bean id="service_Impl2" class="com.zy.spring.service.serviceimpl.Service_Impl2">
<constructor-arg index="0" value="https://www.cnblogs.com/zhangyuan1024/p/1024"></constructor-arg>
</bean>
<constructor-arg index="0" value="https://www.cnblogs.com/zhangyuan1024/p/1024"></constructor-arg>這是構造方法中引數的設定,index顧名思義就是索引的意思,其中a引數是第0個,value是引數的值,

3.單實體 懶加載宣告bean
Service_Impl3.java
public class Service_Impl3 implements Service_{ public Service_Impl3() { // TODO Auto-generated constructor stub System.out.println("service3-懶加載 單實體"); } @Override public void show() { // TODO Auto-generated method stub System.out.println("Service_Impl3"); } }
ApplicationContext.xml
<!-- 單實體 懶加載 -->
<bean id="service_Impl3" class="com.zy.spring.service.serviceimpl.Service_Impl3" lazy-init="true" scope="singleton"></bean>
lazy-init="true" 設定懶加載,也就是呼叫的時候才會加載bean,不會自動加載;scope="singleton" 作用域標簽,單實體也就是只創建一個實體,

4.引數參考宣告bean
Service_Impl4.java
public class Service_Impl4 implements Service_{ Service_ s3; public Service_ getS3() { return s3; } public void setS3(Service_ s3) { this.s3 = s3; } public Service_Impl4() { // TODO Auto-generated constructor stub System.out.println("service4-引數參考bean"); } @Override public void show() { // TODO Auto-generated method stub System.out.println("Service_Impl4"); } }
ApplicationContext.xml
<!-- 引數參考bean -->
<bean id="service_Impl4" class="com.zy.spring.service.serviceimpl.Service_Impl4">
<property name="s3" ref="service_Impl3"></property>
</bean>
<property name="s3" ref="service_Impl3"></property> 引數標簽,name是Service_Impl4中的引數s3,ref鏈接要參考的bean,
5.初始化屬性宣告bean
Service_Impl5.java
public class Service_Impl5 implements Service_{ String name; ArrayList<String> list; HashMap<String, String> map; HashSet<Integer> set; @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((list == null) ? 0 : list.hashCode()); result = prime * result + ((map == null) ? 0 : map.hashCode()); result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + ((set == null) ? 0 : set.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Service_Impl5 other = (Service_Impl5) obj; if (list == null) { if (other.list != null) return false; } else if (!list.equals(other.list)) return false; if (map == null) { if (other.map != null) return false; } else if (!map.equals(other.map)) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; if (set == null) { if (other.set != null) return false; } else if (!set.equals(other.set)) return false; return true; } @Override public String toString() { return "Service_Impl5 [name=" + name + ", list=" + list + ", map=" + map + ", set=" + set + "]"; } public String getName() { return name; } public void setName(String name) { this.name = name; } public ArrayList<String> getList() { return list; } public void setList(ArrayList<String> list) { this.list = list; } public HashMap<String, String> getMap() { return map; } public void setMap(HashMap<String, String> map) { this.map = map; } public HashSet<Integer> getSet() { return set; } public void setSet(HashSet<Integer> set) { this.set = set; } public Service_Impl5() { // TODO Auto-generated constructor stub System.out.println("service5-初始化屬性"); } @Override public void show() { // TODO Auto-generated method stub System.out.println("Service_Impl5"); } }
其中初始化引數有list,map,set以及普通引數,重寫了hashCode和equals方法,詳見HashMap記憶體泄漏;重寫toString方法用來輸出初始化屬性,
ApplicationContext.xml
<!-- 初始化屬性 -->
<bean id="service_Impl5" class="com.zy.spring.service.serviceimpl.Service_Impl5">
<property name="name" value="https://www.cnblogs.com/zhangyuan1024/p/zy"></property>
<property name="map">
<map>
<entry key="AAA" value="https://www.cnblogs.com/zhangyuan1024/p/aaa"></entry>
<entry key="BBB" value="https://www.cnblogs.com/zhangyuan1024/p/bbb"></entry>
</map>
</property>
<property name="list">
<list>
<value type="java.lang.String">QQQ</value>
<value type="java.lang.String">WWW</value>
</list>
</property>
<property name="set">
<set>
<value type="java.lang.Integer">111</value>
<value type="java.lang.Integer">222</value>
</set>
</property>
</bean>
其中map標簽內使用<entry key="AAA" value="https://www.cnblogs.com/zhangyuan1024/p/aaa"></entry>進行賦值,其他的正常使用property和value進行賦值,

6.初始化屬性參考方法回傳值宣告bean
Service_Impl6.java
public class Service_Impl6 implements Service_{ String s5_toString; public String getS5_toString() { return s5_toString; } public void setS5_toString(String s5_toString) { this.s5_toString = s5_toString; } public Service_Impl6() { // TODO Auto-generated constructor stub System.out.println("service6-呼叫方法回傳值"); } @Override public void show() { // TODO Auto-generated method stub System.out.println("Service_Impl6 回傳值"+s5_toString); } }
其中呼叫了Service_Impl5的toString方法并且進行了輸出,
ApplicationContext.xml
<!-- 呼叫方法回傳值 -->
<bean id="service_Impl6" class="com.zy.spring.service.serviceimpl.Service_Impl6">
<property name="s5_toString">
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="service_Impl5"></property>
<property name="targetMethod" value="https://www.cnblogs.com/zhangyuan1024/p/toString"></property>
</bean>
</property>
</bean>
<bean >固定用來宣告呼叫方法回傳值,
targetObject——目標的bean
targetMethod——目標的方法

7.靜態工廠——宣告工廠bean
Service_Impl7.java
public class Service_Impl7 implements Service_{ public static Service_ StaticFactory(int num) { switch (num) { case 1: return new Service_Impl1(); case 2: return new Service_Impl2(100); case 3: return new Service_Impl3(); case 4: return new Service_Impl4(); case 5: return new Service_Impl5(); default: return new Service_Impl6(); } } public Service_Impl7() { // TODO Auto-generated constructor stub System.out.println("service7-靜態工廠"); } @Override public void show() { // TODO Auto-generated method stub System.out.println("Service_Impl7"); } }
工廠在實作類中使用了switch陳述句進行模擬,靜態工廠在方法前加上static關鍵字,分別呼叫上面的其他實作類方法,
ApplicationContext.xml
<!-- 靜態工廠 -->
<bean id="service_Impl7" class="com.zy.spring.service.serviceimpl.Service_Impl7" factory-method="StaticFactory" >
<constructor-arg name="num" value="https://www.cnblogs.com/zhangyuan1024/p/2"></constructor-arg>
</bean>
使用構造方法注入的方法來賦值<constructor-arg name="num" value="https://www.cnblogs.com/zhangyuan1024/p/2"></constructor-arg> ;factory-method="StaticFactory" ( factory-method工廠的方法名)

8.實體工廠——宣告工廠bean
Service_Impl8.java
public class Service_Impl8 implements Service_{ public Service_ factory1(int num) { switch (num) { case 1: return new Service_Impl1(); case 2: return new Service_Impl2(100); case 3: return new Service_Impl3(); case 4: return new Service_Impl4(); case 5: return new Service_Impl5(); default: return new Service_Impl6(); } } public Service_Impl8() { // TODO Auto-generated constructor stub System.out.println("service8-實體工廠"); } @Override public void show() { // TODO Auto-generated method stub System.out.println("Service_Impl8"); } }
ApplicationContext.xml
<!-- 實體工廠 -->
<bean id="service_Impl8" class="com.zy.spring.service.serviceimpl.Service_Impl8" >
</bean>
<bean id="service_Impl8_new" factory-bean="service_Impl8" factory-method="factory1">
<constructor-arg name="num" value="https://www.cnblogs.com/zhangyuan1024/p/2"></constructor-arg>
</bean>
創建實體工廠bean,首先創建一個實體工廠的bean,然后再創建一個工廠方法的bean去呼叫工廠的bean,
呼叫的時候要呼叫工廠方法的bean,這里就要呼叫service_Impl8_new
9.注解宣告bean
@Service:用于標注業務層組件
@Controller:用于標注控制層組件(如struts中的action)
@Repository:用于標注資料訪問組件,即DAO組件
@Component(value="https://www.cnblogs.com/zhangyuan1024/p/*"):泛指組件,當組件不好歸類的時候,我們可以使用這個注解進行標注
Service_Impl9.java
@Service public class Service_Impl9 implements Service_{ public Service_Impl9() { // TODO Auto-generated constructor stub System.out.println("service9-注解注入bean"); } @Override public void show() { // TODO Auto-generated method stub System.out.println("Service_Impl9"); } }
@Service進行bean的宣告(注解只能宣告無參構造方法),使用注解默認宣告的bean是類名的首字母小寫,這里宣告的bean的id應該是service_Impl9,
ApplicationContext.xml
<!-- 注解掃描IOC根目錄 -->
<context:component-scan base-package="com.zy.spring">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/><!-- 掃描不包括controller -->
</context:component-scan>
使用注解需要加上注解掃描,其中base-package是掃描的目錄,一般使用的是專案的根目錄,以后使用SpringMVC的話,就不用掃描Controller,

注解寫入bean
@Resource(name="*" type="*")bean寫入
@Autowired/@Qualifier
@inject/@named
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/32391.html
標籤:架構設計
上一篇:分布式事物之綜合案例分析
