1.静态代理
public class SimpleStaticProxyDemo {
static interface IService{
public void sayHello();
}
static class RealService implements IService{
@Override
public void sayHello() {
System.out.println("hello");
}
}
static class TraceProxy implements IService {
private IService realService;
public TraceProxy(IService realService) {
this.realService = realService;
}
@Override
public void sayHello() {
System.out.println("entering sayHello");
realService.sayHello();
System.out.println("leaving sayHello");
}
}
public static void main(String[] args) {
IService realService = new RealService();
IService proxyService = new TraceProxy(realService);
proxyService.sayHello();
}
}
2.动态代理
基于jdk的动态代理
基于 cglib的动态代理
相同点:都是为了增强某一个类中的方法
不同点:jdk的动态代理要求该类必须有接口, 且只能处理接口中的方法, cglib 没有这个限制
基于jdk的动态代理demo:
public class SimpleJdkDynamicProxyDemo {
static interface IService {
public void sayHello();
}
static class RealService implements IService {
@Override
public void sayHello() {
System.out.println("hello");
}
}
/**
* 对代理对象的调用都会转交给该方法
*/
static class SimpleInvocationHandler implements InvocationHandler{
private Object realObj;
public SimpleInvocationHandler(Object realObj) {
this.realObj = realObj;
}
/**
*
* @param proxy 代理对象本身
* @param method 调用的方法
* @param args 方法的参数
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("entering "+method.getName());
Object result = method.invoke(realObj, args);
System.out.println("leaving "+method.getName());
return result;
}
}
public static void main(String[] args) {
IService realService = new RealService();
IService proxyService = (IService) Proxy.newProxyInstance(
//类加载器
IService.class.getClassLoader(),
//代理类要实现的接口列表
new Class<?>[]{IService.class},
//InvocationHandler接口
new SimpleInvocationHandler(realService));
proxyService.sayHello();
}
}
基于cglib 的 demo:
public class SimpleCGLibDemo {
static class RealService{
public void sayHello() {
System.out.println("hello");
}
}
static class SimpleInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("entering "+method.getName());
Object result = methodProxy.invokeSuper(o, objects);
System.out.println("leaving "+method.getName());
return result;
}
}
private static <T> T getProxy(Class<T> cls) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(cls);
enhancer.setCallback(new SimpleInterceptor());
return (T)enhancer.create();
}
public static void main(String[] args) {
RealService proxyService = getProxy(RealService.class);
proxyService.sayHello();
}
}
3.动态代理的应用:
aop的执行流程
例如@Transcational 事务管理, 和定义切面打印日志:
打印日志的 demo:
@Slf4j
@Aspect
@Component
public class LogAspect {
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
@Pointcut("execution(* com.example.controller..*.*(..))")
public void doArgsLog() {
}
@Pointcut("execution(* com.example.controller..*.*(..))")
public void doTimerLog() {
}
@Before("doArgsLog(){}")
public void doLogbefore(JoinPoint joinPoint) {
//获取传入目标方法的参数
Object[] args = joinPoint.getArgs();
Arrays.stream(args).forEach(arg-> {
try {
log.info("入参为:"+OBJECT_MAPPER.writeValueAsString(arg));
} catch (JsonProcessingException e) {
log.info("JsonProcessingException:"+arg.toString());
}
});
}
@Around("doTimerLog(){}")
public Object doTimer(ProceedingJoinPoint point) throws Throwable {
long beginTime = System.currentTimeMillis();
//执行原方法
Object result = point.proceed();
long time = System.currentTimeMillis() - beginTime;
log.info("目标类:"+point.getSignature().getDeclaringTypeName()+"目标方法:"+point.getSignature().getName()+"耗时=="+time);
return result;
}
}