Implementing Before and After Notifications with CGLIB Dynamic Proxy
Dynamic Proxy Implementtaion
/**
* @author Li Yajie
* @date 2024/4/7 10:57
* @description ProxyUtil
*/
public class ProxyUtil {
/**
* JDK Dynamic Proxy
*
* @param target Target object to be proxied
* @param <T>
* @return
*/
@SuppressWarnings("unchecked")
public static <T> T createJDKProxy(@NotNull T target) {
return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
(proxy, method, args) -> method.invoke(target, args)
);
}
/**
*
* @param target Target object for proxy
* @param before Before notification action
* @param after After notification action
* @return Proxied instance
* @param <T>
*/
@SuppressWarnings("unchecked")
public static <T> T createCglibProxy(@NotNull T target, Runnable before, Runnable after) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(target.getClass());
enhancer.setCallback((MethodInterceptor) (obj, method, args, proxy) -> {
before.run();
Object result = proxy.invokeSuper(obj, args);
after.run();
return result;
});
return (T) enhancer.create();
}
}
Test method
@Test
public void test02(){
UserServiceImpl service = new UserServiceImpl();
UserServiceImpl proxy = ProxyUtil.createCglibProxy(service,
()-> System.out.println("Before notification"),
() -> System.out.println("After notification")
);
proxy.insert(new User());
}
Output
The function interface can also be changed to Function<T,R> to achieve pre-interception.
Code example:
@SuppressWarnings("unchecked")
public static <T> T createCglibProxy(@NotNull T target, Function<Object[],Boolean> before, Runnable after) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(target.getClass());
enhancer.setCallback((MethodInterceptor) (obj, method, args, proxy) -> {
if (!before.apply(args)) {
return null;
}
Object result = proxy.invokeSuper(obj, args);
after.run();
return result;
});
return (T) enhancer.create();
}
Test code
@Test
public void test02() {
UserServiceImpl service = new UserServiceImpl();
UserServiceImpl proxy = ProxyUtil.createCglibProxy(service,
(args) -> {
System.out.println("Pre-interception");
User user = (User) args[0];
return user != null;
},
() -> System.out.println("After notification")
);
proxy.insert(null);
System.out.println("_________");
proxy.insert(new User());
}
Test output
Interception behavior achieved through a functioanl itnerface returning a value