Spring“集合”注入蔚万、Spring AOP實現(xiàn)(2)

一篮绰、Java集合框架

1、集合框架

  • Java Collections Framework2.png
  • 各種集合框架的關(guān)系如上圖所示乌逐,List有序可重復(fù)玛荞,Set無序不重復(fù)秉沼,ArrayList的父類是AbstractList梭冠,關(guān)于三種集合添加元素返回值

    • List調(diào)用add()永遠返回的是true
    • Set調(diào)用add()如果是第一次添加返回的是true辕狰,否則返回false
    • map的鍵值都可以為null,調(diào)用put方法如果是覆蓋的話返回上一個值控漠,如果是新添加的話返回null蔓倍。所以返回null有兩種情況,一種是之前沒有這個key盐捷,另外一種是這個key對應(yīng)的value是null柬脸。
  • Java 集合類:list、set毙驯、queue、map灾测、stack 的特點與用法爆价?

    • Map
      • Map 是鍵值對垦巴,鍵 Key 是唯一不能重復(fù)的,一個鍵對應(yīng)一個值铭段,值可以重復(fù)骤宣。
      • TreeMap 可以保證順序,HashMap 不保證順序序愚,即為無序的憔披,
      • Map 中可以將 Key 和 Value 單獨抽取出來,其中 KeySet()方法可以將所有的 keys 抽取成一個 Set爸吮,而 Values()方法可以將 map 中所有的 values 抽取成一個集合芬膝。
    • Set
      • 不包含重復(fù)元素的集合,set 中最多包含一個 null 元素形娇,只能用 Iterator 實現(xiàn)單項遍歷锰霜, Set 中沒有同步方法。
    • List
      • 有序的可重復(fù)集合桐早,可以在任意位置增加刪除元素癣缅,用 Iterator 實現(xiàn)單向遍歷,也可用ListIterator 實現(xiàn)雙向遍歷哄酝。
    • Queue
      • Queue 遵從先進先出原則友存,使用時盡量避免 add()和 remove()方法,而是使用 offer()來添加元素,使用 poll()來移除元素陶衅,它的優(yōu)點是可以通過返回值來判斷是否成功屡立,LinkedList實現(xiàn)了 Queue 接口,Queue 通常不允許插入 null 元素万哪。
    • Stack
      • Stack 遵從后進先出原則侠驯,Stack 繼承自 Vector,它通過五個操作對類 Vector 進行擴展允許將向量視為堆棧奕巍,它提供了通常的 push 和 pop 操作吟策,以及取堆棧頂點的 peek()方法、測試堆棧是否為空的 empty 方法等的止。
    • 用法
      • 如果涉及堆棧檩坚,隊列等操作,建議使用 List诅福。
      • 對于快速插入和刪除元素的匾委,建議使用 LinkedList。如果需要快速隨機訪問元素的氓润,建議使用ArrayList赂乐。
  • 接口里面的變量必須是公開、靜態(tài)的常量(public static final)

  • 權(quán)限修飾符咖气、static挨措、final這三個修飾符的位置可以任意交換

二挖滤、“集合”注入

  • Spring對于數(shù)組、List浅役、Set斩松、Map與Properties五種數(shù)據(jù)類型的注入需要特別說明。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <property name="arrays">
        <array>
            <value>java</value>
            <value>html5</value>
        </array>
    </property>
    <property name="list">
        <list>
            <value>aaa</value>
            <ref bean="obj"/> 
        </list>
    </property>
    <property name="set">
        <set>
            <value>aaa</value>
            <value>bbb</value>
        </set>
    </property>
    <property name="map">
        <map>
            <entry key="a" value="aab"/>
            <entry key="b" value="bbb"/>
        </map>
    </property>
    <property name="properties">
        <props>
            <prop key="username">cc</prop>
            <prop key="password">dd</prop>
        </props>
    </property>
</beans>
  • 使用property標簽對對象成員進行賦值是調(diào)用setter方法
  • constructor-arg標簽的賦值方式是使用構(gòu)造方法
  • 八個基本數(shù)據(jù)類型加上String都是使用value進行賦值的觉既,其他類型的引用數(shù)據(jù)類型都是使用ref方式進行賦值

三惧盹、Spring AOP

1、第四種方式:config方式

  • 基于xml文件瞪讼,和第三種方式類似钧椰,但可以根據(jù)方法返回值、包尝艘、類演侯、方法與方法參數(shù)進行匹配,讓符合條件的類或者方法進行動態(tài)代理
  • 可以指定代理方式:采用Java原生的動態(tài)代理還是cglib的動態(tài)代理背亥。
    Caused by: java.lang.NoClassDefFoundError: org/aspectj/weaver/reflect/ReflectionWorld$ReflectionWorldException
<!--在pom.xml添加依賴-->
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>com.springsource.org.aspectj.weaver</artifactId>
    <version>1.6.8.RELEASE</version>
</dependency>

IUserService.java

