9. Spring

IOC

  • 由于java 編譯后才能運(yùn)行缕溉,由于編譯期進(jìn)行的檢查可能導(dǎo)致我們?nèi)苯M件不能編譯通過弃衍。所以要想個(gè)辦法繞過編譯器的檢測(cè)盲厌,所以反射就引用而生馒过。編譯完成后不能修改參數(shù)臭脓,所以配置文件應(yīng)用而生。

  • 有些時(shí)候?qū)ο笮枰貜?fù)調(diào)用腹忽,這個(gè)時(shí)候需要一個(gè)容器存著可以調(diào)用對(duì)象来累。這個(gè)就是bean。以前都是自己new對(duì)象窘奏,現(xiàn)在是向bean要對(duì)象嘹锁。所以稱為控制反轉(zhuǎn)。

  • 所以有對(duì)象創(chuàng)建對(duì)象獲取兩類着裹。最后還包括main函數(shù)的運(yùn)行兼耀。

  • main函數(shù)獲取容器里對(duì)象的方法

BeanFactory 才是 Spring 容器中的頂層接口。
ApplicationContext 是它的子接口求冷。
BeanFactory 和 ApplicationContext 的區(qū)別:
創(chuàng)建對(duì)象的時(shí)間點(diǎn)不一樣瘤运。
ApplicationContext:只要一讀取配置文件,默認(rèn)情況下就會(huì)創(chuàng)建對(duì)象匠题。
BeanFactory:什么使用什么時(shí)候創(chuàng)建對(duì)象拯坟。


ApplicationContext 常用三個(gè)實(shí)現(xiàn)類:
     ClassPathXmlApplicationContext:
    它是從類的根路徑下加載配置文件 推薦使用這種
    FileSystemXmlApplicationContext:
    它是從磁盤路徑上加載配置文件,配置文件可以在磁盤的任意位置韭山。
    AnnotationConfigApplicationContext:
    當(dāng)我們使用注解配置容器對(duì)象時(shí)郁季,需要使用此類來創(chuàng)建 spring 容器冷溃。它用來讀取注解。


spring架構(gòu)圖

xml 對(duì)象創(chuàng)建

- 創(chuàng)建方法
<bean id="" class=""  scope=""></bean>
id:給對(duì)象在容器中提供一個(gè)唯一標(biāo)識(shí)梦裂。用于獲取對(duì)象似枕。
class:指定類的全限定類名。用于反射創(chuàng)建對(duì)象年柠。默認(rèn)情況下調(diào)用無參構(gòu)造函數(shù)凿歼。
scope:指定對(duì)象的作用范圍。
* singleton :默認(rèn)值冗恨,單例的.
* prototype :多例的.
* request :WEB 項(xiàng)目中

<!-- 告知 spring 創(chuàng)建容器時(shí)要掃描的包 -->
<context:component-scan base-package="com.itheima"></context:component-scan>
- 構(gòu)造方法
<!--構(gòu)造函數(shù)constructor-arg-->
<!--set 注入property-->
<property name="password" value="1234"></property>
<property name="password" ref="引用一個(gè)定義"></property>

- 同樣可以注入集合setmap


<property name="myList">
<array>
<value>AAA</value>
<value>BBB</value>
<value>CCC</value>
</array>
</property>


其中 list 對(duì)應(yīng)array
set對(duì)應(yīng)list
props對(duì)應(yīng)map
 如何注入變量呢答憔?

注解創(chuàng)建對(duì)象

  • 創(chuàng)建對(duì)象
    @Component(value="name")將當(dāng)前類注入到spring容器。默認(rèn)將首字母改成小寫的掀抹。與<bean id="" class="">一樣
