javascript
Spring基础知识及入门
---恢復內容開始---
1?spring框架概述
1.1?什么是spring
? ?Spring是一個開源框架,Spring是于2003?年興起的一個輕量級的Java?開發框架,由Rod?Johnson?在其著作Expert?One-On-One?J2EE?Development?and?Design中闡述的部分理念和原型衍生而來。它是為了解決企業應用開發的復雜性而創建的。框架的主要優勢之一就是其分層架構,分層架構允許使用者選擇使用哪一個組件,同時為?J2EE?應用程序開發提供集成的框架。Spring使用基本的JavaBean來完成以前只可能由EJB完成的事情。然而,Spring的用途不僅限于服務器端的開發。從簡單性、可測試性和松耦合的角度而言,任何Java應用都可以從Spring中受益。Spring的核心是控制反轉(IoC)和面向切面(AOP)。簡單來說,Spring是一個分層的JavaSE/EE?full-stack(一站式)?輕量級開源框架。
l?輕量級:與EJB對比,依賴資源少,銷毀的資源少。
l?分層:?一站式,每一個層都提供的解決方案
web層:struts,spring-MVC
service層:spring
dao層:hibernate,mybatis?,?jdbcTemplate??-->?spring-data
1.2?spring核心
?
Spring的核心是控制反轉(IoC)和面向切面(AOP)
IoC(Inversion of control): 控制反轉控制權由對象本身轉向容器;由容器根據配置文件去創建實例并創建各個實例之間的依賴關系
AOP(Aspect Oriented Programming),也就是面向方面編程的技術。AOP基于IoC基礎,是對OOP的有益補充。1.3spring優點
| l?方便解耦,簡化開發??(高內聚低耦合)
l?AOP編程的支持
l?聲明式事務的支持
l?方便程序的測試
l?方便集成各種優秀框架
l?降低JavaEE?API的使用難度
? |
?
1.4?spring體系結構
?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 核心容器:beans、core、context、expression
?
1?入門案例:IoC【掌握】
1.1?導入jar包
l?4?+?1??:?4個核心(beans、core、context、expression)?+?1個依賴(commons-loggins...jar)
?
?
?
?
1.2?目標類
l?提供UserService接口和實現類
l?獲得UserService實現類的實例
之前開發中,直接new一個對象即可。
學習spring之后,將由Spring創建對象實例-->?IoC?控制反轉(Inverse?of??Control)
之后需要實例對象時,從spring工廠(容器)中獲得,需要將實現類的全限定名稱配置到xml文件中
| public?interface?UserService?{ ? public?void?addUser(); ? } |
| ? public?class?UserServiceImpl?implements?UserService?{ ? @Override public?void?addUser()?{ System.out.println("a_ico?add?user"); } ? } |
?
1.3?配置文件
l?位置:任意,開發中一般在classpath下(src)
l?名稱:任意,開發中常用applicationContext.xml
l?內容:添加schema約束
約束文件位置:spring-framework-3.2.0.RELEASE\docs\spring-framework-reference\html\?xsd-config.html
| <?xml?version="1.0"?encoding="UTF-8"?> <beans?xmlns="http://www.springframework.org/schema/beans" ???????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ???????xsi:schemaLocation="http://www.springframework.org/schema/beans? ??????????http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--?配置service? <bean>?配置需要創建的對象 id?:用于之后從spring容器獲得實例時使用的 class?:需要創建實例的全限定類名 --> <bean?id="userServiceId"?class="com.zqy.a_ioc.UserServiceImpl"></bean> </beans> |
?
?
1.4?測試
| @Test public?void?demo02(){ //從spring容器獲得 //1?獲得容器 String?xmlPath?=?"com/zqy/a_ioc/beans.xml"; ApplicationContext?applicationContext?=?new?ClassPathXmlApplicationContext(xmlPath); //2獲得內容?--不需要自己new,都是從spring容器獲得 UserService?userService?=?(UserService)?applicationContext.getBean("userServiceId"); userService.addUser(); ? } |
?
?
?
?
2?入門案例:DI【掌握】
l?DI?Dependency?Injection?,依賴注入
is?a?:是一個,繼承。
has?a:有一個,成員變量,依賴。
class?B?{
???????????private?A?a;???//B類依賴A類
????????}
依賴:一個對象需要使用另一個對象
注入:通過setter方法進行另一個對象實例設置。
l?例如:
class?BookServiceImpl{
????????//之前開發:接口?=?實現類??(service和dao耦合)
//private?BookDao?bookDao?=?new?BookDaoImpl();
? //spring之后?(解耦:service實現類使用dao接口,不知道具體的實現類)
private?BookDao?bookDao;
setter方法
???}
模擬spring執行過程
創建service實例:BookService?bookService?=?new?BookServiceImpl() -->IoC??<bean>
創建dao實例:BookDao?bookDao?=?new?BookDaoImple() -->IoC
將dao設置給service:bookService.setBookDao(bookDao); -->DI???<property>
?
2.1?目標類
l?創建BookService接口和實現類
l?創建BookDao接口和實現類
l?將dao和service配置?xml文件
l?使用api測試
2.1.1?dao
| public?interface?BookDao?{ ? public?void?addBook(); ? } |
| public?class?BookDaoImpl?implements?BookDao?{ ? @Override public?void?addBook()?{ System.out.println("di??add?book"); } ? } |
?
?
2.1.2?service
?
| public?interface?BookService?{ ? public?abstract?void?addBook(); ? } |
| public?class?BookServiceImpl?implements?BookService?{ ? //?方式1:之前,接口=實現類 // private?BookDao?bookDao?=?new?BookDaoImpl(); //?方式2:接口?+?setter private?BookDao?bookDao; public?void?setBookDao(BookDao?bookDao)?{ this.bookDao?=?bookDao; } ? @Override public?void?addBook(){ this.bookDao.addBook(); } ? } |
?
?
2.2?配置文件
?
?
| <beans?xmlns="http://www.springframework.org/schema/beans" ???????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ???????xsi:schemaLocation="http://www.springframework.org/schema/beans? ??????????http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--? 模擬spring執行過程 創建service實例:BookService?bookService?=?new?BookServiceImpl() IoC??<bean> 創建dao實例:BookDao?bookDao?=?new?BookDaoImpl() IoC 將dao設置給service:bookService.setBookDao(bookDao); DI???<property> ? <property>?用于進行屬性注入 name:?bean的屬性名,通過setter方法獲得 setBookDao?##>?BookDao??##>?bookDao ref?:另一個bean的id值的引用 ?--> ? <!--?創建service?--> <bean?id="bookServiceId"?class="com.zqy.b_di.BookServiceImpl"> <property?name="bookDao"?ref="bookDaoId"></property> </bean> ? <!--?創建dao實例?--> <bean?id="bookDaoId"?class="com.zqy.b_di.BookDaoImpl"></bean> ? ? </beans> |
?
?
2.3?測試
| @Test public?void?demo01(){ //從spring容器獲得 String?xmlPath?=?"com/zqy/b_di/beans.xml"; ApplicationContext?applicationContext?=?new?ClassPathXmlApplicationContext(xmlPath); BookService?bookService?=?(BookService)?applicationContext.getBean("bookServiceId"); ? bookService.addBook(); ? } |
?
3?myeclipse?schema?xml提示
l?步驟一:確定xsd文件位置
spring-framework-3.2.0.RELEASE\schema\beans
?
?
l?步驟二:復制路徑
?
?
l?步驟三:搜索“xml?catalog”
?
?
?
l?步驟四:添加約束提示
?
?
?
4?核心API
l?api整體了解,之后不使用,在學習過程需要。
?
?
l?BeanFactory?:這是一個工廠,用于生成任意bean。
采取延遲加載,第一次getBean時才會初始化Bean
l?ApplicationContext:是BeanFactory的子接口,功能更強大。(國際化處理、事件傳遞、Bean自動裝配、各種不同應用層的Context實現)。當配置文件被加載,就進行對象實例化。
ClassPathXmlApplicationContext?用于加載classpath(類路徑、src)下的xml
加載xml運行時位置?-->?/WEB-INF/classes/...xml
FileSystemXmlApplicationContext?用于加載指定盤符下的xml
加載xml運行時位置?-->?/WEB-INF/...xml
通過java?web?ServletContext.getRealPath()?獲得具體盤符
?
| @Test public?void?demo02(){ //使用BeanFactory??--第一次條用getBean實例化 String?xmlPath?=?"com/zqy/b_di/beans.xml"; ? BeanFactory?beanFactory?=?new?XmlBeanFactory(new?ClassPathResource(xmlPath)); ? BookService?bookService?=?(BookService)?beanFactory.getBean("bookServiceId"); ? bookService.addBook(); ? } |
?
?
?
5?裝配Bean?基于XML
5.1?實例化方式
l?3種bean實例化方式:默認構造、靜態工廠、實例工廠
l?
?
5.1.1?默認構造
| <bean?id=""?class="">??必須提供默認構造 |
?
5.1.2?靜態工廠
l?常用與spring整合其他框架(工具)
l?靜態工廠:用于生成實例對象,所有的方法必須是static
| <bean?id=""??class="工廠全限定類名"??factory-method="靜態方法"> |
?
5.1.2.1?工廠
| public?class?MyBeanFactory?{ ? /** ?*?創建實例 ?*?@return ?*/ public?static?UserService?createService(){ return?new?UserServiceImpl(); } } |
?
5.1.2.2?spring配置
| <!--?將靜態工廠創建的實例交予spring? class?確定靜態工廠全限定類名 factory-method?確定靜態方法名 --> <bean?id="userServiceId"?class="com.zqy.c_inject.b_static_factory.MyBeanFactory"?factory-method="createService"></bean> |
?
5.1.3?實例工廠
l?實例工廠:必須先有工廠實例對象,通過實例對象創建對象。提供所有的方法都是“非靜態”的。
?
5.1.3.1?工廠
| /** ?*?實例工廠,所有方法非靜態 ?* ?*/ public?class?MyBeanFactory?{ ? /** ?*?創建實例 ?*?@return ?*/ public?UserService?createService(){ return?new?UserServiceImpl(); } ? } |
?
5.1.3.2?spring配置
?
| <!--?創建工廠實例?--> <bean?id="myBeanFactoryId"?class="com.zqy.c_inject.c_factory.MyBeanFactory"></bean> <!--?獲得userservice? *?factory-bean?確定工廠實例 *?factory-method?確定普通方法 --> <bean?id="userServiceId"?factory-bean="myBeanFactoryId"?factory-method="createService"></bean> ? |
?
?
5.2?Bean種類
l?普通bean:之前操作的都是普通bean。<bean?id=""?class="A">?,spring直接創建A實例,并返回
l?FactoryBean:是一個特殊的bean,具有工廠生成對象能力,只能生成特定的對象。
bean必須使用?FactoryBean接口,此接口提供方法?getObject()?用于獲得特定bean。
<bean?id=""?class="FB">?先創建FB實例,使用調用getObject()方法,并返回方法的返回值
FB?fb?=?new?FB();
return?fb.getObject();
l?BeanFactory?和?FactoryBean?對比?
BeanFactory:工廠,用于生成任意bean。
FactoryBean:特殊bean,用于生成另一個特定的bean。例如:ProxyFactoryBean?,此工廠bean用于生產代理。<bean?id=""?class="....ProxyFactoryBean">?獲得代理對象實例。AOP使用
?
5.3?作用域
?
l?作用域:用于確定spring創建bean實例個數
?
l?取值:
singleton?單例,默認值。
prototype?多例,每執行一次getBean將獲得一個實例。例如:struts整合spring,配置action多例。
l?配置信息
| <bean?id=""?class=""??scope=""> |
?
?
?
| <bean?id="userServiceId"?class="com.zqy.d_scope.UserServiceImpl"? scope="prototype"?></bean> |
?
?
5.4?生命周期
5.4.1?初始化和銷毀
l?目標方法執行前后執行后,將進行初始化或銷毀。
| <bean?id=""?class=""?init-method="初始化方法名稱"??destroy-method="銷毀的方法名稱"> |
?
5.4.1.1?目標類
| public?class?UserServiceImpl?implements?UserService?{ ? @Override public?void?addUser()?{ System.out.println("e_lifecycle?add?user"); } ? public?void?myInit(){ System.out.println("初始化"); } public?void?myDestroy(){ System.out.println("銷毀"); } ? } |
?
5.4.1.2?spring配置
| <!--?? init-method?用于配置初始化方法,準備數據等 destroy-method?用于配置銷毀方法,清理資源等 --> <bean?id="userServiceId"?class="com.zqy.e_lifecycle.UserServiceImpl"? init-method="myInit"?destroy-method="myDestroy"?></bean> |
?
5.4.1.3?測試
| @Test public?void?demo02()?throws?Exception{ //spring?工廠 String?xmlPath?=?"com/zqy/e_lifecycle/beans.xml"; ClassPathXmlApplicationContext?applicationContext?=?new?ClassPathXmlApplicationContext(xmlPath); UserService?userService?=?(UserService)?applicationContext.getBean("userServiceId"); userService.addUser(); ? //要求:1.容器必須close,銷毀方法執行;?2.必須是單例的 // applicationContext.getClass().getMethod("close").invoke(applicationContext); //?*?此方法接口中沒有定義,實現類提供 applicationContext.close(); ? } |
?
5.4.2?BeanPostProcessor?后處理Bean
l?spring?提供一種機制,只要實現此接口BeanPostProcessor,并將實現類提供給spring容器,spring容器將自動執行,在初始化方法前執行before(),在初始化方法后執行after()?。?配置<bean?class="">
?
?
l?Factory?hook(勾子)?that?allows?for?custom?modification?of?new?bean?instances,?e.g.?checking?for?marker?interfaces?or?wrapping?them?with?proxies.?
l?spring提供工廠勾子,用于修改實例對象,可以生成代理對象,是AOP底層。
模擬
A?a?=new?A();
a?=?B.before(a) -->?將a的實例對象傳遞給后處理bean,可以生成代理對象并返回。
a.init();
a?=?B.after(a);
?
a.addUser(); //生成代理對象,目的在目標方法前后執行(例如:開啟事務、提交事務)
?
a.destroy()
?
5.4.2.1?編寫實現類
| public?class?MyBeanPostProcessor?implements?BeanPostProcessor?{ ? @Override public?Object?postProcessBeforeInitialization(Object?bean,?String?beanName)?throws?BeansException?{ System.out.println("前方法?:?"?+?beanName); return?bean; } ? @Override public?Object?postProcessAfterInitialization(final?Object?bean,?String?beanName)?throws?BeansException?{ System.out.println("后方法?:?"?+?beanName); //?bean?目標對象 //?生成?jdk?代理 return?Proxy.newProxyInstance( MyBeanPostProcessor.class.getClassLoader(),? bean.getClass().getInterfaces(),? new?InvocationHandler(){ @Override public?Object?invoke(Object?proxy,?Method?method,?Object[]?args)?throws?Throwable?{ ? System.out.println("------開啟事務"); ? //執行目標方法 Object?obj?=?method.invoke(bean,?args); ? System.out.println("------提交事務"); return?obj; }}); } } |
?
5.4.2.2?配置
| <!--?將后處理的實現類注冊給spring?--> <bean?class="com.zqy.e_lifecycle.MyBeanPostProcessor"></bean> |
?
l?問題1:后處理bean作用某一個目標類,還是所有目標類?
所有
l?問題2:如何只作用一個?
通過“參數2”beanName進行控制
?
5.5?屬性依賴注入
l?依賴注入方式:手動裝配?和?自動裝配
l?手動裝配:一般進行配置信息都采用手動
基于xml裝配:構造方法、setter方法
基于注解裝配:
l?自動裝配:struts和spring?整合可以自動裝配
byType:按類型裝配?
byName:按名稱裝配
constructor構造裝配,
auto:?不確定裝配。
5.5.1?構造方法
5.5.1.1?目標類
| public?class?User?{ ? private?Integer?uid; private?String?username; private?Integer?age; ? public?User(Integer?uid,?String?username)?{ super(); this.uid?=?uid; this.username?=?username; } ? public?User(String?username,?Integer?age)?{ super(); this.username?=?username; this.age?=?age; } ? |
?
5.5.1.2?spring配置
| <!--?構造方法注入? *?<constructor-arg>?用于配置構造方法一個參數argument name?:參數的名稱 value:設置普通數據 ref:引用數據,一般是另一個bean?id值 ? index?:參數的索引號,從0開始?。如果只有索引,匹配到了多個構造方法時,默認使用第一個。 type?:確定參數類型 例如:使用名稱name <constructor-arg?name="username"?value="jack"></constructor-arg> <constructor-arg?name="age"?value="18"></constructor-arg> 例如2:【類型type?和??索引?index】 <constructor-arg?index="0"?type="java.lang.String"?value="1"></constructor-arg> <constructor-arg?index="1"?type="java.lang.Integer"?value="2"></constructor-arg> --> <bean?id="userId"?class="com.zqy.f_xml.a_constructor.User"?> <constructor-arg?index="0"?type="java.lang.String"?value="1"></constructor-arg> <constructor-arg?index="1"?type="java.lang.Integer"?value="2"></constructor-arg> </bean> |
5.5.2?setter方法
| <!--?setter方法注入? *?普通數據? <property?name=""?value="值"> 等效 <property?name=""> <value>值 *?引用數據 <property?name=""?ref="另一個bean"> 等效 <property?name=""> <ref?bean="另一個bean"/> ? --> <bean?id="personId"?class="com.zqy.f_xml.b_setter.Person"> <property?name="pname"?value="陽志"></property> <property?name="age"> <value>1234</value> </property> ? <property?name="homeAddr"?ref="homeAddrId"></property> <property?name="companyAddr"> <ref?bean="companyAddrId"/> </property> </bean> ? <bean?id="homeAddrId"?class="com.zqy.f_xml.b_setter.Address"> <property?name="addr"?value="阜南"></property> <property?name="tel"?value="911"></property> </bean> <bean?id="companyAddrId"?class="com.zqy.f_xml.b_setter.Address"> <property?name="addr"?value="北京八寶山"></property> <property?name="tel"?value="120"></property> </bean> |
?
5.5.3?P命令空間[了解]
l?對“setter方法注入”進行簡化,替換<property?name="屬性名">,而是在
<bean?p:屬性名="普通值"??p:屬性名-ref="引用值">
l?p命名空間使用前提,必須添加命名空間
?
?
?
| <bean?id="personId"?class="com.zqy.f_xml.c_p.Person"? p:pname="禹太璞"?p:age="22"? p:homeAddr-ref="homeAddrId"?p:companyAddr-ref="companyAddrId"> </bean> ? <bean?id="homeAddrId"?class="com.zqy.f_xml.c_p.Address" p:addr="DG"?p:tel="東莞"> </bean> <bean?id="companyAddrId"?class="com.zqy.f_xml.c_p.Address" p:addr="DG"?p:tel="島國"> </bean> |
?
?
?
5.5.4?集合注入
| <!--? 集合的注入都是給<property>添加子標簽 數組:<array> List:<list> Set:<set> Map:<map>?,map存放k/v?鍵值對,使用<entry>描述 Properties:<props>??<prop?key=""></prop>??【】 ? 普通數據:<value> 引用數據:<ref> --> <bean?id="collDataId"?class="com.zqy.f_xml.e_coll.CollData"?> <property?name="arrayData"> <array> <value>DS</value> <value>DZD</value> <value>屌絲</value> <value>屌中屌</value> </array> </property> ? <property?name="listData"> <list> <value>于嵩楠</value> <value>曾衛</value> <value>楊煜</value> <value>曾小賢</value> </list> </property> ? <property?name="setData"> <set> <value>H封</value> <value>J紙</value> <value>A系</value> </set> </property> ? <property?name="mapData"> <map> <entry?key="jack"?value="杰克"></entry> <entry> <key><value>rose</value></key> <value>肉絲</value> </entry> </map> </property> ? <property?name="propsData"> <props> <prop?key="高富帥">ASD</prop> <prop?key="白富美">AS</prop> <prop?key="男屌絲">GG</prop> </props> </property> </bean> |
?
?
?
?
?
?
?
6?裝配Bean?基于注解
l?注解:就是一個類,使用@注解名稱
l?開發中:使用注解?取代?xml配置文件。
?
?
1.?@Component取代<bean?class="">
@Component("id")?取代?<bean?id=""?class="">
2.web開發,提供3個@Component注解衍生注解(功能一樣)取代<bean?class="">
@Repository?:dao層
@Service:service層
@Controller:web層
3.依賴注入 ,給私有字段設置,也可以給setter方法設置
普通值:@Value("")
引用值:
方式1:按照【類型】注入
@Autowired
方式2:按照【名稱】注入1
@Autowired
@Qualifier("名稱")
方式3:按照【名稱】注入2
@Resource("名稱")
4.生命周期
初始化:@PostConstruct
銷毀:@PreDestroy
5.作用域
@Scope("prototype")?多例
?
l?注解使用前提,添加命名空間,讓spring掃描含有注解類
?
?
| <beans?xmlns="http://www.springframework.org/schema/beans" ???????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ???????xmlns:context="http://www.springframework.org/schema/context" ???????xsi:schemaLocation="http://www.springframework.org/schema/beans? ??????????http://www.springframework.org/schema/beans/spring-beans.xsd ??????????http://www.springframework.org/schema/context? ??????????http://www.springframework.org/schema/context/spring-context.xsd"> <!--?組件掃描,掃描含有注解的類?--> <context:component-scan?base-package="com.zqy.g_annotation.a_ioc"></context:component-scan> </beans> |
轉載于:https://www.cnblogs.com/zqy-blogzone/p/7372871.html
總結
以上是生活随笔為你收集整理的Spring基础知识及入门的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 暴力枚举进程
- 下一篇: logging 模块