1.Maven找包:
spring-webmvc
spring-jdbc
2.Spring的本質是控制反轉,依靠依賴注入來實現。以一個servcie對象為例,即是service暴露注入接口(構造,set方法),由spring配置對象注入(設置)給該service對象,這樣可以做到Service層專注業務,不需要因為變化改變自身代碼,只要在調用(注入)的時候改變對象即可改變service的具體實現,service面向接口編程,由service主動構建對象到被動接收外部注入的對象。同時Spring作為容器會自己構建對象,這些對象可以作為參數來注入
對象由Spring來創建,管理,裝配
3.resources目錄放beans.xml
<bean id= class= >
<property name= value=>
bean相當於一個對象,property相當於給對象屬性設值,id是對象的唯一標志符,class為類型,name為別名用逗號或者空格,分號分開;scope指定是不是單例
程序里通過ClassPathXmlApplicationContext("beans.xml")獲取ApplicationContext
getBean(id)獲取bean,類型轉換之后即可用。也可以通過.class獲取xml里的對象,不用強制類型轉換了
4.property標簽中,ref指的是spring容器中創建好的對象,value指的是基本數據類型的值
5.現在,要用不同的底層實現,只要設置代碼動態讀入相應的配置文件即可,代碼不用改了
6.默認使用無參構造對象。
要使用有參構造,需要在bean標簽下用<constructor-arg>標簽,index或者type來制定參數,或者多個constructor-arg標簽直接使用name,value,ref賦值
7. 容器只要被創建了,里邊的對象就都會被創建了
8.alias標簽,通過name設置源id名,alias設置別名
9.import標簽,將多個配置文件合並導入為一個,resource屬性指定文件名
10.可以看到,spring的標簽還是比較少的。下面要學習標簽里的屬性
11.依賴注入
構造器注入
construct-arg標簽
set方式注入
bean,ref,idref,list,set,map,props(Properties類),value,null可以用來設置屬性的值
要注入,必須有set方法。非boolean類型的變量,set方法名要是set+屬性名
- 普通值注入,value注入:<property name="a" value="avavlue">
- bean對象注入,通過ref指向id,ref=“id”
- 數組注入,property標簽下要有<array><value>aaa </value><value>bbb</value></array>,value標簽里的值可以沒有雙引號
- list注入,<list>標簽
- map注入,<map> <entry key value/></map>
- set注入,<set> <value></value></set>
- null注入,property標簽下直接加<null/>標簽
- properties注入,<props><prop key=“”>數值</prop></props>,比如數據庫配置
- idref注入,就是注入目標bean的id這個屬性
拓展方式注入
p: c:這樣的方式
p和c是命名空間名稱,使用需要導入約束
p的意思是property,可以直接注入屬性的值,即為<bean p:屬性名=value>的形式,p:屬性名-ref可以引用其他bean的id
c是construct的意思,構造器注入,賦值方式和p的一致
引入了xsd之后,這些都會有提示
12.bean的作用域,即bean要構建幾個,scope屬性指定
singleton:只有一個,默認值(單線程使用)
prototype:get一次有一個(多線程使用)
request:每次request有一個
session:每次session有一個
13.自動裝配是spring自動在上下文中給對象注入屬性
自動裝配要做兩件事情,一是組件掃描,二是按照規則裝配
三種裝配方式:
xml里配置
java代碼注解配置
隱式裝配
自動裝配又叫autowire,可以設置bean標簽里的autowire屬性,可以有以下字符串的值
- byname自動裝配:自動在上下文里找和自己屬性對應set方法后邊的名字(首字母改成小寫)一樣的bean id。id要唯一
- bytype自動裝配:自動在上下文里找和自己屬性類型相同的bean,類型要唯一,不然報錯。要被注入的bean沒有id也可以。class要唯一
14.使用注解自動裝配
有三個自動裝配的注解
@Autowired和@Qualifier是Spring的注解
@Resource是J2EE的注解
這三個注解可以放在字段上,也可以放在set方法上,表示相應的對象屬性要被spring自動裝配。注解放在字段上,就不需要set方法了
支持注解xml里要做兩件事
1.xml頭部導入約束
xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
2.使用<context:annotation-config/>
標簽
@Autowired注解:表示默認按照類型掃描組件,裝配到該屬性。required屬性表明是否支持該屬性為null
@Qualifier注解:指定該value為id的字符串,找這個id來裝配。Qualifier注解不能獨自存在
@Resource注解:是Java自帶的注解,是上邊兩個的結合體。先按照指定的name屬性去查,再按照默認字段名去查,最后按照類型去查
15.注解開發
標簽<context:component-scan base-package="com.kuang.pojo"/>指定要掃描的package,這個包下面的注解會生效
@Component注解,指定bean,默認id為類名首字母小寫,通過value值來改變
@Value注解給對象的屬性或者set方法注入
衍生注解:
Controller:@Controller
Service:@Service
Dao:@Repository
這四個注解功能一樣,都是為了把對象注冊到spring容器里,只是為了方便區分
@Scope注解:聲明對象作用域
注解的缺點,不是自己的類不能使用注解注冊到spring容器中
16.不用xml配置
聲明一個類,用@Configuration注解配置
這個類里@Bean注解修飾的東西,返回值是bean標簽的class屬性,函數名稱是其id屬性
獲取注解配置,要用AnnotationConfigApplicationContext類: ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
@ComponentScan注解指定掃描包
@Import(com.a.class)注解:引入其他config類
當使用 < context:component-scan/> 后,就可以將 < context:annotation-config/> 移除了,后者被自動忽略
17.所有的類都要注冊到注冊到beans里邊,所有的bean都要通過容器去取,容器里的bean取出來就是一個對象
18.代理模式,將公共代碼給代理,方便集中修改,分工明確,各做各的
分為靜態代理與動態代理,動態代理動態生成一個類,通過反射代理無數個類或者接口
靜態代理寫死了類
動態代理jdk原生方法,有兩個類要關注
1.InvocationHandler
2.Proxy
代理類繼承InvocationHandler,實現其接口invoke在其中調用真正業務方法並在業務方法前后調用自己的公共代碼。通過newProxyInstance動態生成被代理的接口對象,客戶調用相應接口即可實現代理調用
19.使用spring接口添加aop
比如MethodBeforeAdvice ,MethodAfterAdvic,在其中的接口方法里做自己的操作
xml里配置:
1.導入約束
2.在標簽<aop:config>里配置。
aop:pointcut定義切入點(業務方法),有id屬性用於被環繞引用,experssion屬性指定那個包哪個類哪個方法什么樣的參數什么樣的返回值
aop:advisor定義環繞,屬性advice-ref為實現了spring相應接口的bean id,pointcut-ref為要應用到的切入點業務方法引用
20.使用自定義類添加aop
aop:aspect定義切面,ref屬性指向代理bean的id,即相應的代理方法實現類。里面可以有上面的切入點,還有aop:before等標簽定義在什么時候切入。aop:before標簽的method屬性指定方法,pointcut-ref屬性指定要切入的點
這個功能簡單,沒辦法獲取切入點信息
21.注解實現aop
@Aspect注解定義切面,即代理實現類
@Before定義before類方法,可以通過@Before("excecution(表達式)")這樣的辦法指定切入點
22.總之,aop要定義切面,即代理方法,指定這些方法在哪些業務類什么位置執行
23.<aop:aspectj-autoproxy>標簽表面自動為用注解聲明了的切面創建代理,織入切面
proxy-target-class屬性指定代理實現模式,jdk還是CGLib實現代理,true為CGLib
24.@Around注解下,方法可以有個ProceedingJoinPoint參數,通過proceed方法執行方法,在這前后即可加入自己的操作
25.aop在不影響我們的業務代碼的情況下,實現動態的增強
26. 整合Mybatis
1.導入jar包
mybatis
mysql數據庫連接需要的驅動包(mysql-connector-java)
spring
aop織入(aspectjewaver)
mybatis-spring(整合包,取代mybatis默認的配置相關)
spring-jdbc(spring操作數據庫需要的包)
2.編寫配置文件
maven要在pom里設置靜態資源過濾,把不在resources文件里,在java文件夾里的xml文件也導入項目進行編譯
編寫mybatis步驟:
1.pojo類
2.配置文件
3.Dao層Mapper接口
4.Mapper.xml
5.通過sqlSession的getMapper方法獲取Mapper接口代理類然后執行里邊的相應方法
Mybatis里需要創造的對象,全部要由spring來創建,管理,裝配
Mybatis-Spring配置:
在spring XML里要配置SqlSessionFactory和數據映射器(數據源,配置數據庫的)
數據源配置:
可以使用Spring的數據源替換Mybatis的配置,也可以用c3p0,dbcp,druid(看class)
<!--配置數據源:數據源有非常多,可以使用第三方的,也可使使用Spring的--> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=utf8"/> <property name="username" value="root"/> <property name="password" value="123456"/> </bean>
SqlSessionFactory配置:
類要用Mybatis-Spring包里的SqlSessionFactoryBean
指定datasource,綁定mybatis包括config xml路徑和各個mapper的xml路徑
<!--配置SqlSessionFactory--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <!--關聯Mybatis--> <property name="configLocation" value="classpath:mybatis-config.xml"/> <property name="mapperLocations" value="classpath:com/kuang/dao/*.xml"/> </bean>
Mybatis原生配置文件里的environments,datasource,transactionmanager配置會被Mybatis-Spring里的SqlSessionFactoryBean替代。
同樣的,Mybatis-Spring會用SqlSessionTemplate代替Myatis的SqlSession,由其自動管理SQL Session。這個類也是SqlSession的子類
模板的意思是流程都是固定死的,只是流程里的數據是不確定的,要在調用的時候填入,在流程中使用
所以,在xml里先用以下辦法創建SqlSessionTemplate
<!--注冊sqlSessionTemplate , 關聯sqlSessionFactory--> <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <!--利用構造器注入--> <constructor-arg index="0" ref="sqlSessionFactory"/> </bean>
再把這個Bean注入到要訪問Dao層的對象(新增接口實現類)里即可,用的時候調用SqlSessionTemplate的getMapper方法
新的SqlSessionTemplate是線程安全的,在各個線程里都可以使用,不需要自己構造了。
SqlSessionTemplate還支持Batch批量操作
第二種整合辦法:
使用 SqlSessionDaoSupport
繼承這個類,設置其sqlSessionFactory或者sqlSessionTemplate之一即可。
然后通過getSqlSession()獲取SqlSessionTemplate
SqlSessionTemplate操作Dao有兩種辦法,一是通過getMapper獲取接口類調用其中方法,一是把包名+方法名傳遞給selectOne這樣的常規操作函數來調用
27.聲明式事務
事物把一組操作放一起,要不都成功,要不都失敗,確保一致性和完整性
ACID原則:
原子性
一致性
隔離性
持久性
事務管理分編程式事物和聲明式事務
編程的要自己寫代碼調用Spring的API,比較麻煩
聲明的通過AOP配置,自動調用
使用聲明式事務步驟
1.導入約束
xmlns:tx="http://www.springframework.org/schema/tx"
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
2.將jdbc事務管理器注入Spring並配置其數據源,類為Spring為事務管理抽象出來的類DataSourceTransactionManager
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean>
3.通過tx:advice標簽配置管理器,即事物是什么,及其傳播性
其中tx:method配置事務管理器里抽象好的幾個事物,add,delete之類的都是自己代碼定義的
<!--配置事務通知--> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <!--配置哪些方法使用什么樣的事務,配置事務的傳播特性--> <tx:method name="add" propagation="REQUIRED"/> <tx:method name="delete" propagation="REQUIRED"/> <tx:method name="update" propagation="REQUIRED"/> <tx:method name="search*" propagation="REQUIRED"/> <tx:method name="get" read-only="true"/> <tx:method name="*" propagation="REQUIRED"/> </tx:attributes> </tx:advice>
傳播性為多個方法之前怎么處理事物關系,是進入新事物,還是不進入之類的
- propagation_requierd:如果當前沒有事務,就新建一個事務,如果已存在一個事務中,加入到這個事務中,這是最常見的選擇。
- propagation_supports:支持當前事務,如果沒有當前事務,就以非事務方法執行。
- propagation_mandatory:使用當前事務,如果沒有當前事務,就拋出異常。
- propagation_required_new:新建事務,如果當前存在事務,把當前事務掛起。
- propagation_not_supported:以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。
- propagation_never:以非事務方式執行操作,如果當前事務存在則拋出異常。
- propagation_nested:如果當前存在事務,則在嵌套事務內執行。如果當前沒有事務,則執行與propagation_required類似的操作
4.aop配置,在相應方法即切入點添加事物
<!--配置aop織入事務--> <aop:config> <aop:pointcut id="txPointcut" expression="execution(* com.kuang.dao.*.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/> </aop:config>