Spring注入、Spring AOP实现2

一、Java集合框架

1、集合框架

image.png

  • 各种集合框架的关系如上图所示,List有序可重复,Set无序不重复,ArrayList的父类是AbstractList,关于三种集合添加元素返回值

    • List调用add()永远返回的是true
    • Set调用add()如果是第一次添加返回的是true,否则返回false
    • map的键值都可以为null,调用put方法如果是覆盖的话返回上一个值,如果是新添加的话返回null。所以返回null有两种情况,一种是之前没有这个key,另外一种是这个key对应的value是null。
  • Java 集合类:list、set、queue、map、stack 的特点与用法?

    • Map
      • Map 是键值对,键 Key 是唯一不能重复的,一个键对应一个值,值可以重复。
      • TreeMap 可以保证顺序,HashMap 不保证顺序,即为无序的,
      • Map 中可以将 Key 和 Value 单独抽取出来,其中 KeySet()方法可以将所有的 keys 抽取成一个 Set,而 Values()方法可以将 map 中所有的 values 抽取成一个集合。
    • Set
      • 不包含重复元素的集合,set 中最多包含一个 null 元素,只能用 Iterator 实现单项遍历, Set 中没有同步方法。
    • List
      • 有序的可重复集合,可以在任意位置增加删除元素,用 Iterator 实现单向遍历,也可用ListIterator 实现双向遍历。
    • Queue
      • Queue 遵从先进先出原则,使用时尽量避免 add()和 remove()方法,而是使用 offer()来添加元素,使用 poll()来移除元素,它的优点是可以通过返回值来判断是否成功,LinkedList实现了 Queue 接口,Queue 通常不允许插入 null 元素。
    • Stack
      • Stack 遵从后进先出原则,Stack 继承自 Vector,它通过五个操作对类 Vector 进行扩展允许将向量视为堆栈,它提供了通常的 push 和 pop 操作,以及取堆栈顶点的 peek()方法、测试堆栈是否为空的 empty 方法等。
    • 用法
      • 如果涉及堆栈,队列等操作,建议使用 List。
      • 对于快速插入和删除元素的,建议使用 LinkedList。如果需要快速随机访问元素的,建议使用ArrayList。
  • 接口里面的变量必须是公开、静态的常量(public static final)

  • 权限修饰符、static、final这三个修饰符的位置可以任意交换

二、“集合”注入

  • Spring对于数组、List、Set、Map与Properties五种数据类型的注入需要特别说明。
<?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标签对对象成员进行赋值是调用setter方法
  • constructor-arg标签的赋值方式是使用构造方法
  • 八个基本数据类型加上String都是使用value进行赋值的,其他类型的引用数据类型都是使用ref方式进行赋值

三、Spring AOP

1、第四种方式:config方式

  • 基于xml文件,和第三种方式类似,但可以根据方法返回值、包、类、方法与方法参数进行匹配,让符合条件的类或者方法进行动态代理
  • 可以指定代理方式:采用Java原生的动态代理还是cglib的动态代理。
    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);
    /**
     * 根据用户uid删除该uid对应的用户信息
     * @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下所有的任意类,类下的任意含参不含参数的方法,返回值必须为List的方法将会被代理
            <aop:pointcut id="pt" expression="execution(java.util.List com.aop4.*.*(..))" />
            该包com.aop4下所有的任意类,类下的任意含参不含参数的方法,返回值必须为boolean的方法将会被代理
            <aop:pointcut id="pt" expression="execution(boolean com.aop4.*.*(..))" />
            com.aop4.UserServiceImpl.deleteUser(int)具体的方法了,参数为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与切点关联起来 -->
        <aop:advisor advice-ref="ma" pointcut-ref="pt" />
    </aop:config>
</beans>
  • proxy-target-class设置为true,强制使用cglib方式来实现动态代理

2、第五种方式

  • 使用-xml通知,代理类不需要实现接口。
    IUserService.java
public interface IUserService {
    /**
     * 获取所有的用户对象列表
     * @return
     */
    List<Object> getAllUser();
    /**
     * 保存用户
     * @param user
     * @return
     */
    boolean saveUser(Object user);
    /**
     * 根据用户uid删除该uid对应的用户信息
     * @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());
    }
}
  • 五种通知方式来实现aop
      1. 前置通知,在业务方法之前执行
      1. 后置通知,在业务方法之后执行
      1. 环绕通知,同时在业务方法的前后执行
      1. 带有返回值通知,可以拿到业务方法的返回值
      1. 异常通知,可以捕获业务方法中的异常对象
    • 注意:如果同时配置来所有的通知方式,则执行顺序依次为:
    • before>around before>业务方法 >after returning > around after > after
    • before>around before>业务方法 >after throwing > after
    • ps. 使用注解的话是环绕通知proceed方法之前部分先执行,使用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的位置的集合,指名执行advice的触发条件
  • advice:可以理解为代理方法的实现,向切点注入的代码
  • advisor:pointcut和advice的配置器,将advice注入到pointcut的位置

良心zuo教育的千锋 个人学习总结

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,884评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,212评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,351评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,412评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,438评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,127评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,714评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,636评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,173评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,264评论 3 339
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,402评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,073评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,763评论 3 332
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,253评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,382评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,749评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,403评论 2 358

推荐阅读更多精彩内容