1.InvocationHandler
用于接口的代理,拦截。
首先一个接口和一个实现类:
public interface InvocationService {
public void print();
}
public class InvocationServiceImpl implements InvocationService {
@Override
public void print() {
System.out.println("real service print content");
}
}
接着数写一个代理类并实现invocationHandler接口,充重写invoke方法:
public class InvocationServiceHandler implements InvocationHandler {
private InvocationService invocationService;
public InvocationServiceHandler(InvocationService invocationService) {
this.invocationService = invocationService;
}
public InvocationService getProxy() {
return (InvocationService) Proxy.newProxyInstance(invocationService.getClass().getClassLoader(), invocationService.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("handler before method");
Object invoke = method.invoke(invocationService, args);
System.out.println("handler after method");
return invoke;
}
}
最后开始使用
public class HandlerMain {
public static void main(String[] args) {
InvocationServiceHandler handler = new InvocationServiceHandler(new InvocationServiceImpl());
InvocationService proxy = handler.getProxy();
proxy.print();
}
}
分析一下Proxy.newProxyInstance()是怎么返回这个代理对象的
/**
* Returns an instance of a proxy class for the specified interfaces
* that dispatches method invocations to the specified invocation
* handler.
* 返回一个代理对象的实例,这个实例会把你给定的接口的方法转发到代理的方法中(接口下的所有方法和所实实现类)
*/
@CallerSensitive
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
{
Objects.requireNonNull(h);
final Class<?>[] intfs = interfaces.clone();
final SecurityManager sm = System.getSecurityManager();
if (sm != null) { //主要是检查权限 包的权限 修饰符的权限
checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
}
/*
* Look up or generate the designated proxy class.
*/
Class<?> cl = getProxyClass0(loader, intfs);
/*
* Invoke its constructor with the designated invocation handler.
*/
try {
if (sm != null) {
checkNewProxyPermission(Reflection.getCallerClass(), cl);
}
final Constructor<?> cons = cl.getConstructor(constructorParams);
final InvocationHandler ih = h;
if (!Modifier.isPublic(cl.getModifiers())) {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
cons.setAccessible(true);
return null;
}
});
}
return cons.newInstance(new Object[]{h});
} catch (IllegalAccessException|InstantiationException e) {
throw new InternalError(e.toString(), e);
} catch (InvocationTargetException e) {
Throwable t = e.getCause();
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
} else {
throw new InternalError(t.toString(), t);
}
} catch (NoSuchMethodException e) {
throw new InternalError(e.toString(), e);
}
}
有一个弱引用的实例map 每次去拿 但是因为是弱引用可能被GC回收,所以比较耗时。
2.cglib动态代理
生成一个子类继承要代理的类,并重写所有方法
3.spring代理
package com.hyq.btc.cos.filter;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
/**
* @author dibulidohu
* @classname Aop
* @date 2019/2/1419:45
* @description
*/
@Aspect
@Component
public class Aop {
@Pointcut(value = "execution(* com.hyq.btc.cos.service.IEinvoiceService.*(..))")
public void aop(){}
@Before(value = "aop()")
public void before(JoinPoint joinPoint) {
System.out.println("Logging before " + joinPoint.getSignature().getName());
}
@After("aop()")
public void after(JoinPoint joinPoint) {
System.out.println("Logging after " + joinPoint.getSignature().getName());
}
@Around("aop()")
public Object aroud(ProceedingJoinPoint joinpoint) throws Throwable {
System.out.println("Logging around before" + joinpoint.getSignature().getName());
joinpoint.proceed();
System.out.println("Logging around after" + joinpoint.getSignature().getName());
return null;
}
@AfterThrowing("aop()")
public void afterthr(JoinPoint joinPoint) {
System.out.println("Logging after throw " + joinPoint.getSignature().getName());
}
}