public interface IUserService {
    /**
     * 獲取所有的用戶對象列表
     * @return
     */
    List<Object> getAllUser();
    /**
     * 保存用戶
     * @param user
     * @return
     */
    boolean saveUser(Object user);
    /**
     * 根據(jù)用戶uid刪除該uid對應(yīng)的用戶信息
     * @param uid
     * @return
     */
    boolean deleteUser(int uid);
    /**
     * 更新指定用戶信息
     * @param obj
     * @return
     */
    boolean updateUser(Object obj);
}

UserServiceImpl.java

public class UserServiceImpl implements IUserService {
    @Override
    public List<Object> getAllUser() {
        System.out.println("--------getAllUser----------");
        return new ArrayList<>();
    }
    @Override
    public boolean saveUser(Object user) {
        System.out.println("--------saveUser----------");
        return true;
    }
    @Override
    public boolean deleteUser(int uid) {
        System.out.println("--------deleteUser----------");
        return false;
    }
    @Override
    public boolean updateUser(Object obj) {
        System.out.println("--------updateUser----------");
        return true;
    }
}

MyAspect.java

public class MyAspect implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        System.out.println("-----------before----------");
        Object obj = invocation.proceed();
        System.out.println("-----------after----------");
        return obj;
    }
}

TestAOP4.java

public class TestAOP4 {
    @Test
    public void test(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("com/aop4/beans.xml");
        IUserService us = ac.getBean("us", IUserService.class);
        us.getAllUser();
        us.deleteUser(1);
        us.updateUser(new Object());
        us.saveUser(new Object());
    }
}

beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">
    <bean id="us" class="com.aop4.UserServiceImpl"/>
    <bean id="ma" class="com.aop4.MyAspect" />
    <aop:config proxy-target-class="true">
        <!--
            定義一個aop的切點
            該包com.aop4下所有的任意類秒际,類下的任意含參不含參數(shù)的方法,返回值必須為List的方法將會被代理
            <aop:pointcut id="pt" expression="execution(java.util.List com.aop4.*.*(..))" />
            該包com.aop4下所有的任意類狡汉,類下的任意含參不含參數(shù)的方法娄徊,返回值必須為boolean的方法將會被代理
            <aop:pointcut id="pt" expression="execution(boolean com.aop4.*.*(..))" />
            com.aop4.UserServiceImpl.deleteUser(int)具體的方法了,參數(shù)為int盾戴,返回值任意
            <aop:pointcut id="pt" expression="execution(* com.aop4.UserServiceImpl.deleteUser(int))" />
            多個條件
            <aop:pointcut id="pt" expression="(execution(boolean com.aop4.*.*(..)) or (execution(java.util.List com.aop4.*.*(..))))" />
        -->
        <aop:pointcut id="pt" expression="(execution(boolean com.aop4.*.*(..)) or (execution(java.util.List com.aop4.*.*(..))))" />
        <!-- 通知寄锐,將MyAspect與切點關(guān)聯(lián)起來 -->
        <aop:advisor advice-ref="ma" pointcut-ref="pt" />
    </aop:config>
</beans>
  • proxy-target-class設(shè)置為true,強制使用cglib方式來實現(xiàn)動態(tài)代理

2尖啡、第五種方式

  • 使用-xml通知橄仆,代理類不需要實現(xiàn)接口。
    IUserService.java
public interface IUserService {
    /**
     * 獲取所有的用戶對象列表
     * @return
     */
    List<Object> getAllUser();
    /**
     * 保存用戶
     * @param user
     * @return
     */
    boolean saveUser(Object user);
    /**
     * 根據(jù)用戶uid刪除該uid對應(yīng)的用戶信息
     * @param uid
     * @return
     */
    boolean deleteUser(int uid);
    /**
     * 更新指定用戶信息
     * @param obj
     * @return
     */
    boolean updateUser(Object obj);
    void getUserByUid();
}

UserServiceImpl.java

public class UserServiceImpl implements IUserService {
    @Override
    public List<Object> getAllUser() {
        System.out.println("--------getAllUser----------");
        return new ArrayList<>();
    }
    @Override
    public boolean saveUser(Object user) {
        System.out.println("--------saveUser----------");
        return true;
    }
    @Override
    public boolean deleteUser(int uid) {
        System.out.println("--------deleteUser----------");
        return false;
    }
    @Override
    public boolean updateUser(Object obj) {
        System.out.println("--------updateUser----------");
        return true;
    }
    @Override
    public void getUserByUid() {
        System.out.println("--------getUserByUid----------");
        System.out.println(1 / 0);
        String str = null;
        System.out.println(str.length());
    }
}
  • 五種通知方式來實現(xiàn)aop
      1. 前置通知衅斩,在業(yè)務(wù)方法之前執(zhí)行
      1. 后置通知盆顾,在業(yè)務(wù)方法之后執(zhí)行
      1. 環(huán)繞通知,同時在業(yè)務(wù)方法的前后執(zhí)行
      1. 帶有返回值通知畏梆,可以拿到業(yè)務(wù)方法的返回值
      1. 異常通知您宪,可以捕獲業(yè)務(wù)方法中的異常對象
    • 注意:如果同時配置來所有的通知方式,則執(zhí)行順序依次為:
    • before>around before>業(yè)務(wù)方法 >after returning > around after > after
    • before>around before>業(yè)務(wù)方法 >after throwing > after
    • ps. 使用注解的話是環(huán)繞通知proceed方法之前部分先執(zhí)行奠涌,使用xml配置的話取決于aop:before和aop:around的配置順序

