一篮绰、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赂乐。
- Map
接口里面的變量必須是公開、靜態(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
- 前置通知衅斩,在業(yè)務(wù)方法之前執(zhí)行
- 后置通知盆顾,在業(yè)務(wù)方法之后執(zhí)行
- 環(huán)繞通知,同時在業(yè)務(wù)方法的前后執(zhí)行
- 帶有返回值通知畏梆,可以拿到業(yè)務(wù)方法的返回值
- 異常通知您宪,可以捕獲業(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的位置