Spring第二天

類掃描注解

案例

1、創(chuàng)建實(shí)例(Persion和Student)

@Component("persion")//相當(dāng)于<bean id = "persion" class = "../Persion"></bean>
public class Persion {
    @Resource(name = "student")
    private Student student;
    public void say(){
        student.say();
    }
}


@Component("student")
public class Student {
    public void say(){
        System.out.println("student");
    }
}

2、配置文件進(jìn)行配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       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-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd">
      <context:component-scan base-package="spring.com.bxp.bean"></context:component-scan>
</beans>

3、測(cè)試

public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Persion persion = (Persion) context.getBean("persion");
        persion.say();
    }  
步驟:

1、啟動(dòng)Spring容器
2、Spring容器解析到類掃描注解解析器<context:component-scan base-package="spring.com.bxp.bean"></context:component-scan>的時(shí)候,在base-package指定的包及其子包下查找所有的類
3、查看哪些類上面含有@Component
4、如果注解的value屬性的值為空,則把類名的第一個(gè)字母變?yōu)樾?,作為id值,放入到Spring容器中
5、如果value屬性的值不為空,則使用value的值作為id值,放入到spring容器中。
6、在查找spring中的類的所有屬性,按照@Resource的規(guī)則進(jìn)行查找。
綜上所述,使用了類掃描機(jī)制的做法,配置文件中配置很簡(jiǎn)單,但是效率越來越低。

繼承

案例1

1、創(chuàng)建實(shí)例(Book, Persion, Student)

public class Book {
    public void read(){
        System.out.println("閱讀書籍");
    }
}


public class Persion {
    private Book book;
    
    public Book getBook() {
        return book;
    }

    public void setBook(Book book) {
        this.book = book;
    }

    public void read(){
        book.read();
    }
}


public class Student extends Persion{
    
}

2、配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       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-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd">


        <bean id="persion" class="spring.com.bxp.bean.Persion">
            <property name="bok" ref="book"></property>
        </bean>
        <bean id="student" class="spring.com.bxp.bean.Student"></bean>
        <bean id="book" class="spring.com.bxp.bean.Book"></bean>
</beans>

3、測(cè)試

public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Student student = (Student) context.getBean("student");
        student.read();
    }  

運(yùn)行結(jié)果出錯(cuò),空指針,說明在student中沒有繼承persion中book屬性的值。
解決辦法,在配置文件的student的bean上添加屬性parent

<bean id="student" class="spring.com.bxp.bean.Student" parent="persion"></bean>
案例二

1、創(chuàng)建實(shí)例

@Component
public class Book {
    public void read(){
        System.out.println("閱讀書籍");
    }
}

@Component
public class Persion {
    @Resource(name = "book")
    private Book book;

    public void read(){
        book.read();
    }
}


@Component
public class Student extends Persion{
    
}

2、配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    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-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd">

    <context:component-scan base-package="spring.com.bxp.bean"></context:component-scan>
</beans>

3、測(cè)試

public class Test {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Student student = (Student) context.getBean("student");
        student.read();
    }  
}

運(yùn)行結(jié)果正確

綜上連個(gè)案例:在使用繼承的過程中,在配置文件中給屬性賦值,需要使用parent屬性。使用注解給屬性賦值,則不需要。

AOP

切入點(diǎn)表達(dá)式
切入點(diǎn)表達(dá)式對(duì)應(yīng)圖

execution(public * *(..)):所有的公共方法
execution(* set*(..)) :代表所有的以set開頭的方法
execution(* com.xyz.server.AccountServer.*(..)):代表com.xyz.server包下的AccountServer類中的所有方法
execution( * com.xyz.server.*.*(..)):代表con.xyz.server包下的所有類中的所有方法
execution( * com.xyz.server..*.*(..)):代表con.xyz.server包及其子包下的所有類中的所有方法

第一個(gè)AOP程序

引入兩個(gè)jar包

aspectjrt.jar
aspectjweaver.jar

1、創(chuàng)建對(duì)象

public interface Dao {
    void save();
    void update();
}


public  class DaoImpl implements Dao{
    @Override
    public void save() {
        System.out.println("保存數(shù)據(jù)");
        /**
         * 此處書寫保存全部數(shù)據(jù)數(shù)據(jù)的程序
         */
    }

    @Override
    public void update() {
        /**
         * 此處書寫更新數(shù)據(jù)的程序
         */
    }

}


public class Transaction {
    public void open(){
        System.out.println("開啟事物");
    }
    public void commit(){
        System.out.println("提交事物");
    }
}

2、創(chuàng)建配置文件
引入以下名稱空間:

xmlns:aop="http://www.springframework.org/schema/aop"