他們?nèi)齻€(gè)注解都是針對(duì)一個(gè)的衍生注解虐拓,他們的作用及屬性都是一模一樣的。因?yàn)橹挥芯唧w類可以實(shí)例化傲武,所以這里肯定也是可以實(shí)例的類蓉驹。他們只不過是提供了更加明確的語義化。
@Controller:一般用于表現(xiàn)層的注解揪利。
@Service:一般用于業(yè)務(wù)層的注解戒幔。
@Repository:一般用于持久層的注解。
細(xì)節(jié):如果注解中有且只有一個(gè)屬性要賦值時(shí)土童,且名稱是 value,value 在賦值是可以不寫工坊。
  • 注入數(shù)據(jù)

- 只能注入其他 bean 類型献汗。
@Autowired  
自動(dòng)按照類型注入。當(dāng)使用注解注入屬性時(shí)王污,set 方法可以省略罢吃。它只能注入其他 bean 類型。當(dāng)有多個(gè)類型匹配時(shí)昭齐,使用要注入的對(duì)象變量名稱作為 bean 的 id尿招,在 spring 容器查找,找到了也可以注入成功阱驾。找不到就報(bào)錯(cuò)就谜。

@Qualifier
參數(shù)是名字,通過名字獲取變量數(shù)據(jù)里覆。丧荐。必須在autowired之后。
@Resource



// 注入基本數(shù)據(jù)類型和 String 類型數(shù)據(jù)的
@Value
@scope
singleton
prototype

  • 改變作用范圍
@Scope
取值:singleton prototype request session globalsession
  • getBean('impl',class)???
    id,強(qiáng)制類型轉(zhuǎn)換的類型

  • 注入數(shù)據(jù)順序
    Autowired

image.png

Configuration

指定該類的spring配置類喧枷,被指定路徑引入時(shí)可以省略虹统。

獲取容器時(shí)需要使用
AnnotationApplicationContext(有@Configuration 注解的類.class)
@ComponentScan("")
指定需要掃描的包
@PropertySource
property配置文件

@Bean(name="")
只能用于方法上弓坞,表明此方法創(chuàng)建一個(gè)對(duì)象放入容器

@Import
引入其他配置類

-寫property文件

public class JdbcConfig {
    
   @Value("${jdbc.driver}")
    private String driver;
    
    @Value("${jdbc.url}")
    private String url;
    
    @Value("${jdbc.username}")
    private String username;
    
    @Value("${jdbc.password}")
    private String password;

//這樣就可以存入spring容器里了。
@Bean(name="dataSource")
public DataSource createDataSource() {
}


}

//jdbc.properties 文件:
  jdbc.driver=com.mysql.jdbc.Driver
  
 jdbc.url=jdbc:mysql://localhost:3306/day44_ee247_spring
  • 實(shí)例代碼


    image.png
  • 通過注解獲取容器
ApplicationContext ac =
new AnnotationConfigApplicationContext(SpringConfiguration.class);
  • Spring 整合Junit
2.使用@RunWith 注解替換原有運(yùn)行器
3.使用@ContextConfiguration 指定 spring 配置文件的位置
4.使用@Autowired 給測(cè)試類中的變量注入數(shù)據(jù)


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations= {"classpath:bean.xml"})
public class AccountServiceTest {
@Autowired
private IAccountService as ;
}

AOP

Aspect oriented Programming
實(shí)現(xiàn)方式:動(dòng)態(tài)代理的方式车荔。典型應(yīng)用事務(wù)管理渡冻,日志管理。

  • 使用CGlib 的Enhancer 類創(chuàng)建代理對(duì)象

  • Proxy.newProxyInstance

  • Spring自帶的AOP細(xì)節(jié)

  • sprin術(shù)語

Joinpoint(連接點(diǎn)):
所謂連接點(diǎn)是指那些被攔截到的點(diǎn)忧便。在 spring 中,這些點(diǎn)指的是方法,因?yàn)?spring 只支持方法類型的連接點(diǎn)族吻。

