上期,我們看到有小伙伴留言說希望講講AOP
然后......

別激動,來得及

什么是AOP
AOP是Spring 框架的一個關鍵組件,全稱為Aspect-OrientedProgramming(面向切面編程),目前已是一種比較成熟的編程方式。
AOP采取橫向抽取機制,將分散在各個方法中的重復代碼提取出來,然后在編譯或運行的時候,再將這些代碼應用到需要執行的地方。
注:提取出來的代碼應用到需要執行的地方,並不會把源代碼加到需要的地方執行,即源代碼文件不會更改,但是它會影響最終的機器編譯代碼

意思就是,有一些通用功能的代碼可以提取出來,然后在使用的時候應用進去就可以了,比如表單驗證和日志記錄等等
AOP術語
Aspect(切面)
通常指封裝起來用於插入到指定位置實現某項功能的類
Join point(連接點)
在SpringAOP中,連接點指方法的調用
Pointcut(切入點)
切面與程序流程的交叉點,即那些需要處理的連接點,通常在程序中,切入點指的是類或者方法名
Advice(通知/增強處理)
就是程序實際運行之前或之后執行的方法,也就是AOP加入的代碼
Target Object(目標對象)
即需要加入AOP代碼的對象
Proxy(代理)
AOP框架動態生成的一個對象,該對象可以作為目標對象使用
Weaving(織入)
把切面連接到其它的應用程序類型或者對象上,並創建一個需要Advice對象的過程

看不懂就先往下看,關於術語等自己會了,自然就好理解多了
這時......
阿音過來知道了小知在學AOP
於是......
阿音非要展示一個關於AOP的小例子




UserDao接口
package com.aop.jdk;
public interface UserDao {
public void addUser();
}
UserDaoImpl
package com.aop.jdk;
public class UserDaoImpl implements UserDao {
@Override
public void addUser() {
System.out.println("新增用戶");
}
}
JdkProxy
package com.aop.jdk;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import com.aop.aspect.MyAspect;
/**
* JDK代理類
*/
public class JdkProxy implements InvocationHandler{
// 聲明目標類接口
private UserDao userDao;
// 創建代理方法
public Object createProxy(UserDao userDao) {
this.userDao = userDao;
// 1.類加載器
ClassLoader classLoader = JdkProxy.class.getClassLoader();
// 2.被代理對象實現的所有接口
@SuppressWarnings("rawtypes")
Class[] clazz = userDao.getClass().getInterfaces();
// 3.使用代理類,進行增強,返回的是代理后的對象
return Proxy.newProxyInstance(classLoader,clazz,this);
}
/*
* 所有動態代理類的方法調用,都會交由invoke()方法去處理
* proxy 被代理后的對象
* method 將要執行的方法
* args 執行方法時需要的參數
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// 聲明切面
MyAspect myAspect = new MyAspect();
// 指定位置程序執行前執行這個方法
myAspect.start();
// 在目標類上調用方法
Object obj = method.invoke(userDao, args);
// 指定位置程序執行結束后執行
myAspect.end();
return obj;
}
}
MyAspect
package com.aop.aspect;
/**
* 切面
*/
public class MyAspect {
public void start(){
System.out.println("模擬事務處理功能 ...");
}
public void end(){
System.out.println("程序結束后執行此處 ...");
}
}
JdkTest
測試結果項目編寫完之后運行該類
package com.aop.test;
import com.aop.jdk.JdkProxy;
import com.aop.jdk.UserDao;
import com.aop.jdk.UserDaoImpl;
public class JdkTest {
public static void main(String[] args) {
// 創建代理對象
JdkProxy jdkProxy = new JdkProxy();
// 創建目標對象
UserDao userDao= new UserDaoImpl();
// 從代理對象中獲取增強后的目標對象
UserDao userDao1 = (UserDao) jdkProxy.createProxy(userDao);
// 執行方法
userDao1.addUser();
}
}

運行之后,我們可以看到以下結果:


我們可以看到,在我們執行新增用戶的方法時,依據我們AOP編程,系統自動執行了start方法和end方法
在實際運用中,我們可以把一些通用的方法放到start和end的位置,在需要的方法處加入切面即可
此外,建議大家再了解下AspectJ
AspectJ實現AOP有兩種方式:一種是基於XML的聲明式,另一種是基於注解的聲明式
基於XML的聲明式AspectJ要便捷一些,但是存在配置信息多的缺點
基於注解的聲明式AspectJ則通過注解的方式減少了很多配置信息
