1.JDK動態(tài)代理
主要使用到?InvocationHandler?接口和?Proxy.newProxyInstance()?方法响巢。?JDK動態(tài)代理要求被代理實現(xiàn)一個接口,只有接口中的方法才能夠被代理?己英。其方法是將被代理對象注入到一個中間對象鹤耍,而中間對象實現(xiàn)InvocationHandler接口,在實現(xiàn)該接口時弄跌,可以在?被代理對象調(diào)用它的方法時,在調(diào)用的前后插入一些代碼尝苇。而?Proxy.newProxyInstance()?能夠利用中間對象來生產(chǎn)代理對象铛只。插入的代碼就是切面代碼。所以使用JDK動態(tài)代理可以實現(xiàn)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");
? ? ? ? // 調(diào)用被代理對象的方法并得到返回值
? ? ? ? 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();
? ? }
}
輸出結(jié)果
do something before
start insert user into database
do something after
do something before
start find user by userId
do something after