Pointcut(切入點(diǎn)):
所謂切入點(diǎn)是指我們要對(duì)哪些 Joinpoint 進(jìn)行攔截的定義。對(duì)連接點(diǎn)的定義是切入點(diǎn)茬腿。

Advice(通知/增強(qiáng)):
所謂通知是指攔截到 Joinpoint 之后所要做的事情就是通知呼奢。通知的類型:前置通知,后置通知,異常通知,最終通知,環(huán)繞通知。

Introduction(引介):
引介是一種特殊的通知在不修改類代碼的前提下, Introduction 可以在運(yùn)行期為類動(dòng)態(tài)地添加一些方法或 Field切平。

Target(目標(biāo)對(duì)象):
代理的目標(biāo)對(duì)象握础。

Weaving(織入):
是指把增強(qiáng)應(yīng)用到目標(biāo)對(duì)象來創(chuàng)建新的代理對(duì)象的過程。spring 采用動(dòng)態(tài)代理織入悴品,而 AspectJ 采用編譯期織入和類裝載期織入禀综。

Proxy(代理):
一個(gè)類被 AOP 織入增強(qiáng)后,就產(chǎn)生一個(gè)結(jié)果代理類苔严。

Aspect(切面):
是切入點(diǎn)和通知(引介)的結(jié)合定枷。

  • 1.配置
<!-- 配置通知 -->
<bean id="txManager" class="com.itheima.utils.TransactionManager">
<property name="dbAssit" ref="dbAssit"></property>
</bean> 
  • 2.聲明aop
<aop:config>
...........
</aop:config>
  • 3.配置切面
<aop:aspect id="txAdvice" ref="txManager">
<!--配置通知的類型要寫在此處-->
</aop:aspect>
ref 引用已經(jīng)配置好的通知類bean的id
  • 4.配置切入點(diǎn)表達(dá)式
<aop:pointcut expression="execution(
public void com.itheima.service.impl.AccountServiceImpl.transfer(
java.lang.String, java.lang.String, java.lang.Float)
)" id="pt1"/>
    1. 配置具體的通知
<aop:before method="方法" pointct-ref="引用切入點(diǎn)表達(dá)式">
    1. 代碼
<aop:config>
    <aop:pointcut expression="execution(* com.itheima.service.impl.*.*(..))"id="pt1"/>
    <aop:aspect id="txAdvice" ref="txManager">
        <!-- 配置環(huán)繞通知 -->
        <aop:around method="transactionAround" pointcut-ref="pt1"/>
    </aop:aspect>
</aop:config>

使用注解方式實(shí)現(xiàn)aop

    1. 創(chuàng)建通知類,聲明為切面類
@Component("txManager")
@Aspect//表明當(dāng)前類是一個(gè)切面類
public class TransactionManager {
    //定義一個(gè) DBAssit
    @Autowired
    private DBAssit dbAssit ;
}

  • 2.在 spring 配置文件中開啟 spring 對(duì)注解 AOP 的支持
    <aop:aspectj-autoproxy/>
  • 3.切面表達(dá)式
@Pointcut("execution(* com.itheima.service.impl.*.*(..))")
private void pt1() {
}

  • 4.定義通知
@Around("pt1()")//注意:千萬別忘了寫括號(hào)
public Object transactionAround(ProceedingJoinPoint pjp) {
    //怎么獲得函數(shù)的名字
    //定義返回值
    Object rtValue = null;
    try {
        //獲取方法執(zhí)行所需的參數(shù)
        Object[] args = pjp.getArgs();
        //前置通知:開啟事務(wù)
        beginTransaction();
        //執(zhí)行方法
        rtValue = pjp.proceed(args);
        //后置通知:提交事務(wù)
        commit();
      }catch(Throwable e) {
        //異常通知:回滾事務(wù)
        rollback();
        e.printStackTrace();
      }finally {
        //最終通知:釋放資源
        release();
      }
    return rtValue;
}

環(huán)境搭建

  • 在配置文件中導(dǎo)入 context 的名稱空間