http://www.springframework.org/schema/aop 
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:aop="http://www.springframework.org/schema/aop"
       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-2.5.xsd
           http://www.springframework.org/schema/aop 
           http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
           
    <bean id="daoimpl" class="spring.com.bxp.proxy.DaoImpl"></bean>
    <bean id="transaction" class="spring.com.bxp.proxy.Transaction"></bean>
    
    
    <aop:config>
    <!-- 切入點(diǎn) -->
        <aop:pointcut expression="execution(* spring.com.bxp.proxy.DaoImpl.*(..))"
         id="perform"/>
         <!-- 切面 -->
        <aop:aspect ref="transaction" >
            <!-- aop:before:前置通知 
            aop:after-returning:后置通知
            pointcut-ref:指向切入點(diǎn)表達(dá)式
            -->
            <aop:before pointcut-ref="perform" method="open"/>
            <aop:after-returning pointcut-ref="perform" method="commit"/>
        </aop:aspect>
    </aop:config>


</beans>

3、測(cè)試類

public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        
        Dao dao = (Dao) context.getBean("daoimpl");
        dao.save();
    }
AOP步驟:

1、啟動(dòng)spring容器
2、實(shí)例化bean對(duì)象
3、spring容器 解析aop配置
(1)切入點(diǎn)表達(dá)式:把id對(duì)應(yīng)的類包含進(jìn)spring容器
(2)前置通知,后置通知
4、spring容器會(huì)按照切入點(diǎn)表達(dá)式所匹配的類在spring容器中進(jìn)行查找,如果找到該類,則會(huì)創(chuàng)建代理對(duì)象,如果找不到,則報(bào)錯(cuò)。
5、spring容器產(chǎn)生代理對(duì)象的方法:通知+目標(biāo)方法
6、客戶端通過context.getBean()得到一個(gè)對(duì)象,如果該對(duì)象有代理,則返回代理對(duì)象,如果沒有代理,則返回對(duì)象本身。

說明:1、客戶端通過context.getBean()得到一個(gè)對(duì)象,如果該對(duì)象有代理,則返回代理對(duì)象,如果沒有代理,則返回對(duì)象本身
2、如果目標(biāo)類實(shí)現(xiàn)了接口,則采用jvm生成代理對(duì)象,如果沒有實(shí)現(xiàn)接口,則采用cglib生成代理對(duì)象,而生成代理對(duì)象時(shí)候spring來做。

spring的通知:

前置通知:具有JoinPoint參數(shù)
    /**
     * 連接點(diǎn),代表一個(gè)方法,客戶端調(diào)用那個(gè)方法,那個(gè)方法就是連接點(diǎn)
     * 
     * 通過參數(shù)可以獲取連接點(diǎn)的一些信息
     * @param joinPoint
     */
    public void open(JoinPoint joinPoint){
        //獲取目標(biāo)類
        joinPoint.getTarget();
        //獲取連接點(diǎn)參數(shù)
        joinPoint.getArgs();
        //獲取連接點(diǎn)的名稱
        joinPoint.getSignature().getName();
        System.out.println("開啟事物");
    }

    <!-- aop:before:前置通知 
    pointcut-ref:指向切入點(diǎn)表達(dá)式
    -->
    <aop:before pointcut-ref="perform" method="open"/>
后置通知:
    /**
     * @param joinPoint:連接點(diǎn)
     * @param val:接受目標(biāo)參數(shù)的返回值
     */
    public void commit(JoinPoint joinPoint, Object val){
        System.out.println("提交事物");
    }

    <!-- 
    aop:after-returning:后置通知
    val:和后置通知方法的參數(shù)名稱保持一致
    -->
    <aop:after-returning pointcut-ref="perform" method="commit" returning="val"/>
        
如果目標(biāo)方法遇到異常,后置通知將不執(zhí)行
最終通知:
    /**
     * 
     * @param joinPoint:連接點(diǎn)
     */
    public void finallyMythod(JoinPoint joinPoint){
        
    }

    <aop:after method="finallyMythod" pointcut-ref="perform"/>
不管目標(biāo)方法是否遇到異常,最終通知都會(huì)執(zhí)行
異常通知:
    /**
     * 
     * @param joinPoint
     * @param throwable:獲取目標(biāo)方法拋出的異常
     */
    public void thowingMythod(JoinPoint joinPoint, Throwable throwable){
        
    }

    <!-- 
    throwing:和通知中的異常參數(shù)名稱相同
     -->
    <aop:after-throwing method="thowingMythod" pointcut-ref="perform" throwing="throwable"/>
環(huán)繞通知:
    public void arroundMythod(ProceedingJoinPoint joinPoint) throws Throwable{
        joinPoint.proceed();//執(zhí)行目標(biāo)方法
    }

    applicationContext.xml
環(huán)繞通知可以控制目標(biāo)方法的執(zhí)行
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,525評(píng)論 19 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 47,261評(píng)論 6 342
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,633評(píng)論 18 399
  • 上個(gè)星期,在永澄老師的博客上發(fā)現(xiàn)了這個(gè)分享會(huì),特意下載了“朝夕日歷”app來聽這個(gè)分享會(huì)的內(nèi)容,簡(jiǎn)單的記錄了重點(diǎn)內(nèi)...
    盛某閱讀 370評(píng)論 1 0
  • 前幾天在一家餐廳吃飯,服務(wù)員端上來一盤香酥鴨,里面全是香菜。 我:“啊……今天怎么都是香菜呀?” 老公:“哎呀,結(jié)...
    華思語閱讀 561評(píng)論 4 12

友情鏈接更多精彩內(nèi)容