MyAspect.java

public class MyAspect {
    public void myBefore(JoinPoint jp){
//      System.out.println("args " + Arrays.toString(jp.getArgs()));
//      System.out.println("toString " + jp.toString());
//      System.out.println("getTarget " + jp.getTarget());
        System.out.println("this is before.");
    }
    public void myAfter(JoinPoint jp){
        System.out.println("this is after.");
    }
    public Object myAround(ProceedingJoinPoint pjp){
        try {
            System.out.println("this is around before");
            Object obj = pjp.proceed();
            System.out.println("this is around after " + obj);
            return obj;
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return null;
    }
    /**
     * 帶有返回值的通知
     * @param jp
     * @param obj 配置文件中的obj
     */
    public void myReturn(JoinPoint jp, Object obj){
        System.out.println("this is after returning " + obj);
    }
    public void myThrow(JoinPoint jp, Throwable e){
        System.out.println("this is after throwing " + e.getMessage());
    }
}

TestAOP5.java

public class TestAOP5 {
    @Test
    public void test(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("com/aop5/beans.xml");
        IUserService us = ac.getBean("us", IUserService.class);
        us.updateUser(new Object());
        us.getAllUser();
        us.saveUser(new Object());
        us.deleteUser(1);
        us.getUserByUid();
    }
}

beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">
    <bean id="us" class="com.aop5.UserServiceImpl"/>
    <bean id="ma" class="com.aop5.MyAspect" />
    <aop:config proxy-target-class="true">
        <aop:aspect ref="ma">
            <aop:pointcut id="mpc" expression="execution(* com.aop5.*.*(..))" />
            <aop:around method="myAround" pointcut-ref="mpc" />
            <aop:before method="myBefore" pointcut-ref="mpc"/>
            <aop:after method="myAfter" pointcut-ref="mpc" />
            <aop:after-returning method="myReturn" pointcut-ref="mpc" returning="obj" />
            <aop:after-throwing method="myThrow" pointcut-ref="mpc" throwing="e" />
        </aop:aspect>
    </aop:config>
</beans>
  • pointcut切點:程序中需要注入advice的位置的集合,指名執(zhí)行advice的觸發(fā)條件
  • advice:可以理解為代理方法的實現(xiàn),向切點注入的代碼
  • advisor:pointcut和advice的配置器,將advice注入到pointcut的位置
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末宪巨,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子溜畅,更是在濱河造成了極大的恐慌捏卓,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件慈格,死亡現(xiàn)場離奇詭異天吓,居然都是意外死亡贿肩,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進店門龄寞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人汤功,你說我怎么就攤上這事物邑。” “怎么了滔金?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵色解,是天一觀的道長。 經(jīng)常有香客問我餐茵,道長科阎,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任忿族,我火速辦了婚禮锣笨,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘道批。我一直安慰自己错英,他們只是感情好,可當我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布隆豹。 她就那樣靜靜地躺著椭岩,像睡著了一般。 火紅的嫁衣襯著肌膚如雪璃赡。 梳的紋絲不亂的頭發(fā)上判哥,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天,我揣著相機與錄音碉考,去河邊找鬼塌计。 笑死,一個胖子當著我的面吹牛豆励,可吹牛的內(nèi)容都是我干的夺荒。 我是一名探鬼主播,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼良蒸,長吁一口氣:“原來是場噩夢啊……” “哼技扼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起嫩痰,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤剿吻,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后串纺,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體丽旅,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡椰棘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了榄笙。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片邪狞。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖茅撞,靈堂內(nèi)的尸體忽然破棺而出帆卓,到底是詐尸還是另有隱情,我是刑警寧澤米丘,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布剑令,位于F島的核電站,受9級特大地震影響拄查,放射性物質(zhì)發(fā)生泄漏吁津。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一堕扶、第九天 我趴在偏房一處隱蔽的房頂上張望碍脏。 院中可真熱鬧,春花似錦挣柬、人聲如沸潮酒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽急黎。三九已至,卻和暖如春侧到,著一層夾襖步出監(jiān)牢的瞬間勃教,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工匠抗, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留故源,地道東北人。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓汞贸,卻偏偏與公主長得像绳军,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子矢腻,可洞房花燭夜當晚...
    茶點故事閱讀 44,914評論 2 355