jdbcTemplate

  1. aop 和tx命名空間
  2. 實(shí)體類届氢,編寫業(yè)務(wù)層接口和實(shí)現(xiàn)類
  3. 持久層和實(shí)現(xiàn)類
  4. 在配置文件中配置業(yè)務(wù)層和持久層對(duì)
   <!-- 配置業(yè)務(wù)層-->
    <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
        <property name="accountDao" ref="accountDao"></property>
    </bean>

    <!-- 配置賬戶的持久層-->
    <bean id="accountDao" class="com.itheima.dao.impl.AccountDaoImpl">
        <property name="dataSource" ref="dataSource"></property>
    </bean>


    <!-- 配置數(shù)據(jù)源-->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:3306/eesy"></property>
        <property name="username" value="root"></property>
        <property name="password" value="1234"></property>
    </bean>

    <!-- spring中基于XML的聲明式事務(wù)控制配置步驟
        1欠窒、配置事務(wù)管理器
        2、配置事務(wù)的通知
                此時(shí)我們需要導(dǎo)入事務(wù)的約束 tx名稱空間和約束退子,同時(shí)也需要aop的
                使用tx:advice標(biāo)簽配置事務(wù)通知
                    屬性:
                        id:給事務(wù)通知起一個(gè)唯一標(biāo)識(shí)
                        transaction-manager:給事務(wù)通知提供一個(gè)事務(wù)管理器引用
        3岖妄、配置AOP中的通用切入點(diǎn)表達(dá)式
        4、建立事務(wù)通知和切入點(diǎn)表達(dá)式的對(duì)應(yīng)關(guān)系
        5寂祥、配置事務(wù)的屬性
               是在事務(wù)的通知tx:advice標(biāo)簽的內(nèi)部

     -->
    <!-- 配置事務(wù)管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!-- 配置事務(wù)的通知-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <!-- 配置事務(wù)的屬性
                isolation:用于指定事務(wù)的隔離級(jí)別荐虐。默認(rèn)值是DEFAULT,表示使用數(shù)據(jù)庫的默認(rèn)隔離級(jí)別丸凭。
                propagation:用于指定事務(wù)的傳播行為福扬。默認(rèn)值是REQUIRED,表示一定會(huì)有事務(wù)惜犀,增刪改的選擇铛碑。查詢方法可以選擇SUPPORTS。
                read-only:用于指定事務(wù)是否只讀虽界。只有查詢方法才能設(shè)置為true亚茬。默認(rèn)值是false,表示讀寫浓恳。
                timeout:用于指定事務(wù)的超時(shí)時(shí)間刹缝,默認(rèn)值是-1碗暗,表示永不超時(shí)。如果指定了數(shù)值梢夯,以秒為單位言疗。
                rollback-for:用于指定一個(gè)異常,當(dāng)產(chǎn)生該異常時(shí)颂砸,事務(wù)回滾噪奄,產(chǎn)生其他異常時(shí),事務(wù)不回滾人乓。沒有默認(rèn)值勤篮。表示任何異常都回滾。
                no-rollback-for:用于指定一個(gè)異常色罚,當(dāng)產(chǎn)生該異常時(shí)碰缔,事務(wù)不回滾,產(chǎn)生其他異常時(shí)事務(wù)回滾戳护。沒有默認(rèn)值金抡。表示任何異常都回滾。
        -->
        <tx:attributes>
            <tx:method name="*" propagation="REQUIRED" read-only="false"/>
            <tx:method name="find*" propagation="SUPPORTS" read-only="true"></tx:method>
        </tx:attributes>
    </tx:advice>

    <!-- 配置aop-->
    <aop:config>
        <!-- 配置切入點(diǎn)表達(dá)式-->
        <aop:pointcut id="pt1" expression="execution(* com.itheima.service.impl.*.*(..))"></aop:pointcut>
        <!--建立切入點(diǎn)表達(dá)式和事務(wù)通知的對(duì)應(yīng)關(guān)系 -->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pt1"></aop:advisor>
    </aop:config>

  • spring-framework-5.0.02.RELEASE
  • xmlns
  • xsi
  • xsi:schemaLocation
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末腌且,一起剝皮案震驚了整個(gè)濱河市梗肝,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌铺董,老刑警劉巖巫击,帶你破解...
    沈念sama閱讀 211,042評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異精续,居然都是意外死亡坝锰,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門驻右,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人崎淳,你說我怎么就攤上這事堪夭。” “怎么了拣凹?”我有些...
    開封第一講書人閱讀 156,674評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵森爽,是天一觀的道長。 經(jīng)常有香客問我嚣镜,道長爬迟,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,340評(píng)論 1 283
  • 正文 為了忘掉前任菊匿,我火速辦了婚禮付呕,結(jié)果婚禮上计福,老公的妹妹穿的比我還像新娘。我一直安慰自己徽职,他們只是感情好象颖,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著姆钉,像睡著了一般说订。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上潮瓶,一...
    開封第一講書人閱讀 49,749評(píng)論 1 289
  • 那天陶冷,我揣著相機(jī)與錄音,去河邊找鬼毯辅。 笑死埂伦,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的悉罕。 我是一名探鬼主播赤屋,決...
    沈念sama閱讀 38,902評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼壁袄!你這毒婦竟也來了类早?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,662評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤嗜逻,失蹤者是張志新(化名)和其女友劉穎涩僻,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體栈顷,經(jīng)...
    沈念sama閱讀 44,110評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡逆日,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了萄凤。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片室抽。...
    茶點(diǎn)故事閱讀 38,577評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖靡努,靈堂內(nèi)的尸體忽然破棺而出坪圾,到底是詐尸還是另有隱情,我是刑警寧澤惑朦,帶...
    沈念sama閱讀 34,258評(píng)論 4 328
  • 正文 年R本政府宣布兽泄,位于F島的核電站,受9級(jí)特大地震影響漾月,放射性物質(zhì)發(fā)生泄漏病梢。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評(píng)論 3 312
  • 文/蒙蒙 一梁肿、第九天 我趴在偏房一處隱蔽的房頂上張望蜓陌。 院中可真熱鬧觅彰,春花似錦、人聲如沸护奈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽霉旗。三九已至痴奏,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間厌秒,已是汗流浹背读拆。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評(píng)論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留鸵闪,地道東北人檐晕。 一個(gè)月前我還...
    沈念sama閱讀 46,271評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像蚌讼,于是被迫代替她去往敵國和親辟灰。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 本章內(nèi)容: 面向切面編程的基本原理 通過POJO創(chuàng)建切面 使用@AspectJ注解 為AspectJ切面注入依賴 ...
    謝隨安閱讀 3,132評(píng)論 0 9
  • **** AOP 面向切面編程 底層原理 代理4凼=胬! 今天AOP課程1凰萨、 Spring 傳統(tǒng) AOP2继控、 Spri...
    luweicheng24閱讀 1,359評(píng)論 0 1
  • IoC 容器 Bean 的作用域 自定義作用域?qū)崿F(xiàn) org.springframework.beans.facto...
    Hsinwong閱讀 2,458評(píng)論 0 7
  • 概述 Spring是什么? Spring是一個(gè)開源框架胖眷,為了解決企業(yè)應(yīng)用開發(fā)的復(fù)雜性而創(chuàng)建的武通,但是現(xiàn)在已經(jīng)不止于企...
    瑯筑閱讀 1,157評(píng)論 2 8
  • 今天晚上帶快五歲的女兒去公園放風(fēng)。一到珊搀,就碰到一個(gè)之前有一起玩過的六歲多小男孩冶忱。男孩很開心的來找女兒,兩人玩了一會(huì)...
    自在陽子閱讀 202評(píng)論 0 2