1.JDK動態代理
主要使用到?InvocationHandler?接口和?Proxy.newProxyInstance()?方法。?JDK動態代理要求被代理實現一個接口,只有接口中的方法才能夠被代理?。其方法是將被代理對象注入到一個中間對象,而中間對象實現InvocationHandler接口,在實現該接口時,可以在?被代理對象調用它的方法時,在調用的前后插入一些代碼。而?Proxy.newProxyInstance()?能夠利用中間對象來生產代理對象。插入的代碼就是切面代碼。所以使用JDK動態代理可以實現AOP。
下面來看例子
interface
public?interface?UserService?{
? ? void?addUser();
? ? String?findUserById();
}
impl
import?com.spring.aop.jdk.service.UserService;
public?class?UserServiceImpl?implements?UserService?{
? ? @Override
? ? public?void?addUser()?{
? ? ? ? System.out.println("start?insert?user?into?database");
? ? }
? ? @Override
? ? public?String?findUserById()?{
? ? ? ? System.out.println("start?find?user?by?userId");
? ? ? ? return?null;
? ? }
}
代理中間類
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class ProxyUtil implements InvocationHandler {
? ? private Object target;//被代理的對象
? ? @Override
? ? public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
? ? ? ? System.out.println("do something before");
? ? ? ? // 調用被代理對象的方法并得到返回值
? ? ? ? Object result = method.invoke(target, args);
? ? ? ? System.out.println("do something after");
? ? ? ? return result;
? ? }
? ? public ProxyUtil(Object target) {
? ? ? ? this.target = target;
? ? }
? ? public Object getTarget() {
? ? ? ? return target;
? ? }
? ? public void setTarget(Object target) {
? ? ? ? this.target = target;
? ? }
}
Test
import java.lang.reflect.Proxy;
import com.spring.aop.jdk.proxy.ProxyUtil;
import com.spring.aop.jdk.service.UserService;
import com.spring.aop.jdk.service.impl.UserServiceImpl;
public class Main {
? ? public static void main(String[] args) {
? ? ? ? Object proxyObject = new UserServiceImpl();
? ? ? ? ProxyUtil proxyUtil = new ProxyUtil(proxyObject);
? ? ? ? UserService userService? = (UserService) Proxy.newProxyInstance(
? ? ? ? Thread.currentThread().getContextClassLoader(),
? ? ? ? UserServiceImpl.class.getInterfaces(), proxyUtil);
? ? ? ? userService.addUser();
? ? ? ? userService.findUserById();
? ? }
}
輸出結果
do something before
start insert user into database
do something after
do something before
start find user by userId
do something after